Bug Summary

File:demos/ctk-demo/event_axes.c
Warning:line 594, column 50
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption

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 event_axes.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 -pic-is-pie -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/demos/ctk-demo -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I ../.. -I ../.. -I ../../cdk -D CDK_DISABLE_DEPRECATED -D CTK_DISABLE_DEPRECATED -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/atk-1.0 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/gio-unix-2.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -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/pango-1.0 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -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/demos/ctk-demo -ferror-limit 19 -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 event_axes.c
1/* Touch and Drawing Tablets
2 *
3 * Demonstrates advanced handling of event information from exotic
4 * input devices.
5 *
6 * On one hand, this snippet demonstrates management of drawing tablets,
7 * those contain additional information for the pointer other than
8 * X/Y coordinates. Tablet pads events are mapped to actions, which
9 * are both defined and interpreted by the application.
10 *
11 * Input axes are dependent on hardware devices, on linux/unix you
12 * can see the device axes through xinput list <device>. Each time
13 * a different hardware device is used to move the pointer, the
14 * master device will be updated to match the axes it provides,
15 * these changes can be tracked through CdkDevice::changed, or
16 * checking cdk_event_get_source_device().
17 *
18 * On the other hand, this demo handles basic multitouch events,
19 * each event coming from an specific touchpoint will contain a
20 * CdkEventSequence that's unique for its lifetime, so multiple
21 * touchpoints can be tracked.
22 */
23
24#include <glib/gi18n.h>
25#include <ctk/ctk.h>
26
27typedef struct {
28 CdkDevice *last_source;
29 CdkDeviceTool *last_tool;
30 gdouble *axes;
31 CdkRGBA color;
32 gdouble x;
33 gdouble y;
34} AxesInfo;
35
36typedef struct {
37 GHashTable *pointer_info; /* CdkDevice -> AxesInfo */
38 GHashTable *touch_info; /* CdkEventSequence -> AxesInfo */
39} EventData;
40
41const gchar *colors[] = {
42 "black",
43 "orchid",
44 "fuchsia",
45 "indigo",
46 "thistle",
47 "sienna",
48 "azure",
49 "plum",
50 "lime",
51 "navy",
52 "maroon",
53 "burlywood"
54};
55
56static CtkPadActionEntry pad_actions[] = {
57 { CTK_PAD_ACTION_BUTTON, 1, -1, N_("Nuclear strike")("Nuclear strike"), "pad.nuke" },
58 { CTK_PAD_ACTION_BUTTON, 2, -1, N_("Release siberian methane reserves")("Release siberian methane reserves"), "pad.heat" },
59 { CTK_PAD_ACTION_BUTTON, 3, -1, N_("Release solar flare")("Release solar flare"), "pad.fry" },
60 { CTK_PAD_ACTION_BUTTON, 4, -1, N_("De-stabilize Oort cloud")("De-stabilize Oort cloud"), "pad.fall" },
61 { CTK_PAD_ACTION_BUTTON, 5, -1, N_("Ignite WR-104")("Ignite WR-104"), "pad.burst" },
62 { CTK_PAD_ACTION_BUTTON, 6, -1, N_("Lart whoever asks about this button")("Lart whoever asks about this button"), "pad.lart" },
63 { CTK_PAD_ACTION_RING, -1, -1, N_("Earth axial tilt")("Earth axial tilt"), "pad.tilt" },
64 { CTK_PAD_ACTION_STRIP, -1, -1, N_("Extent of weak nuclear force")("Extent of weak nuclear force"), "pad.dissolve" },
65};
66
67static const gchar *pad_action_results[] = {
68 "☢",
69 "♨",
70 "☼",
71 "☄",
72 "⚡",
73 "💫",
74 "◑",
75 "⚛"
76};
77
78static guint cur_color = 0;
79static guint pad_action_timeout_id = 0;
80
81static AxesInfo *
82axes_info_new (void)
83{
84 AxesInfo *info;
85
86 info = g_new0 (AxesInfo, 1)((AxesInfo *) g_malloc0_n ((1), sizeof (AxesInfo)));
87 cdk_rgba_parse (&info->color, colors[cur_color]);
88
89 cur_color = (cur_color + 1) % G_N_ELEMENTS (colors)(sizeof (colors) / sizeof ((colors)[0]));
90
91 return info;
92}
93
94static EventData *
95event_data_new (void)
96{
97 EventData *data;
98
99 data = g_new0 (EventData, 1)((EventData *) g_malloc0_n ((1), sizeof (EventData)));
100 data->pointer_info = g_hash_table_new_full (NULL((void*)0), NULL((void*)0), NULL((void*)0),
101 (GDestroyNotify) g_free);
102 data->touch_info = g_hash_table_new_full (NULL((void*)0), NULL((void*)0), NULL((void*)0),
103 (GDestroyNotify) g_free);
104
105 return data;
106}
107
108static void
109event_data_free (EventData *data)
110{
111 g_hash_table_destroy (data->pointer_info);
112 g_hash_table_destroy (data->touch_info);
113 g_free (data);
114}
115
116static void
117update_axes_from_event (CdkEvent *event,
118 EventData *data)
119{
120 CdkDevice *device, *source_device;
121 CdkEventSequence *sequence;
122 CdkDeviceTool *tool;
123 gdouble x, y;
124 AxesInfo *info;
125
126 device = cdk_event_get_device (event);
127 source_device = cdk_event_get_source_device (event);
128 sequence = cdk_event_get_event_sequence (event);
129 tool = cdk_event_get_device_tool (event);
130
131 if (event->type == CDK_TOUCH_END ||
132 event->type == CDK_TOUCH_CANCEL)
133 {
134 g_hash_table_remove (data->touch_info, sequence);
135 return;
136 }
137 else if (event->type == CDK_LEAVE_NOTIFY)
138 {
139 g_hash_table_remove (data->pointer_info, device);
140 return;
141 }
142
143 if (!sequence)
144 {
145 info = g_hash_table_lookup (data->pointer_info, device);
146
147 if (!info)
148 {
149 info = axes_info_new ();
150 g_hash_table_insert (data->pointer_info, device, info);
151 }
152 }
153 else
154 {
155 info = g_hash_table_lookup (data->touch_info, sequence);
156
157 if (!info)
158 {
159 info = axes_info_new ();
160 g_hash_table_insert (data->touch_info, sequence, info);
161 }
162 }
163
164 if (info->last_source != source_device)
165 info->last_source = source_device;
166
167 if (info->last_tool != tool)
168 info->last_tool = tool;
169
170 g_clear_pointer (&info->axes, g_free)do { _Static_assert (sizeof *(&info->axes) == sizeof (
gpointer), "Expression evaluates to false"); __typeof__ ((&
info->axes)) _pp = (&info->axes); __typeof__ (*(&
info->axes)) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_free
) (_ptr); } while (0)
;
171
172 if (event->type == CDK_TOUCH_BEGIN ||
173 event->type == CDK_TOUCH_UPDATE)
174 {
175 if (sequence && event->touch.emulating_pointer)
176 g_hash_table_remove (data->pointer_info, device);
177 }
178 if (event->type == CDK_MOTION_NOTIFY)
179 {
180 info->axes =
181 g_memdup2 (event->motion.axes,
182 sizeof (gdouble) * cdk_device_get_n_axes (source_device));
183 }
184 else if (event->type == CDK_BUTTON_PRESS ||
185 event->type == CDK_BUTTON_RELEASE)
186 {
187 info->axes =
188 g_memdup2 (event->button.axes,
189 sizeof (gdouble) * cdk_device_get_n_axes (source_device));
190 }
191
192 if (cdk_event_get_coords (event, &x, &y))
193 {
194 info->x = x;
195 info->y = y;
196 }
197}
198
199static gboolean
200event_cb (CtkWidget *widget,
201 CdkEvent *event,
202 gpointer user_data)
203{
204 update_axes_from_event (event, user_data);
205 ctk_widget_queue_draw (widget);
206 return FALSE(0);
207}
208
209static void
210render_arrow (cairo_t *cr,
211 gdouble x_diff,
212 gdouble y_diff,
213 const gchar *label)
214{
215 cairo_save (cr);
216
217 cairo_set_source_rgb (cr, 0, 0, 0);
218 cairo_new_path (cr);
219 cairo_move_to (cr, 0, 0);
220 cairo_line_to (cr, x_diff, y_diff);
221 cairo_stroke (cr);
222
223 cairo_move_to (cr, x_diff, y_diff);
224 cairo_show_text (cr, label);
225
226 cairo_restore (cr);
227}
228
229static void
230draw_axes_info (cairo_t *cr,
231 AxesInfo *info,
232 CtkAllocation *allocation)
233{
234 gdouble pressure, tilt_x, tilt_y, distance, wheel, rotation, slider;
235 CdkAxisFlags axes = cdk_device_get_axes (info->last_source);
236
237 cairo_save (cr);
238
239 cairo_set_line_width (cr, 1);
240 cdk_cairo_set_source_rgba (cr, &info->color);
241
242 cairo_move_to (cr, 0, info->y);
243 cairo_line_to (cr, allocation->width, info->y);
244 cairo_move_to (cr, info->x, 0);
245 cairo_line_to (cr, info->x, allocation->height);
246 cairo_stroke (cr);
247
248 cairo_translate (cr, info->x, info->y);
249
250 if (!info->axes)
251 {
252 cairo_restore (cr);
253 return;
254 }
255
256 if (axes & CDK_AXIS_FLAG_PRESSURE)
257 {
258 cairo_pattern_t *pattern;
259
260 cdk_device_get_axis (info->last_source, info->axes, CDK_AXIS_PRESSURE,
261 &pressure);
262
263 pattern = cairo_pattern_create_radial (0, 0, 0, 0, 0, 100);
264 cairo_pattern_add_color_stop_rgba (pattern, pressure, 1, 0, 0, pressure);
265 cairo_pattern_add_color_stop_rgba (pattern, 1, 0, 0, 1, 0);
266
267 cairo_set_source (cr, pattern);
268
269 cairo_arc (cr, 0, 0, 100, 0, 2 * G_PI3.1415926535897932384626433832795028841971693993751);
270 cairo_fill (cr);
271
272 cairo_pattern_destroy (pattern);
273 }
274
275 if (axes & CDK_AXIS_FLAG_XTILT &&
276 axes & CDK_AXIS_FLAG_YTILT)
277 {
278 cdk_device_get_axis (info->last_source, info->axes, CDK_AXIS_XTILT,
279 &tilt_x);
280 cdk_device_get_axis (info->last_source, info->axes, CDK_AXIS_YTILT,
281 &tilt_y);
282
283 render_arrow (cr, tilt_x * 100, tilt_y * 100, "Tilt");
284 }
285
286 if (axes & CDK_AXIS_FLAG_DISTANCE)
287 {
288 double dashes[] = { 5.0, 5.0 };
289 cairo_text_extents_t extents;
290
291 cdk_device_get_axis (info->last_source, info->axes, CDK_AXIS_DISTANCE,
292 &distance);
293
294 cairo_save (cr);
295
296 cairo_move_to (cr, distance * 100, 0);
297
298 cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
299 cairo_set_dash (cr, dashes, 2, 0.0);
300 cairo_arc (cr, 0, 0, distance * 100, 0, 2 * G_PI3.1415926535897932384626433832795028841971693993751);
301 cairo_stroke (cr);
302
303 cairo_move_to (cr, 0, -distance * 100);
304 cairo_text_extents (cr, "Distance", &extents);
305 cairo_rel_move_to (cr, -extents.width / 2, 0);
306 cairo_show_text (cr, "Distance");
307
308 cairo_move_to (cr, 0, 0);
309
310 cairo_restore (cr);
311 }
312
313 if (axes & CDK_AXIS_FLAG_WHEEL)
314 {
315 cdk_device_get_axis (info->last_source, info->axes, CDK_AXIS_WHEEL,
316 &wheel);
317
318 cairo_save (cr);
319 cairo_set_line_width (cr, 10);
320 cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
321
322 cairo_new_sub_path (cr);
323 cairo_arc (cr, 0, 0, 100, 0, wheel * 2 * G_PI3.1415926535897932384626433832795028841971693993751);
324 cairo_stroke (cr);
325 cairo_restore (cr);
326 }
327
328 if (axes & CDK_AXIS_FLAG_ROTATION)
329 {
330 cdk_device_get_axis (info->last_source, info->axes, CDK_AXIS_ROTATION,
331 &rotation);
332 rotation *= 2 * G_PI3.1415926535897932384626433832795028841971693993751;
333
334 cairo_save (cr);
335 cairo_rotate (cr, - G_PI3.1415926535897932384626433832795028841971693993751 / 2);
336 cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
337 cairo_set_line_width (cr, 5);
338
339 cairo_new_sub_path (cr);
340 cairo_arc (cr, 0, 0, 100, 0, rotation);
341 cairo_stroke (cr);
342 cairo_restore (cr);
343 }
344
345 if (axes & CDK_AXIS_FLAG_SLIDER)
346 {
347 cairo_pattern_t *pattern, *mask;
348
349 cdk_device_get_axis (info->last_source, info->axes, CDK_AXIS_SLIDER,
350 &slider);
351
352 cairo_save (cr);
353
354 cairo_move_to (cr, 0, -10);
355 cairo_rel_line_to (cr, 0, -50);
356 cairo_rel_line_to (cr, 10, 0);
357 cairo_rel_line_to (cr, -5, 50);
358 cairo_close_path (cr);
359
360 cairo_clip_preserve (cr);
361
362 pattern = cairo_pattern_create_linear (0, -10, 0, -60);
363 cairo_pattern_add_color_stop_rgb (pattern, 0, 0, 1, 0);
364 cairo_pattern_add_color_stop_rgb (pattern, 1, 1, 0, 0);
365 cairo_set_source (cr, pattern);
366 cairo_pattern_destroy (pattern);
367
368 mask = cairo_pattern_create_linear (0, -10, 0, -60);
369 cairo_pattern_add_color_stop_rgba (mask, 0, 0, 0, 0, 1);
370 cairo_pattern_add_color_stop_rgba (mask, slider, 0, 0, 0, 1);
371 cairo_pattern_add_color_stop_rgba (mask, slider, 0, 0, 0, 0);
372 cairo_pattern_add_color_stop_rgba (mask, 1, 0, 0, 0, 0);
373 cairo_mask (cr, mask);
374 cairo_pattern_destroy (mask);
375
376 cairo_set_source_rgb (cr, 0, 0, 0);
377 cairo_stroke (cr);
378
379 cairo_restore (cr);
380 }
381
382 cairo_restore (cr);
383}
384
385static const gchar *
386tool_type_to_string (CdkDeviceToolType tool_type)
387{
388 switch (tool_type)
389 {
390 case CDK_DEVICE_TOOL_TYPE_PEN:
391 return "Pen";
392 case CDK_DEVICE_TOOL_TYPE_ERASER:
393 return "Eraser";
394 case CDK_DEVICE_TOOL_TYPE_BRUSH:
395 return "Brush";
396 case CDK_DEVICE_TOOL_TYPE_PENCIL:
397 return "Pencil";
398 case CDK_DEVICE_TOOL_TYPE_AIRBRUSH:
399 return "Airbrush";
400 case CDK_DEVICE_TOOL_TYPE_MOUSE:
401 return "Mouse";
402 case CDK_DEVICE_TOOL_TYPE_LENS:
403 return "Lens cursor";
404 case CDK_DEVICE_TOOL_TYPE_UNKNOWN:
405 default:
406 return "Unknown";
407 }
408}
409
410static void
411draw_device_info (CtkWidget *widget,
412 cairo_t *cr,
413 CdkEventSequence *sequence,
414 gint *y,
415 AxesInfo *info)
416{
417 PangoLayout *layout;
418 GString *string;
419 gint height;
420
421 cairo_save (cr);
422
423 string = g_string_new (NULL((void*)0));
424 g_string_append_printf (string, "Source: %s",
425 cdk_device_get_name (info->last_source));
426
427 if (sequence)
428 g_string_append_printf (string, "\nSequence: %d",
429 GPOINTER_TO_UINT (sequence)((guint) (gulong) (sequence)));
430
431 if (info->last_tool)
432 {
433 const gchar *tool_type;
434 guint64 serial;
435
436 tool_type = tool_type_to_string (cdk_device_tool_get_tool_type (info->last_tool));
437 serial = cdk_device_tool_get_serial (info->last_tool);
438 g_string_append_printf (string, "\nTool: %s", tool_type);
439
440 if (serial != 0)
441 g_string_append_printf (string, ", Serial: %lx", serial);
442 }
443
444 cairo_move_to (cr, 10, *y);
445 layout = ctk_widget_create_pango_layout (widget, string->str);
446 pango_cairo_show_layout (cr, layout);
447 cairo_stroke (cr);
448
449 pango_layout_get_pixel_size (layout, NULL((void*)0), &height);
450
451 cdk_cairo_set_source_rgba (cr, &info->color);
452 cairo_set_line_width (cr, 10);
453 cairo_move_to (cr, 0, *y);
454
455 *y = *y + height;
456 cairo_line_to (cr, 0, *y);
457 cairo_stroke (cr);
458
459 cairo_restore (cr);
460
461 g_object_unref (layout);
462 g_string_free (string, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(string), ((!(0)))) : g_string_free_and_steal (string)) : (g_string_free
) ((string), ((!(0)))))
;
463}
464
465static gboolean
466draw_cb (CtkWidget *widget,
467 cairo_t *cr,
468 gpointer user_data)
469{
470 EventData *data = user_data;
471 CtkAllocation allocation;
472 AxesInfo *info;
473 GHashTableIter iter;
474 gpointer key, value;
475 gint y = 0;
476
477 ctk_widget_get_allocation (widget, &allocation);
478
479 /* Draw Abs info */
480 g_hash_table_iter_init (&iter, data->pointer_info);
481
482 while (g_hash_table_iter_next (&iter, NULL((void*)0), &value))
483 {
484 info = value;
485 draw_axes_info (cr, info, &allocation);
486 }
487
488 g_hash_table_iter_init (&iter, data->touch_info);
489
490 while (g_hash_table_iter_next (&iter, NULL((void*)0), &value))
491 {
492 info = value;
493 draw_axes_info (cr, info, &allocation);
494 }
495
496 /* Draw name, color legend and misc data */
497 g_hash_table_iter_init (&iter, data->pointer_info);
498
499 while (g_hash_table_iter_next (&iter, NULL((void*)0), &value))
500 {
501 info = value;
502 draw_device_info (widget, cr, NULL((void*)0), &y, info);
503 }
504
505 g_hash_table_iter_init (&iter, data->touch_info);
506
507 while (g_hash_table_iter_next (&iter, &key, &value))
508 {
509 info = value;
510 draw_device_info (widget, cr, key, &y, info);
511 }
512
513 return FALSE(0);
514}
515
516static void
517update_label_text (CtkWidget *label,
518 const gchar *text)
519{
520 gchar *markup = NULL((void*)0);
521
522 if (text)
523 markup = g_strdup_printf ("<span font='48.0'>%s</span>", text);
524 ctk_label_set_markup (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((label)), ((ctk_label_get_type ()))))))
, markup);
525 g_free (markup);
526}
527
528static gboolean
529reset_label_text_timeout_cb (gpointer user_data)
530{
531 CtkWidget *label = user_data;
532
533 update_label_text (label, NULL((void*)0));
534 pad_action_timeout_id = 0;
535 return G_SOURCE_REMOVE(0);
536}
537
538static void
539update_label_and_timeout (CtkWidget *label,
540 const gchar *text)
541{
542 if (pad_action_timeout_id)
543 g_source_remove (pad_action_timeout_id);
544
545 update_label_text (label, text);
546 pad_action_timeout_id = g_timeout_add (200, reset_label_text_timeout_cb, label);
547}
548
549static void
550on_action_activate (GSimpleAction *action,
551 GVariant *parameter,
552 gpointer user_data)
553{
554 CtkWidget *label = user_data;
555 const gchar *result;
556
557 result = g_object_get_data (G_OBJECT (action)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((action)), (((GType) ((20) << (2))))))))
, "action-result");
558
559 if (!parameter)
560 update_label_and_timeout (label, result);
561 else
562 {
563 gchar *str;
564
565 str = g_strdup_printf ("%s %.2f", result, g_variant_get_double (parameter));
566 update_label_and_timeout (label, str);
567 g_free (str);
568 }
569}
570
571static void
572init_pad_controller (CtkWidget *window,
573 CtkWidget *label)
574{
575 CtkPadController *pad_controller;
576 GSimpleActionGroup *action_group;
577 GSimpleAction *action;
578 gint i;
579
580 action_group = g_simple_action_group_new ();
581 pad_controller = ctk_pad_controller_new (CTK_WINDOW (window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_window_get_type ()))))))
,
582 G_ACTION_GROUP (action_group)((((GActionGroup*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((action_group)), ((g_action_group_get_type ()))))))
,
583 NULL((void*)0));
584
585 for (i = 0; i < G_N_ELEMENTS (pad_actions)(sizeof (pad_actions) / sizeof ((pad_actions)[0])); i++)
586 {
587 if (pad_actions[i].type == CTK_PAD_ACTION_BUTTON)
588 {
589 action = g_simple_action_new (pad_actions[i].action_name, NULL((void*)0));
590 }
591 else
592 {
593 action = g_simple_action_new_stateful (pad_actions[i].action_name,
594 G_VARIANT_TYPE_DOUBLE((const GVariantType *) "d"), NULL((void*)0));
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
595 }
596
597 g_signal_connect (action, "activate",g_signal_connect_data ((action), ("activate"), (((GCallback) (
on_action_activate))), (label), ((void*)0), (GConnectFlags) 0
)
598 G_CALLBACK (on_action_activate), label)g_signal_connect_data ((action), ("activate"), (((GCallback) (
on_action_activate))), (label), ((void*)0), (GConnectFlags) 0
)
;
599 g_object_set_data (G_OBJECT (action)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((action)), (((GType) ((20) << (2))))))))
, "action-result",
600 (gpointer) pad_action_results[i]);
601 g_action_map_add_action (G_ACTION_MAP (action_group)((((GActionMap*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((action_group)), ((g_action_map_get_type ()))))))
, G_ACTION (action)((((GAction*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((action)), ((g_action_get_type ()))))))
);
602 g_object_unref (action);
603 }
604
605 ctk_pad_controller_set_action_entries (pad_controller, pad_actions,
606 G_N_ELEMENTS (pad_actions)(sizeof (pad_actions) / sizeof ((pad_actions)[0])));
607 g_object_set_data_full (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, "pad-controller",
608 pad_controller, g_object_unref);
609
610 g_object_unref (action_group);
611}
612
613CtkWidget *
614do_event_axes (CtkWidget *toplevel G_GNUC_UNUSED__attribute__ ((__unused__)))
615{
616 static CtkWidget *window = NULL((void*)0);
617
618 if (!window)
619 {
620 EventData *event_data;
621 CtkWidget *box, *label;
622
623 window = ctk_window_new (CTK_WINDOW_TOPLEVEL);
624 ctk_window_set_title (CTK_WINDOW (window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_window_get_type ()))))))
, "Event Axes");
625 ctk_window_set_default_size (CTK_WINDOW (window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_window_get_type ()))))))
, 400, 400);
626
627 g_signal_connect (window, "destroy",g_signal_connect_data ((window), ("destroy"), (((GCallback) (
ctk_widget_destroyed))), (&window), ((void*)0), (GConnectFlags
) 0)
628 G_CALLBACK (ctk_widget_destroyed), &window)g_signal_connect_data ((window), ("destroy"), (((GCallback) (
ctk_widget_destroyed))), (&window), ((void*)0), (GConnectFlags
) 0)
;
629
630 box = ctk_event_box_new ();
631 ctk_container_add (CTK_CONTAINER (window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_container_get_type ()))))))
, box);
632 ctk_widget_set_support_multidevice (box, TRUE(!(0)));
633 ctk_widget_add_events (box,
634 CDK_POINTER_MOTION_MASK |
635 CDK_BUTTON_PRESS_MASK |
636 CDK_BUTTON_RELEASE_MASK |
637 CDK_SMOOTH_SCROLL_MASK |
638 CDK_ENTER_NOTIFY_MASK |
639 CDK_LEAVE_NOTIFY_MASK |
640 CDK_TOUCH_MASK);
641
642 event_data = event_data_new ();
643 g_object_set_data_full (G_OBJECT (box)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((box)), (((GType) ((20) << (2))))))))
, "ctk-demo-event-data",
644 event_data, (GDestroyNotify) event_data_free);
645
646 g_signal_connect (box, "event",g_signal_connect_data ((box), ("event"), (((GCallback) (event_cb
))), (event_data), ((void*)0), (GConnectFlags) 0)
647 G_CALLBACK (event_cb), event_data)g_signal_connect_data ((box), ("event"), (((GCallback) (event_cb
))), (event_data), ((void*)0), (GConnectFlags) 0)
;
648 g_signal_connect (box, "draw",g_signal_connect_data ((box), ("draw"), (((GCallback) (draw_cb
))), (event_data), ((void*)0), (GConnectFlags) 0)
649 G_CALLBACK (draw_cb), event_data)g_signal_connect_data ((box), ("draw"), (((GCallback) (draw_cb
))), (event_data), ((void*)0), (GConnectFlags) 0)
;
650
651 label = ctk_label_new ("");
652 ctk_label_set_use_markup (CTK_LABEL (label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((label)), ((ctk_label_get_type ()))))))
, TRUE(!(0)));
653 ctk_container_add (CTK_CONTAINER (box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((box)), ((ctk_container_get_type ()))))))
, label);
654
655 init_pad_controller (window, label);
656 }
657
658 if (!ctk_widget_get_visible (window))
659 ctk_widget_show_all (window);
660 else
661 ctk_widget_destroy (window);
662
663 return window;
664}