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 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |
27 | typedef struct { |
28 | CdkDevice *last_source; |
29 | CdkDeviceTool *last_tool; |
30 | gdouble *axes; |
31 | CdkRGBA color; |
32 | gdouble x; |
33 | gdouble y; |
34 | } AxesInfo; |
35 | |
36 | typedef struct { |
37 | GHashTable *pointer_info; /* CdkDevice -> AxesInfo */ |
38 | GHashTable *touch_info; /* CdkEventSequence -> AxesInfo */ |
39 | } EventData; |
40 | |
41 | const 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 | |
56 | static 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 | |
67 | static const gchar *pad_action_results[] = { |
68 | "☢", |
69 | "♨", |
70 | "☼", |
71 | "☄", |
72 | "⚡", |
73 | "💫", |
74 | "◑", |
75 | "⚛" |
76 | }; |
77 | |
78 | static guint cur_color = 0; |
79 | static guint pad_action_timeout_id = 0; |
80 | |
81 | static AxesInfo * |
82 | axes_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 | |
94 | static EventData * |
95 | event_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 | |
108 | static void |
109 | event_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 | |
116 | static void |
117 | update_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 | |
199 | static gboolean |
200 | event_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 | |
209 | static void |
210 | render_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 | |
229 | static void |
230 | draw_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 | |
385 | static const gchar * |
386 | tool_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 | |
410 | static void |
411 | draw_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 | |
465 | static gboolean |
466 | draw_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 | |
516 | static void |
517 | update_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 | |
528 | static gboolean |
529 | reset_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 | |
538 | static void |
539 | update_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 | |
549 | static void |
550 | on_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 | |
571 | static void |
572 | init_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 | |
613 | CtkWidget * |
614 | do_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 | } |