Bug Summary

File:cdk/wayland/cdkkeys-wayland.c
Warning:line 506, column 20
Out of bound memory access (access exceeds upper limit of memory block)

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name cdkkeys-wayland.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/cdk/wayland -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I ../.. -D G_LOG_DOMAIN="Cdk" -D G_LOG_USE_STRUCTURED=1 -D CDK_COMPILATION -I ../.. -I ../../cdk -I ../../cdk -D G_ENABLE_DEBUG -D G_ENABLE_CONSISTENCY_CHECKS -D GLIB_MIN_REQUIRED_VERSION=GLIB_VERSION_2_66 -D GLIB_MAX_ALLOWED_VERSION=GLIB_VERSION_2_66 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/cdk/wayland -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-09-19-173409-43638-1 -x c cdkkeys-wayland.c
1/* CDK - The GIMP Drawing Kit
2 * Copyright (C) 2000 Red Hat, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/*
19 * Modified by the CTK+ Team and others 1997-2000. See the AUTHORS
20 * file for a list of people on the CTK+ Team. See the ChangeLog
21 * files for a list of changes. These files are distributed with
22 * CTK+ at ftp://ftp.ctk.org/pub/ctk/.
23 */
24
25#include "config.h"
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <unistd.h>
31#include <limits.h>
32#include <errno(*__errno_location ()).h>
33#include <sys/mman.h>
34
35#include "cdk.h"
36#include "cdkwayland.h"
37
38#include "cdkprivate-wayland.h"
39#include "cdkinternals.h"
40#include "cdkkeysprivate.h"
41
42#include <xkbcommon/xkbcommon.h>
43
44typedef struct _CdkWaylandKeymap CdkWaylandKeymap;
45typedef struct _CdkWaylandKeymapClass CdkWaylandKeymapClass;
46
47struct _CdkWaylandKeymap
48{
49 CdkKeymap parent_instance;
50
51 struct xkb_keymap *xkb_keymap;
52 struct xkb_state *xkb_state;
53
54 PangoDirection *direction;
55 gboolean bidi;
56};
57
58struct _CdkWaylandKeymapClass
59{
60 CdkKeymapClass parent_class;
61};
62
63#define CDK_TYPE_WAYLAND_KEYMAP(_cdk_wayland_keymap_get_type ()) (_cdk_wayland_keymap_get_type ())
64#define CDK_WAYLAND_KEYMAP(object)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((object)), ((_cdk_wayland_keymap_get_type ()
))))))
(G_TYPE_CHECK_INSTANCE_CAST ((object), CDK_TYPE_WAYLAND_KEYMAP, CdkWaylandKeymap)(((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((_cdk_wayland_keymap_get_type ())))))
)
65#define CDK_IS_WAYLAND_KEYMAP(object)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(object)); GType __t = ((_cdk_wayland_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
(G_TYPE_CHECK_INSTANCE_TYPE ((object), CDK_TYPE_WAYLAND_KEYMAP)((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(object)); GType __t = ((_cdk_wayland_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))
)
66
67GType _cdk_wayland_keymap_get_type (void);
68
69G_DEFINE_TYPE (CdkWaylandKeymap, _cdk_wayland_keymap, CDK_TYPE_KEYMAP)static void _cdk_wayland_keymap_init (CdkWaylandKeymap *self)
; static void _cdk_wayland_keymap_class_init (CdkWaylandKeymapClass
*klass); static GType _cdk_wayland_keymap_get_type_once (void
); static gpointer _cdk_wayland_keymap_parent_class = ((void*
)0); static gint CdkWaylandKeymap_private_offset; static void
_cdk_wayland_keymap_class_intern_init (gpointer klass) { _cdk_wayland_keymap_parent_class
= g_type_class_peek_parent (klass); if (CdkWaylandKeymap_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CdkWaylandKeymap_private_offset
); _cdk_wayland_keymap_class_init ((CdkWaylandKeymapClass*) klass
); } __attribute__ ((__unused__)) static inline gpointer _cdk_wayland_keymap_get_instance_private
(CdkWaylandKeymap *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CdkWaylandKeymap_private_offset)))); } GType _cdk_wayland_keymap_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= _cdk_wayland_keymap_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType _cdk_wayland_keymap_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((cdk_keymap_get_type ()), g_intern_static_string ("CdkWaylandKeymap"
), sizeof (CdkWaylandKeymapClass), (GClassInitFunc)(void (*)(
void)) _cdk_wayland_keymap_class_intern_init, sizeof (CdkWaylandKeymap
), (GInstanceInitFunc)(void (*)(void)) _cdk_wayland_keymap_init
, (GTypeFlags) 0); { {{};} } return g_define_type_id; }
70
71static void
72cdk_wayland_keymap_finalize (GObject *object)
73{
74 CdkWaylandKeymap *keymap = CDK_WAYLAND_KEYMAP (object)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((object)), ((_cdk_wayland_keymap_get_type ()
))))))
;
75
76 xkb_keymap_unref (keymap->xkb_keymap);
77 xkb_state_unref (keymap->xkb_state);
78 g_free (keymap->direction);
79
80 G_OBJECT_CLASS (_cdk_wayland_keymap_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((_cdk_wayland_keymap_parent_class)), (((GType) ((20) <<
(2))))))))
->finalize (object);
81}
82
83static PangoDirection
84cdk_wayland_keymap_get_direction (CdkKeymap *keymap)
85{
86 CdkWaylandKeymap *keymap_wayland = CDK_WAYLAND_KEYMAP (keymap)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((keymap)), ((_cdk_wayland_keymap_get_type ()
))))))
;
87 gint i;
88
89 for (i = 0; i < xkb_keymap_num_layouts (keymap_wayland->xkb_keymap); i++)
90 {
91 if (xkb_state_layout_index_is_active (keymap_wayland->xkb_state, i, XKB_STATE_LAYOUT_EFFECTIVE))
92 return keymap_wayland->direction[i];
93 }
94
95 return PANGO_DIRECTION_NEUTRAL;
96}
97
98static gboolean
99cdk_wayland_keymap_have_bidi_layouts (CdkKeymap *keymap)
100{
101 CdkWaylandKeymap *keymap_wayland = CDK_WAYLAND_KEYMAP (keymap)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((keymap)), ((_cdk_wayland_keymap_get_type ()
))))))
;
102
103 return keymap_wayland->bidi;
104}
105
106static gboolean
107cdk_wayland_keymap_get_caps_lock_state (CdkKeymap *keymap)
108{
109 return xkb_state_led_name_is_active (CDK_WAYLAND_KEYMAP (keymap)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((keymap)), ((_cdk_wayland_keymap_get_type ()
))))))
->xkb_state,
110 XKB_LED_NAME_CAPS"Caps Lock");
111}
112
113static gboolean
114cdk_wayland_keymap_get_num_lock_state (CdkKeymap *keymap)
115{
116 return xkb_state_led_name_is_active (CDK_WAYLAND_KEYMAP (keymap)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((keymap)), ((_cdk_wayland_keymap_get_type ()
))))))
->xkb_state,
117 XKB_LED_NAME_NUM"Num Lock");
118}
119
120static gboolean
121cdk_wayland_keymap_get_scroll_lock_state (CdkKeymap *keymap)
122{
123 return xkb_state_led_name_is_active (CDK_WAYLAND_KEYMAP (keymap)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((keymap)), ((_cdk_wayland_keymap_get_type ()
))))))
->xkb_state,
124 XKB_LED_NAME_SCROLL"Scroll Lock");
125}
126
127static gboolean
128cdk_wayland_keymap_get_entries_for_keyval (CdkKeymap *keymap,
129 guint keyval,
130 CdkKeymapKey **keys,
131 gint *n_keys)
132{
133 struct xkb_keymap *xkb_keymap = CDK_WAYLAND_KEYMAP (keymap)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((keymap)), ((_cdk_wayland_keymap_get_type ()
))))))
->xkb_keymap;
134 GArray *retval;
135 guint keycode;
136 xkb_keycode_t min_keycode, max_keycode;
137
138 retval = g_array_new (FALSE(0), FALSE(0), sizeof (CdkKeymapKey));
139
140 min_keycode = xkb_keymap_min_keycode (xkb_keymap);
141 max_keycode = xkb_keymap_max_keycode (xkb_keymap);
142 for (keycode = min_keycode; keycode < max_keycode; keycode++)
143 {
144 gint num_layouts, layout;
145 num_layouts = xkb_keymap_num_layouts_for_key (xkb_keymap, keycode);
146 for (layout = 0; layout < num_layouts; layout++)
147 {
148 gint num_levels, level;
149 num_levels = xkb_keymap_num_levels_for_key (xkb_keymap, keycode, layout);
150 for (level = 0; level < num_levels; level++)
151 {
152 const xkb_keysym_t *syms;
153 gint num_syms, sym;
154 num_syms = xkb_keymap_key_get_syms_by_level (xkb_keymap, keycode, layout, level, &syms);
155 for (sym = 0; sym < num_syms; sym++)
156 {
157 if (syms[sym] == keyval)
158 {
159 CdkKeymapKey key;
160
161 key.keycode = keycode;
162 key.group = layout;
163 key.level = level;
164
165 g_array_append_val (retval, key)g_array_append_vals (retval, &(key), 1);
166 }
167 }
168 }
169 }
170 }
171
172 *n_keys = retval->len;
173 *keys = (CdkKeymapKey*) g_array_free (retval, FALSE(0));
174
175 return TRUE(!(0));
176}
177
178static gboolean
179cdk_wayland_keymap_get_entries_for_keycode (CdkKeymap *keymap,
180 guint hardware_keycode,
181 CdkKeymapKey **keys,
182 guint **keyvals,
183 gint *n_entries)
184{
185 struct xkb_keymap *xkb_keymap = CDK_WAYLAND_KEYMAP (keymap)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((keymap)), ((_cdk_wayland_keymap_get_type ()
))))))
->xkb_keymap;
186 gint num_layouts, layout;
187 gint num_entries;
188 gint i;
189
190 num_layouts = xkb_keymap_num_layouts_for_key (xkb_keymap, hardware_keycode);
191
192 num_entries = 0;
193 for (layout = 0; layout < num_layouts; layout++)
194 num_entries += xkb_keymap_num_levels_for_key (xkb_keymap, hardware_keycode, layout);
195
196 if (n_entries)
197 *n_entries = num_entries;
198 if (keys)
199 *keys = g_new0 (CdkKeymapKey, num_entries)((CdkKeymapKey *) g_malloc0_n ((num_entries), sizeof (CdkKeymapKey
)))
;
200 if (keyvals)
201 *keyvals = g_new0 (guint, num_entries)((guint *) g_malloc0_n ((num_entries), sizeof (guint)));
202
203 i = 0;
204 for (layout = 0; layout < num_layouts; layout++)
205 {
206 gint num_levels, level;
207 num_levels = xkb_keymap_num_levels_for_key (xkb_keymap, hardware_keycode, layout);
208 for (level = 0; level < num_levels; level++)
209 {
210 const xkb_keysym_t *syms;
211 int num_syms;
212 num_syms = xkb_keymap_key_get_syms_by_level (xkb_keymap, hardware_keycode, layout, 0, &syms);
213 if (keys)
214 {
215 (*keys)[i].keycode = hardware_keycode;
216 (*keys)[i].group = layout;
217 (*keys)[i].level = level;
218 }
219 if (keyvals && num_syms > 0)
220 (*keyvals)[i] = syms[0];
221
222 i++;
223 }
224 }
225
226 return num_entries > 0;
227}
228
229static guint
230cdk_wayland_keymap_lookup_key (CdkKeymap *keymap,
231 const CdkKeymapKey *key)
232{
233 struct xkb_keymap *xkb_keymap = CDK_WAYLAND_KEYMAP (keymap)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((keymap)), ((_cdk_wayland_keymap_get_type ()
))))))
->xkb_keymap;
234 const xkb_keysym_t *syms;
235 int num_syms;
236
237 num_syms = xkb_keymap_key_get_syms_by_level (xkb_keymap,
238 key->keycode,
239 key->group,
240 key->level,
241 &syms);
242 if (num_syms > 0)
243 return syms[0];
244 else
245 return XKB_KEY_NoSymbol0x000000;
246}
247
248static guint32
249get_xkb_modifiers (struct xkb_keymap *xkb_keymap,
250 CdkModifierType state)
251{
252 guint32 mods = 0;
253
254 if (state & CDK_SHIFT_MASK)
255 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_SHIFT"Shift");
256 if (state & CDK_LOCK_MASK)
257 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_CAPS"Lock");
258 if (state & CDK_CONTROL_MASK)
259 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_CTRL"Control");
260 if (state & CDK_MOD1_MASK)
261 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_ALT"Mod1");
262 if (state & CDK_MOD2_MASK)
263 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_NUM"Mod2");
264 if (state & CDK_MOD3_MASK)
265 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod3");
266 if (state & CDK_MOD4_MASK)
267 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_LOGO"Mod4");
268 if (state & CDK_MOD5_MASK)
269 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod5");
270 if (state & CDK_SUPER_MASK)
271 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, "Super");
272 if (state & CDK_HYPER_MASK)
273 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, "Hyper");
274 if (state & CDK_META_MASK)
275 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, "Meta");
276
277 return mods;
278}
279
280static CdkModifierType
281get_cdk_modifiers (struct xkb_keymap *xkb_keymap,
282 guint32 mods)
283{
284 CdkModifierType state = 0;
285
286 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_SHIFT"Shift")))
287 state |= CDK_SHIFT_MASK;
288 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_CAPS"Lock")))
289 state |= CDK_LOCK_MASK;
290 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_CTRL"Control")))
291 state |= CDK_CONTROL_MASK;
292 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_ALT"Mod1")))
293 state |= CDK_MOD1_MASK;
294 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_NUM"Mod2")))
295 state |= CDK_MOD2_MASK;
296 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod3")))
297 state |= CDK_MOD3_MASK;
298 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_LOGO"Mod4")))
299 state |= CDK_MOD4_MASK;
300 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod5")))
301 state |= CDK_MOD5_MASK;
302 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, "Super")))
303 state |= CDK_SUPER_MASK;
304 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, "Hyper")))
305 state |= CDK_HYPER_MASK;
306 /* Ctk+ treats MOD1 as a synonym for Alt, and does not expect it to
307 * be mapped around, so we should avoid adding CDK_META_MASK if MOD1
308 * is already included to avoid confusing ctk+ and applications that
309 * rely on that behavior.
310 */
311 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, "Meta")) &&
312 (state & CDK_MOD1_MASK) == 0)
313 state |= CDK_META_MASK;
314
315 return state;
316}
317
318static gboolean
319cdk_wayland_keymap_translate_keyboard_state (CdkKeymap *keymap,
320 guint hardware_keycode,
321 CdkModifierType state,
322 gint group,
323 guint *keyval,
324 gint *effective_group,
325 gint *effective_level,
326 CdkModifierType *consumed_modifiers)
327{
328 struct xkb_keymap *xkb_keymap;
329 struct xkb_state *xkb_state;
330 guint32 modifiers;
331 guint32 consumed;
332 xkb_layout_index_t layout;
333 xkb_level_index_t level;
334 xkb_keysym_t sym;
335
336 g_return_val_if_fail (keymap == NULL || CDK_IS_KEYMAP (keymap), FALSE)do { if ((keymap == ((void*)0) || (((__extension__ ({ GTypeInstance
*__inst = (GTypeInstance*) ((keymap)); GType __t = ((cdk_keymap_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning ("Cdk", ((const
char*) (__func__)), "keymap == NULL || CDK_IS_KEYMAP (keymap)"
); return ((0)); } } while (0)
;
337 g_return_val_if_fail (group < 4, FALSE)do { if ((group < 4)) { } else { g_return_if_fail_warning (
"Cdk", ((const char*) (__func__)), "group < 4"); return ((
0)); } } while (0)
;
338
339 xkb_keymap = CDK_WAYLAND_KEYMAP (keymap)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((keymap)), ((_cdk_wayland_keymap_get_type ()
))))))
->xkb_keymap;
340
341 modifiers = get_xkb_modifiers (xkb_keymap, state);
342
343 xkb_state = xkb_state_new (xkb_keymap);
344
345 xkb_state_update_mask (xkb_state, modifiers, 0, 0, group, 0, 0);
346
347 layout = xkb_state_key_get_layout (xkb_state, hardware_keycode);
348 level = xkb_state_key_get_level (xkb_state, hardware_keycode, layout);
349 sym = xkb_state_key_get_one_sym (xkb_state, hardware_keycode);
350 consumed = modifiers & ~xkb_state_mod_mask_remove_consumed (xkb_state, hardware_keycode, modifiers);
351
352 xkb_state_unref (xkb_state);
353
354 if (keyval)
355 *keyval = sym;
356 if (effective_group)
357 *effective_group = layout;
358 if (effective_level)
359 *effective_level = level;
360 if (consumed_modifiers)
361 *consumed_modifiers = get_cdk_modifiers (xkb_keymap, consumed);
362
363 return (sym != XKB_KEY_NoSymbol0x000000);
364}
365
366static guint
367cdk_wayland_keymap_get_modifier_state (CdkKeymap *keymap)
368{
369 struct xkb_keymap *xkb_keymap = CDK_WAYLAND_KEYMAP (keymap)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((keymap)), ((_cdk_wayland_keymap_get_type ()
))))))
->xkb_keymap;
370 struct xkb_state *xkb_state = CDK_WAYLAND_KEYMAP (keymap)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((keymap)), ((_cdk_wayland_keymap_get_type ()
))))))
->xkb_state;
371 xkb_mod_mask_t mods;
372
373 mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_EFFECTIVE);
374
375 return get_cdk_modifiers (xkb_keymap, mods);
376}
377
378static void
379cdk_wayland_keymap_add_virtual_modifiers (CdkKeymap *keymap,
380 CdkModifierType *state)
381{
382 struct xkb_keymap *xkb_keymap;
383 struct xkb_state *xkb_state;
384 xkb_mod_index_t idx;
385 uint32_t mods, real;
386 struct { const char *name; CdkModifierType mask; } vmods[] = {
387 { "Super", CDK_SUPER_MASK },
388 { "Hyper", CDK_HYPER_MASK },
389 { "Meta", CDK_META_MASK },
390 { NULL((void*)0), 0 }
391 };
392 int i;
393
394 xkb_keymap = CDK_WAYLAND_KEYMAP (keymap)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((keymap)), ((_cdk_wayland_keymap_get_type ()
))))))
->xkb_keymap;
395 mods = get_xkb_modifiers (xkb_keymap, *state);
396
397 xkb_state = xkb_state_new (xkb_keymap);
398
399 for (i = 0; vmods[i].name; i++)
400 {
401 idx = xkb_keymap_mod_get_index (xkb_keymap, vmods[i].name);
402 if (idx == XKB_MOD_INVALID(0xffffffff))
403 continue;
404
405 xkb_state_update_mask (xkb_state, 1 << idx, 0, 0, 0, 0, 0);
406 real = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_EFFECTIVE);
407 real &= 0xf0; /* ignore mapping to Lock, Shift, Control, Mod1 */
408 if (mods & real)
409 *state |= vmods[i].mask;
410 xkb_state_update_mask (xkb_state, 0, 0, 0, 0, 0, 0);
411 }
412
413 xkb_state_unref (xkb_state);
414}
415
416static gboolean
417cdk_wayland_keymap_map_virtual_modifiers (CdkKeymap *keymap,
418 CdkModifierType *state)
419{
420 struct xkb_keymap *xkb_keymap;
421 struct xkb_state *xkb_state;
422 uint32_t mods, mapped;
423 gboolean ret = TRUE(!(0));
424
425 xkb_keymap = CDK_WAYLAND_KEYMAP (keymap)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((keymap)), ((_cdk_wayland_keymap_get_type ()
))))))
->xkb_keymap;
426 mods = get_xkb_modifiers (xkb_keymap, *state);
427
428 xkb_state = xkb_state_new (xkb_keymap);
429 xkb_state_update_mask (xkb_state, mods & ~0xff, 0, 0, 0, 0, 0);
430 mapped = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_EFFECTIVE);
431 if ((mapped & mods & 0xff) != 0)
432 ret = FALSE(0);
433 *state |= get_cdk_modifiers (xkb_keymap, mapped);
434
435 xkb_state_unref (xkb_state);
436
437 return ret;
438}
439
440static void
441_cdk_wayland_keymap_class_init (CdkWaylandKeymapClass *klass)
442{
443 GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
444 CdkKeymapClass *keymap_class = CDK_KEYMAP_CLASS (klass)((((CdkKeymapClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), ((cdk_keymap_get_type ()))))))
;
445
446 object_class->finalize = cdk_wayland_keymap_finalize;
447
448 keymap_class->get_direction = cdk_wayland_keymap_get_direction;
449 keymap_class->have_bidi_layouts = cdk_wayland_keymap_have_bidi_layouts;
450 keymap_class->get_caps_lock_state = cdk_wayland_keymap_get_caps_lock_state;
451 keymap_class->get_num_lock_state = cdk_wayland_keymap_get_num_lock_state;
452 keymap_class->get_scroll_lock_state = cdk_wayland_keymap_get_scroll_lock_state;
453 keymap_class->get_entries_for_keyval = cdk_wayland_keymap_get_entries_for_keyval;
454 keymap_class->get_entries_for_keycode = cdk_wayland_keymap_get_entries_for_keycode;
455 keymap_class->lookup_key = cdk_wayland_keymap_lookup_key;
456 keymap_class->translate_keyboard_state = cdk_wayland_keymap_translate_keyboard_state;
457 keymap_class->get_modifier_state = cdk_wayland_keymap_get_modifier_state;
458 keymap_class->add_virtual_modifiers = cdk_wayland_keymap_add_virtual_modifiers;
459 keymap_class->map_virtual_modifiers = cdk_wayland_keymap_map_virtual_modifiers;
460}
461
462static void
463_cdk_wayland_keymap_init (CdkWaylandKeymap *keymap G_GNUC_UNUSED__attribute__ ((__unused__)))
464{
465}
466
467static void
468update_direction (CdkWaylandKeymap *keymap)
469{
470 gint num_layouts;
471 gint i;
472 gint *rtl;
473 xkb_keycode_t min_keycode, max_keycode;
474 guint key;
475 gboolean have_rtl, have_ltr;
476
477 num_layouts = xkb_keymap_num_layouts (keymap->xkb_keymap);
478
479 keymap->direction = g_renew (PangoDirection, keymap->direction, num_layouts)((PangoDirection *) g_realloc_n (keymap->direction, (num_layouts
), sizeof (PangoDirection)))
;
480 rtl = g_newa (gint, num_layouts)((gint*) __builtin_alloca (sizeof (gint) * (gsize) (num_layouts
)))
;
481 for (i = 0; i
10.1
'i' is < 'num_layouts'
< num_layouts
; i++)
11
Loop condition is true. Entering loop body
12
Assuming 'i' is >= 'num_layouts'
13
Loop condition is false. Execution continues on line 484
482 rtl[i] = 0;
483
484 min_keycode = xkb_keymap_min_keycode (keymap->xkb_keymap);
485 max_keycode = xkb_keymap_max_keycode (keymap->xkb_keymap);
486 for (key = min_keycode; key < max_keycode; key++)
14
Assuming 'key' is < 'max_keycode'
15
Loop condition is true. Entering loop body
487 {
488 gint layouts, layout;
489
490 layouts = xkb_keymap_num_layouts_for_key (keymap->xkb_keymap, key);
491 for (layout = 0; layout < layouts; layout++)
16
Assuming 'layout' is < 'layouts'
17
Loop condition is true. Entering loop body
20
Assuming 'layout' is < 'layouts'
21
Loop condition is true. Entering loop body
492 {
493 const xkb_keysym_t *syms;
494 gint num_syms;
495 gint sym;
496
497 num_syms = xkb_keymap_key_get_syms_by_level (keymap->xkb_keymap, key, layout, 0, &syms);
498 for (sym = 0; sym < num_syms; sym++)
18
Assuming 'sym' is >= 'num_syms'
19
Loop condition is false. Execution continues on line 491
22
Assuming 'sym' is < 'num_syms'
23
Loop condition is true. Entering loop body
499 {
500 PangoDirection dir;
501
502 dir = cdk_unichar_direction (xkb_keysym_to_utf32 (syms[sym]));
503 switch (dir)
24
Control jumps to 'case PANGO_DIRECTION_RTL:' at line 505
504 {
505 case PANGO_DIRECTION_RTL:
506 rtl[layout]++;
25
Out of bound memory access (access exceeds upper limit of memory block)
507 break;
508 case PANGO_DIRECTION_LTR:
509 rtl[layout]--;
510 break;
511 default:
512 break;
513 }
514 }
515 }
516 }
517
518 have_rtl = have_ltr = FALSE(0);
519 for (i = 0; i < num_layouts; i++)
520 {
521 if (rtl[i] > 0)
522 {
523 keymap->direction[i] = PANGO_DIRECTION_RTL;
524 have_rtl = TRUE(!(0));
525 }
526 else
527 {
528 keymap->direction[i] = PANGO_DIRECTION_LTR;
529 have_ltr = TRUE(!(0));
530 }
531 }
532
533 if (have_rtl && have_ltr)
534 keymap->bidi = TRUE(!(0));
535}
536
537CdkKeymap *
538_cdk_wayland_keymap_new (void)
539{
540 CdkWaylandKeymap *keymap;
541 struct xkb_context *context;
542 struct xkb_rule_names names;
543
544 keymap = g_object_new (_cdk_wayland_keymap_get_type(), NULL((void*)0));
545
546 context = xkb_context_new (0);
547
548 names.rules = "evdev";
549 names.model = "pc105";
550 names.layout = "us";
551 names.variant = "";
552 names.options = "";
553 keymap->xkb_keymap = xkb_keymap_new_from_names (context, &names, 0);
554 keymap->xkb_state = xkb_state_new (keymap->xkb_keymap);
555 xkb_context_unref (context);
556
557 update_direction (keymap);
558
559 return CDK_KEYMAP (keymap)((((CdkKeymap*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((keymap)), ((cdk_keymap_get_type ()))))))
;
560}
561
562#ifdef G_ENABLE_DEBUG1
563static void
564print_modifiers (struct xkb_keymap *keymap)
565{
566 int i, j;
567 uint32_t real;
568 struct xkb_state *state;
569
570 g_print ("modifiers:\n");
571 for (i = 0; i < xkb_keymap_num_mods (keymap); i++)
572 g_print ("%s ", xkb_keymap_mod_get_name (keymap, i));
573 g_print ("\n\n");
574
575 g_print ("modifier mapping\n");
576 state = xkb_state_new (keymap);
577 for (i = 0; i < 8; i++)
578 {
579 gboolean need_arrow = TRUE(!(0));
580 g_print ("%s ", xkb_keymap_mod_get_name (keymap, i));
581 for (j = 8; j < xkb_keymap_num_mods (keymap); j++)
582 {
583 xkb_state_update_mask (state, 1 << j, 0, 0, 0, 0, 0);
584 real = xkb_state_serialize_mods (state, XKB_STATE_MODS_EFFECTIVE);
585 if (real & (1 << i))
586 {
587 if (need_arrow)
588 {
589 g_print ("-> ");
590 need_arrow = FALSE(0);
591 }
592 g_print ("%s ", xkb_keymap_mod_get_name (keymap, j));
593 }
594 }
595 g_print ("\n");
596 }
597
598 xkb_state_unref (state);
599}
600#endif
601
602void
603_cdk_wayland_keymap_update_from_fd (CdkKeymap *keymap,
604 uint32_t format,
605 uint32_t fd,
606 uint32_t size)
607{
608 CdkWaylandKeymap *keymap_wayland = CDK_WAYLAND_KEYMAP (keymap)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((keymap)), ((_cdk_wayland_keymap_get_type ()
))))))
;
609 struct xkb_context *context;
610 struct xkb_keymap *xkb_keymap;
611 char *map_str;
612
613 context = xkb_context_new (0);
614
615 map_str = mmap (NULL((void*)0), size, PROT_READ0x1, MAP_SHARED0x01, fd, 0);
616 if (map_str == MAP_FAILED((void *) -1))
1
Assuming the condition is false
2
Taking false branch
617 {
618 close(fd);
619 return;
620 }
621
622 CDK_NOTE(INPUT, g_print ("keymap:\n%s\n", map_str))do { if ((_cdk_debug_flags & CDK_DEBUG_INPUT)) { g_print (
"keymap:\n%s\n", map_str); }; } while (0)
;
3
Assuming the condition is false
4
Taking false branch
5
Loop condition is false. Exiting loop
623
624 xkb_keymap = xkb_keymap_new_from_string (context, map_str, format, 0);
625 munmap (map_str, size);
626 close (fd);
627
628 if (!xkb_keymap)
6
Assuming 'xkb_keymap' is non-null
7
Taking false branch
629 {
630 g_warning ("Got invalid keymap from compositor, keeping previous/default one");
631 xkb_context_unref (context);
632 return;
633 }
634
635 CDK_NOTE(INPUT, print_modifiers (xkb_keymap))do { if ((_cdk_debug_flags & CDK_DEBUG_INPUT)) { print_modifiers
(xkb_keymap); }; } while (0)
;
8
Taking false branch
9
Loop condition is false. Exiting loop
636
637 xkb_keymap_unref (keymap_wayland->xkb_keymap);
638 keymap_wayland->xkb_keymap = xkb_keymap;
639
640 xkb_state_unref (keymap_wayland->xkb_state);
641 keymap_wayland->xkb_state = xkb_state_new (keymap_wayland->xkb_keymap);
642
643 xkb_context_unref (context);
644
645 update_direction (keymap_wayland);
10
Calling 'update_direction'
646}
647
648struct xkb_keymap *
649_cdk_wayland_keymap_get_xkb_keymap (CdkKeymap *keymap)
650{
651 return CDK_WAYLAND_KEYMAP (keymap)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((keymap)), ((_cdk_wayland_keymap_get_type ()
))))))
->xkb_keymap;
652}
653
654struct xkb_state *
655_cdk_wayland_keymap_get_xkb_state (CdkKeymap *keymap)
656{
657 return CDK_WAYLAND_KEYMAP (keymap)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((keymap)), ((_cdk_wayland_keymap_get_type ()
))))))
->xkb_state;
658}
659
660gboolean
661_cdk_wayland_keymap_key_is_modifier (CdkKeymap *keymap,
662 guint keycode)
663{
664 struct xkb_keymap *xkb_keymap = CDK_WAYLAND_KEYMAP (keymap)((((CdkWaylandKeymap*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((keymap)), ((_cdk_wayland_keymap_get_type ()
))))))
->xkb_keymap;
665 struct xkb_state *xkb_state;
666 gboolean is_modifier;
667
668 is_modifier = FALSE(0);
669
670 xkb_state = xkb_state_new (xkb_keymap);
671
672 if (xkb_state_update_key (xkb_state, keycode, XKB_KEY_DOWN) & XKB_STATE_MODS_EFFECTIVE)
673 is_modifier = TRUE(!(0));
674
675 xkb_state_unref (xkb_state);
676
677 return is_modifier;
678}