1 /*
2 * Clutter.
3 *
4 * An OpenGL based 'interactive canvas' library.
5 *
6 * Authored By Matthew Allum <mallum@openedhand.com>
7 *
8 * Copyright (C) 2006 OpenedHand
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
22 *
23 *
24 */
25
26 #include "clutter-build-config.h"
27
28 #include "clutter-backend-private.h"
29 #include "clutter-debug.h"
30 #include "clutter-event-private.h"
31 #include "clutter-keysyms.h"
32 #include "clutter-private.h"
33
34 #include <math.h>
35
36 /**
37 * SECTION:clutter-event
38 * @short_description: User and window system events
39 *
40 * Windowing events handled by Clutter.
41 *
42 * The events usually come from the windowing backend, but can also
43 * be synthesized by Clutter itself or by the application code.
44 */
45
46 typedef struct _ClutterEventPrivate {
47 ClutterEvent base;
48
49 ClutterInputDevice *device;
50 ClutterInputDevice *source_device;
51
52 gdouble delta_x;
53 gdouble delta_y;
54
55 ClutterInputDeviceTool *tool;
56
57 gpointer platform_data;
58
59 ClutterModifierType button_state;
60 ClutterModifierType base_state;
61 ClutterModifierType latched_state;
62 ClutterModifierType locked_state;
63
64 guint is_pointer_emulated : 1;
65 } ClutterEventPrivate;
66
67 typedef struct _ClutterEventFilter {
68 int id;
69
70 ClutterStage *stage;
71 ClutterEventFilterFunc func;
72 GDestroyNotify notify;
73 gpointer user_data;
74 } ClutterEventFilter;
75
76 G_DEFINE_BOXED_TYPE (ClutterEvent, clutter_event,
77 clutter_event_copy,
78 clutter_event_free);
79
80 static ClutterEventSequence *
clutter_event_sequence_copy(ClutterEventSequence * sequence)81 clutter_event_sequence_copy (ClutterEventSequence *sequence)
82 {
83 /* Nothing to copy here */
84 return sequence;
85 }
86
87 static void
clutter_event_sequence_free(ClutterEventSequence * sequence)88 clutter_event_sequence_free (ClutterEventSequence *sequence)
89 {
90 /* Nothing to free here */
91 }
92
93 G_DEFINE_BOXED_TYPE (ClutterEventSequence, clutter_event_sequence,
94 clutter_event_sequence_copy,
95 clutter_event_sequence_free);
96
97 /*
98 * _clutter_event_get_platform_data:
99 * @event: a #ClutterEvent
100 *
101 * Retrieves the pointer to platform-specific data inside an event
102 *
103 * Return value: a pointer to platform-specific data
104 *
105 * Since: 1.4
106 */
107 gpointer
_clutter_event_get_platform_data(const ClutterEvent * event)108 _clutter_event_get_platform_data (const ClutterEvent *event)
109 {
110 return ((ClutterEventPrivate *) event)->platform_data;
111 }
112
113 /*< private >
114 * _clutter_event_set_platform_data:
115 * @event: a #ClutterEvent
116 * @data: a pointer to platform-specific data
117 *
118 * Sets the pointer to platform-specific data inside an event
119 *
120 * Since: 1.4
121 */
122 void
_clutter_event_set_platform_data(ClutterEvent * event,gpointer data)123 _clutter_event_set_platform_data (ClutterEvent *event,
124 gpointer data)
125 {
126 ((ClutterEventPrivate *) event)->platform_data = data;
127 }
128
129 void
_clutter_event_set_pointer_emulated(ClutterEvent * event,gboolean is_emulated)130 _clutter_event_set_pointer_emulated (ClutterEvent *event,
131 gboolean is_emulated)
132 {
133 ((ClutterEventPrivate *) event)->is_pointer_emulated = !!is_emulated;
134 }
135
136 /**
137 * clutter_event_type:
138 * @event: a #ClutterEvent
139 *
140 * Retrieves the type of the event.
141 *
142 * Return value: a #ClutterEventType
143 */
144 ClutterEventType
clutter_event_type(const ClutterEvent * event)145 clutter_event_type (const ClutterEvent *event)
146 {
147 g_return_val_if_fail (event != NULL, CLUTTER_NOTHING);
148
149 return event->type;
150 }
151
152 /**
153 * clutter_event_get_time:
154 * @event: a #ClutterEvent
155 *
156 * Retrieves the time of the event.
157 *
158 * Return value: the time of the event, or %CLUTTER_CURRENT_TIME
159 *
160 * Since: 0.4
161 */
162 guint32
clutter_event_get_time(const ClutterEvent * event)163 clutter_event_get_time (const ClutterEvent *event)
164 {
165 g_return_val_if_fail (event != NULL, CLUTTER_CURRENT_TIME);
166
167 return event->any.time;
168 }
169
170 /**
171 * clutter_event_set_time:
172 * @event: a #ClutterEvent
173 * @time_: the time of the event
174 *
175 * Sets the time of the event.
176 *
177 * Since: 1.8
178 */
179 void
clutter_event_set_time(ClutterEvent * event,guint32 time_)180 clutter_event_set_time (ClutterEvent *event,
181 guint32 time_)
182 {
183 g_return_if_fail (event != NULL);
184
185 event->any.time = time_;
186 }
187
188 /**
189 * clutter_event_get_state:
190 * @event: a #ClutterEvent
191 *
192 * Retrieves the modifier state of the event. In case the window system
193 * supports reporting latched and locked modifiers, this function returns
194 * the effective state.
195 *
196 * Return value: the modifier state parameter, or 0
197 *
198 * Since: 0.4
199 */
200 ClutterModifierType
clutter_event_get_state(const ClutterEvent * event)201 clutter_event_get_state (const ClutterEvent *event)
202 {
203 g_return_val_if_fail (event != NULL, 0);
204
205 switch (event->type)
206 {
207 case CLUTTER_KEY_PRESS:
208 case CLUTTER_KEY_RELEASE:
209 return event->key.modifier_state;
210
211 case CLUTTER_BUTTON_PRESS:
212 case CLUTTER_BUTTON_RELEASE:
213 return event->button.modifier_state;
214
215 case CLUTTER_TOUCH_BEGIN:
216 case CLUTTER_TOUCH_UPDATE:
217 case CLUTTER_TOUCH_END:
218 case CLUTTER_TOUCH_CANCEL:
219 return event->touch.modifier_state;
220
221 case CLUTTER_MOTION:
222 return event->motion.modifier_state;
223
224 case CLUTTER_SCROLL:
225 return event->scroll.modifier_state;
226
227 default:
228 break;
229 }
230
231 return 0;
232 }
233
234 /**
235 * clutter_event_set_state:
236 * @event: a #ClutterEvent
237 * @state: the modifier state to set
238 *
239 * Sets the modifier state of the event.
240 *
241 * Since: 1.8
242 */
243 void
clutter_event_set_state(ClutterEvent * event,ClutterModifierType state)244 clutter_event_set_state (ClutterEvent *event,
245 ClutterModifierType state)
246 {
247 g_return_if_fail (event != NULL);
248
249 switch (event->type)
250 {
251 case CLUTTER_KEY_PRESS:
252 case CLUTTER_KEY_RELEASE:
253 event->key.modifier_state = state;
254 break;
255
256 case CLUTTER_BUTTON_PRESS:
257 case CLUTTER_BUTTON_RELEASE:
258 event->button.modifier_state = state;
259 break;
260
261 case CLUTTER_MOTION:
262 event->motion.modifier_state = state;
263 break;
264
265 case CLUTTER_TOUCH_BEGIN:
266 case CLUTTER_TOUCH_UPDATE:
267 case CLUTTER_TOUCH_END:
268 case CLUTTER_TOUCH_CANCEL:
269 event->touch.modifier_state = state;
270 break;
271
272 case CLUTTER_SCROLL:
273 event->scroll.modifier_state = state;
274 break;
275
276 default:
277 break;
278 }
279 }
280
281 void
_clutter_event_set_state_full(ClutterEvent * event,ClutterModifierType button_state,ClutterModifierType base_state,ClutterModifierType latched_state,ClutterModifierType locked_state,ClutterModifierType effective_state)282 _clutter_event_set_state_full (ClutterEvent *event,
283 ClutterModifierType button_state,
284 ClutterModifierType base_state,
285 ClutterModifierType latched_state,
286 ClutterModifierType locked_state,
287 ClutterModifierType effective_state)
288 {
289 ClutterEventPrivate *private = (ClutterEventPrivate*) event;
290
291 private->button_state = button_state;
292 private->base_state = base_state;
293 private->latched_state = latched_state;
294 private->locked_state = locked_state;
295
296 clutter_event_set_state (event, effective_state);
297 }
298
299 /**
300 * clutter_event_get_state_full:
301 * @event: a #ClutterEvent
302 * @button_state: (out) (allow-none): the pressed buttons as a mask
303 * @base_state: (out) (allow-none): the regular pressed modifier keys
304 * @latched_state: (out) (allow-none): the latched modifier keys (currently released but still valid for one key press/release)
305 * @locked_state: (out) (allow-none): the locked modifier keys (valid until the lock key is pressed and released again)
306 * @effective_state: (out) (allow-none): the logical OR of all the state bits above
307 *
308 * Retrieves the decomposition of the keyboard state into button, base,
309 * latched, locked and effective. This can be used to transmit to other
310 * applications, for example when implementing a wayland compositor.
311 *
312 * Since: 1.16
313 */
314 void
clutter_event_get_state_full(const ClutterEvent * event,ClutterModifierType * button_state,ClutterModifierType * base_state,ClutterModifierType * latched_state,ClutterModifierType * locked_state,ClutterModifierType * effective_state)315 clutter_event_get_state_full (const ClutterEvent *event,
316 ClutterModifierType *button_state,
317 ClutterModifierType *base_state,
318 ClutterModifierType *latched_state,
319 ClutterModifierType *locked_state,
320 ClutterModifierType *effective_state)
321 {
322 const ClutterEventPrivate *private = (const ClutterEventPrivate*) event;
323
324 g_return_if_fail (event != NULL);
325
326 if (button_state)
327 *button_state = private->button_state;
328 if (base_state)
329 *base_state = private->base_state;
330 if (latched_state)
331 *latched_state = private->latched_state;
332 if (locked_state)
333 *locked_state = private->locked_state;
334 if (effective_state)
335 *effective_state = clutter_event_get_state (event);
336 }
337
338 /**
339 * clutter_event_get_coords:
340 * @event: a #ClutterEvent
341 * @x: (out): return location for the X coordinate, or %NULL
342 * @y: (out): return location for the Y coordinate, or %NULL
343 *
344 * Retrieves the coordinates of @event and puts them into @x and @y.
345 *
346 * Since: 0.4
347 */
348 void
clutter_event_get_coords(const ClutterEvent * event,gfloat * x,gfloat * y)349 clutter_event_get_coords (const ClutterEvent *event,
350 gfloat *x,
351 gfloat *y)
352 {
353 graphene_point_t coords;
354
355 g_return_if_fail (event != NULL);
356
357 clutter_event_get_position (event, &coords);
358
359 if (x != NULL)
360 *x = coords.x;
361
362 if (y != NULL)
363 *y = coords.y;
364 }
365
366 /**
367 * clutter_event_get_position:
368 * @event: a #ClutterEvent
369 * @position: a #graphene_point_t
370 *
371 * Retrieves the event coordinates as a #graphene_point_t.
372 *
373 * Since: 1.12
374 */
375 void
clutter_event_get_position(const ClutterEvent * event,graphene_point_t * position)376 clutter_event_get_position (const ClutterEvent *event,
377 graphene_point_t *position)
378 {
379 g_return_if_fail (event != NULL);
380 g_return_if_fail (position != NULL);
381
382 switch (event->type)
383 {
384 case CLUTTER_NOTHING:
385 case CLUTTER_KEY_PRESS:
386 case CLUTTER_KEY_RELEASE:
387 case CLUTTER_EVENT_LAST:
388 case CLUTTER_PROXIMITY_IN:
389 case CLUTTER_PROXIMITY_OUT:
390 case CLUTTER_PAD_BUTTON_PRESS:
391 case CLUTTER_PAD_BUTTON_RELEASE:
392 case CLUTTER_PAD_STRIP:
393 case CLUTTER_PAD_RING:
394 case CLUTTER_DEVICE_ADDED:
395 case CLUTTER_DEVICE_REMOVED:
396 case CLUTTER_IM_COMMIT:
397 case CLUTTER_IM_DELETE:
398 case CLUTTER_IM_PREEDIT:
399 graphene_point_init (position, 0.f, 0.f);
400 break;
401
402 case CLUTTER_ENTER:
403 case CLUTTER_LEAVE:
404 graphene_point_init (position, event->crossing.x, event->crossing.y);
405 break;
406
407 case CLUTTER_BUTTON_PRESS:
408 case CLUTTER_BUTTON_RELEASE:
409 graphene_point_init (position, event->button.x, event->button.y);
410 break;
411
412 case CLUTTER_MOTION:
413 graphene_point_init (position, event->motion.x, event->motion.y);
414 break;
415
416 case CLUTTER_TOUCH_BEGIN:
417 case CLUTTER_TOUCH_UPDATE:
418 case CLUTTER_TOUCH_END:
419 case CLUTTER_TOUCH_CANCEL:
420 graphene_point_init (position, event->touch.x, event->touch.y);
421 break;
422
423 case CLUTTER_SCROLL:
424 graphene_point_init (position, event->scroll.x, event->scroll.y);
425 break;
426
427 case CLUTTER_TOUCHPAD_PINCH:
428 graphene_point_init (position, event->touchpad_pinch.x,
429 event->touchpad_pinch.y);
430 break;
431
432 case CLUTTER_TOUCHPAD_SWIPE:
433 graphene_point_init (position, event->touchpad_swipe.x,
434 event->touchpad_swipe.y);
435 break;
436 }
437
438 }
439
440 /**
441 * clutter_event_set_coords:
442 * @event: a #ClutterEvent
443 * @x: the X coordinate of the event
444 * @y: the Y coordinate of the event
445 *
446 * Sets the coordinates of the @event.
447 *
448 * Since: 1.8
449 */
450 void
clutter_event_set_coords(ClutterEvent * event,gfloat x,gfloat y)451 clutter_event_set_coords (ClutterEvent *event,
452 gfloat x,
453 gfloat y)
454 {
455 g_return_if_fail (event != NULL);
456
457 switch (event->type)
458 {
459 case CLUTTER_NOTHING:
460 case CLUTTER_KEY_PRESS:
461 case CLUTTER_KEY_RELEASE:
462 case CLUTTER_EVENT_LAST:
463 case CLUTTER_PROXIMITY_IN:
464 case CLUTTER_PROXIMITY_OUT:
465 case CLUTTER_PAD_BUTTON_PRESS:
466 case CLUTTER_PAD_BUTTON_RELEASE:
467 case CLUTTER_PAD_STRIP:
468 case CLUTTER_PAD_RING:
469 case CLUTTER_DEVICE_ADDED:
470 case CLUTTER_DEVICE_REMOVED:
471 case CLUTTER_IM_COMMIT:
472 case CLUTTER_IM_DELETE:
473 case CLUTTER_IM_PREEDIT:
474 break;
475
476 case CLUTTER_ENTER:
477 case CLUTTER_LEAVE:
478 event->crossing.x = x;
479 event->crossing.y = y;
480 break;
481
482 case CLUTTER_BUTTON_PRESS:
483 case CLUTTER_BUTTON_RELEASE:
484 event->button.x = x;
485 event->button.y = y;
486 break;
487
488 case CLUTTER_MOTION:
489 event->motion.x = x;
490 event->motion.y = y;
491 break;
492
493 case CLUTTER_TOUCH_BEGIN:
494 case CLUTTER_TOUCH_UPDATE:
495 case CLUTTER_TOUCH_END:
496 case CLUTTER_TOUCH_CANCEL:
497 event->touch.x = x;
498 event->touch.y = y;
499 break;
500
501 case CLUTTER_SCROLL:
502 event->scroll.x = x;
503 event->scroll.y = y;
504 break;
505
506 case CLUTTER_TOUCHPAD_PINCH:
507 event->touchpad_pinch.x = x;
508 event->touchpad_pinch.y = y;
509 break;
510
511 case CLUTTER_TOUCHPAD_SWIPE:
512 event->touchpad_swipe.x = x;
513 event->touchpad_swipe.y = y;
514 break;
515 }
516 }
517
518 /**
519 * clutter_event_get_source:
520 * @event: a #ClutterEvent
521 *
522 * Retrieves the source #ClutterActor the event originated from, or
523 * NULL if the event has no source.
524 *
525 * Return value: (transfer none): a #ClutterActor
526 *
527 * Since: 0.6
528 */
529 ClutterActor *
clutter_event_get_source(const ClutterEvent * event)530 clutter_event_get_source (const ClutterEvent *event)
531 {
532 g_return_val_if_fail (event != NULL, NULL);
533
534 return event->any.source;
535 }
536
537 /**
538 * clutter_event_set_source:
539 * @event: a #ClutterEvent
540 * @actor: (allow-none): a #ClutterActor, or %NULL
541 *
542 * Sets the source #ClutterActor of @event.
543 *
544 * Since: 1.8
545 */
546 void
clutter_event_set_source(ClutterEvent * event,ClutterActor * actor)547 clutter_event_set_source (ClutterEvent *event,
548 ClutterActor *actor)
549 {
550 g_return_if_fail (event != NULL);
551 g_return_if_fail (actor == NULL || CLUTTER_IS_ACTOR (actor));
552
553 event->any.source = actor;
554 }
555
556 /**
557 * clutter_event_get_stage:
558 * @event: a #ClutterEvent
559 *
560 * Retrieves the source #ClutterStage the event originated for, or
561 * %NULL if the event has no stage.
562 *
563 * Return value: (transfer none): a #ClutterStage
564 *
565 * Since: 0.8
566 */
567 ClutterStage *
clutter_event_get_stage(const ClutterEvent * event)568 clutter_event_get_stage (const ClutterEvent *event)
569 {
570 g_return_val_if_fail (event != NULL, NULL);
571
572 return event->any.stage;
573 }
574
575 /**
576 * clutter_event_set_stage:
577 * @event: a #ClutterEvent
578 * @stage: (allow-none): a #ClutterStage, or %NULL
579 *
580 * Sets the source #ClutterStage of the event.
581 *
582 * Since: 1.8
583 */
584 void
clutter_event_set_stage(ClutterEvent * event,ClutterStage * stage)585 clutter_event_set_stage (ClutterEvent *event,
586 ClutterStage *stage)
587 {
588 g_return_if_fail (event != NULL);
589 g_return_if_fail (stage == NULL || CLUTTER_IS_STAGE (stage));
590
591 if (event->any.stage == stage)
592 return;
593
594 event->any.stage = stage;
595 }
596
597 /**
598 * clutter_event_get_flags:
599 * @event: a #ClutterEvent
600 *
601 * Retrieves the #ClutterEventFlags of @event
602 *
603 * Return value: the event flags
604 *
605 * Since: 1.0
606 */
607 ClutterEventFlags
clutter_event_get_flags(const ClutterEvent * event)608 clutter_event_get_flags (const ClutterEvent *event)
609 {
610 g_return_val_if_fail (event != NULL, CLUTTER_EVENT_NONE);
611
612 return event->any.flags;
613 }
614
615 /**
616 * clutter_event_set_flags:
617 * @event: a #ClutterEvent
618 * @flags: a binary OR of #ClutterEventFlags values
619 *
620 * Sets the #ClutterEventFlags of @event
621 *
622 * Since: 1.8
623 */
624 void
clutter_event_set_flags(ClutterEvent * event,ClutterEventFlags flags)625 clutter_event_set_flags (ClutterEvent *event,
626 ClutterEventFlags flags)
627 {
628 g_return_if_fail (event != NULL);
629
630 if (event->any.flags == flags)
631 return;
632
633 event->any.flags = flags;
634 event->any.flags |= CLUTTER_EVENT_FLAG_SYNTHETIC;
635 }
636
637 /**
638 * clutter_event_get_related:
639 * @event: a #ClutterEvent of type %CLUTTER_ENTER or of
640 * type %CLUTTER_LEAVE
641 *
642 * Retrieves the related actor of a crossing event.
643 *
644 * Return value: (transfer none): the related #ClutterActor, or %NULL
645 *
646 * Since: 1.0
647 */
648 ClutterActor *
clutter_event_get_related(const ClutterEvent * event)649 clutter_event_get_related (const ClutterEvent *event)
650 {
651 g_return_val_if_fail (event != NULL, NULL);
652 g_return_val_if_fail (event->type == CLUTTER_ENTER ||
653 event->type == CLUTTER_LEAVE, NULL);
654
655 return event->crossing.related;
656 }
657
658 /**
659 * clutter_event_set_related:
660 * @event: a #ClutterEvent of type %CLUTTER_ENTER or %CLUTTER_LEAVE
661 * @actor: (allow-none): a #ClutterActor or %NULL
662 *
663 * Sets the related actor of a crossing event
664 *
665 * Since: 1.8
666 */
667 void
clutter_event_set_related(ClutterEvent * event,ClutterActor * actor)668 clutter_event_set_related (ClutterEvent *event,
669 ClutterActor *actor)
670 {
671 g_return_if_fail (event != NULL);
672 g_return_if_fail (event->type == CLUTTER_ENTER ||
673 event->type == CLUTTER_LEAVE);
674 g_return_if_fail (actor == NULL || CLUTTER_IS_ACTOR (actor));
675
676 if (event->crossing.related == actor)
677 return;
678
679 event->crossing.related = actor;
680 }
681
682 /**
683 * clutter_event_set_scroll_delta:
684 * @event: a #ClutterEvent of type %CLUTTER_SCROLL
685 * @dx: delta on the horizontal axis
686 * @dy: delta on the vertical axis
687 *
688 * Sets the precise scrolling information of @event.
689 *
690 * Since: 1.10
691 */
692 void
clutter_event_set_scroll_delta(ClutterEvent * event,gdouble dx,gdouble dy)693 clutter_event_set_scroll_delta (ClutterEvent *event,
694 gdouble dx,
695 gdouble dy)
696 {
697 g_return_if_fail (event != NULL);
698 g_return_if_fail (event->type == CLUTTER_SCROLL);
699
700 event->scroll.direction = CLUTTER_SCROLL_SMOOTH;
701
702 ((ClutterEventPrivate *) event)->delta_x = dx;
703 ((ClutterEventPrivate *) event)->delta_y = dy;
704 }
705
706 /**
707 * clutter_event_get_scroll_delta:
708 * @event: a #ClutterEvent of type %CLUTTER_SCROLL
709 * @dx: (out): return location for the delta on the horizontal axis
710 * @dy: (out): return location for the delta on the vertical axis
711 *
712 * Retrieves the precise scrolling information of @event.
713 *
714 * The @event has to have a #ClutterScrollEvent.direction value
715 * of %CLUTTER_SCROLL_SMOOTH.
716 *
717 * Since: 1.10
718 */
719 void
clutter_event_get_scroll_delta(const ClutterEvent * event,gdouble * dx,gdouble * dy)720 clutter_event_get_scroll_delta (const ClutterEvent *event,
721 gdouble *dx,
722 gdouble *dy)
723 {
724 gdouble delta_x, delta_y;
725
726 g_return_if_fail (event != NULL);
727 g_return_if_fail (event->type == CLUTTER_SCROLL);
728 g_return_if_fail (event->scroll.direction == CLUTTER_SCROLL_SMOOTH);
729
730 delta_x = ((ClutterEventPrivate *) event)->delta_x;
731 delta_y = ((ClutterEventPrivate *) event)->delta_y;
732
733 if (dx != NULL)
734 *dx = delta_x;
735
736 if (dy != NULL)
737 *dy = delta_y;
738 }
739
740 /**
741 * clutter_event_get_scroll_direction:
742 * @event: a #ClutterEvent of type %CLUTTER_SCROLL
743 *
744 * Retrieves the direction of the scrolling of @event
745 *
746 * Return value: the scrolling direction
747 *
748 * Since: 1.0
749 */
750 ClutterScrollDirection
clutter_event_get_scroll_direction(const ClutterEvent * event)751 clutter_event_get_scroll_direction (const ClutterEvent *event)
752 {
753 g_return_val_if_fail (event != NULL, CLUTTER_SCROLL_UP);
754 g_return_val_if_fail (event->type == CLUTTER_SCROLL, CLUTTER_SCROLL_UP);
755
756 return event->scroll.direction;
757 }
758
759 /**
760 * clutter_event_set_scroll_direction:
761 * @event: a #ClutterEvent
762 * @direction: the scrolling direction
763 *
764 * Sets the direction of the scrolling of @event
765 *
766 * Since: 1.8
767 */
768 void
clutter_event_set_scroll_direction(ClutterEvent * event,ClutterScrollDirection direction)769 clutter_event_set_scroll_direction (ClutterEvent *event,
770 ClutterScrollDirection direction)
771 {
772 g_return_if_fail (event != NULL);
773 g_return_if_fail (event->type == CLUTTER_SCROLL);
774
775 event->scroll.direction = direction;
776 }
777
778 /**
779 * clutter_event_get_button:
780 * @event: a #ClutterEvent of type %CLUTTER_BUTTON_PRESS or
781 * of type %CLUTTER_BUTTON_RELEASE
782 *
783 * Retrieves the button number of @event
784 *
785 * Return value: the button number
786 *
787 * Since: 1.0
788 */
789 guint32
clutter_event_get_button(const ClutterEvent * event)790 clutter_event_get_button (const ClutterEvent *event)
791 {
792 g_return_val_if_fail (event != NULL, 0);
793 g_return_val_if_fail (event->type == CLUTTER_BUTTON_PRESS ||
794 event->type == CLUTTER_BUTTON_RELEASE ||
795 event->type == CLUTTER_PAD_BUTTON_PRESS ||
796 event->type == CLUTTER_PAD_BUTTON_RELEASE, 0);
797
798 if (event->type == CLUTTER_BUTTON_PRESS ||
799 event->type == CLUTTER_BUTTON_RELEASE)
800 return event->button.button;
801 else
802 return event->pad_button.button;
803 }
804
805 /**
806 * clutter_event_set_button:
807 * @event: a #ClutterEvent or type %CLUTTER_BUTTON_PRESS or
808 * of type %CLUTTER_BUTTON_RELEASE
809 * @button: the button number
810 *
811 * Sets the button number of @event
812 *
813 * Since: 1.8
814 */
815 void
clutter_event_set_button(ClutterEvent * event,guint32 button)816 clutter_event_set_button (ClutterEvent *event,
817 guint32 button)
818 {
819 g_return_if_fail (event != NULL);
820 g_return_if_fail (event->type == CLUTTER_BUTTON_PRESS ||
821 event->type == CLUTTER_BUTTON_RELEASE);
822
823 event->button.button = button;
824 }
825
826 /**
827 * clutter_event_get_click_count:
828 * @event: a #ClutterEvent of type %CLUTTER_BUTTON_PRESS or
829 * of type %CLUTTER_BUTTON_RELEASE
830 *
831 * Retrieves the number of clicks of @event
832 *
833 * Return value: the click count
834 *
835 * Since: 1.0
836 */
837 guint32
clutter_event_get_click_count(const ClutterEvent * event)838 clutter_event_get_click_count (const ClutterEvent *event)
839 {
840 g_return_val_if_fail (event != NULL, 0);
841 g_return_val_if_fail (event->type == CLUTTER_BUTTON_PRESS ||
842 event->type == CLUTTER_BUTTON_RELEASE, 0);
843
844 return event->button.click_count;
845 }
846
847 /* keys */
848
849 /**
850 * clutter_event_get_key_symbol:
851 * @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS or
852 * of type %CLUTTER_KEY_RELEASE
853 *
854 * Retrieves the key symbol of @event
855 *
856 * Return value: the key symbol representing the key
857 *
858 * Since: 1.0
859 */
860 guint
clutter_event_get_key_symbol(const ClutterEvent * event)861 clutter_event_get_key_symbol (const ClutterEvent *event)
862 {
863 g_return_val_if_fail (event != NULL, 0);
864 g_return_val_if_fail (event->type == CLUTTER_KEY_PRESS ||
865 event->type == CLUTTER_KEY_RELEASE, 0);
866
867 return event->key.keyval;
868 }
869
870 /**
871 * clutter_event_set_key_symbol:
872 * @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS
873 * or %CLUTTER_KEY_RELEASE
874 * @key_sym: the key symbol representing the key
875 *
876 * Sets the key symbol of @event.
877 *
878 * Since: 1.8
879 */
880 void
clutter_event_set_key_symbol(ClutterEvent * event,guint key_sym)881 clutter_event_set_key_symbol (ClutterEvent *event,
882 guint key_sym)
883 {
884 g_return_if_fail (event != NULL);
885 g_return_if_fail (event->type == CLUTTER_KEY_PRESS ||
886 event->type == CLUTTER_KEY_RELEASE);
887
888 event->key.keyval = key_sym;
889 }
890
891 /**
892 * clutter_event_get_key_code:
893 * @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS or
894 * of type %CLUTTER_KEY_RELEASE
895 *
896 * Retrieves the keycode of the key that caused @event
897 *
898 * Return value: The keycode representing the key
899 *
900 * Since: 1.0
901 */
902 guint16
clutter_event_get_key_code(const ClutterEvent * event)903 clutter_event_get_key_code (const ClutterEvent *event)
904 {
905 g_return_val_if_fail (event != NULL, 0);
906 g_return_val_if_fail (event->type == CLUTTER_KEY_PRESS ||
907 event->type == CLUTTER_KEY_RELEASE, 0);
908
909 return event->key.hardware_keycode;
910 }
911
912 /**
913 * clutter_event_set_key_code:
914 * @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS
915 * or %CLUTTER_KEY_RELEASE
916 * @key_code: the keycode representing the key
917 *
918 * Sets the keycode of the @event.
919 *
920 * Since: 1.8
921 */
922 void
clutter_event_set_key_code(ClutterEvent * event,guint16 key_code)923 clutter_event_set_key_code (ClutterEvent *event,
924 guint16 key_code)
925 {
926 g_return_if_fail (event != NULL);
927 g_return_if_fail (event->type == CLUTTER_KEY_PRESS ||
928 event->type == CLUTTER_KEY_RELEASE);
929
930 event->key.hardware_keycode = key_code;
931 }
932
933 /**
934 * clutter_event_get_key_unicode:
935 * @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS
936 * or %CLUTTER_KEY_RELEASE
937 *
938 * Retrieves the unicode value for the key that caused @keyev.
939 *
940 * Return value: The unicode value representing the key
941 */
942 gunichar
clutter_event_get_key_unicode(const ClutterEvent * event)943 clutter_event_get_key_unicode (const ClutterEvent *event)
944 {
945 g_return_val_if_fail (event != NULL, 0);
946 g_return_val_if_fail (event->type == CLUTTER_KEY_PRESS ||
947 event->type == CLUTTER_KEY_RELEASE, 0);
948
949 if (event->key.unicode_value)
950 return event->key.unicode_value;
951 else
952 return clutter_keysym_to_unicode (event->key.keyval);
953 }
954
955 /**
956 * clutter_event_set_key_unicode:
957 * @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS
958 * or %CLUTTER_KEY_RELEASE
959 * @key_unicode: the Unicode value representing the key
960 *
961 * Sets the Unicode value of @event.
962 *
963 * Since: 1.8
964 */
965 void
clutter_event_set_key_unicode(ClutterEvent * event,gunichar key_unicode)966 clutter_event_set_key_unicode (ClutterEvent *event,
967 gunichar key_unicode)
968 {
969 g_return_if_fail (event != NULL);
970 g_return_if_fail (event->type == CLUTTER_KEY_PRESS ||
971 event->type == CLUTTER_KEY_RELEASE);
972
973 event->key.unicode_value = key_unicode;
974 }
975
976 /**
977 * clutter_event_get_event_sequence:
978 * @event: a #ClutterEvent of type %CLUTTER_TOUCH_BEGIN,
979 * %CLUTTER_TOUCH_UPDATE, %CLUTTER_TOUCH_END, or
980 * %CLUTTER_TOUCH_CANCEL
981 *
982 * Retrieves the #ClutterEventSequence of @event.
983 *
984 * Return value: (transfer none): the event sequence, or %NULL
985 *
986 * Since: 1.10
987 */
988 ClutterEventSequence *
clutter_event_get_event_sequence(const ClutterEvent * event)989 clutter_event_get_event_sequence (const ClutterEvent *event)
990 {
991 g_return_val_if_fail (event != NULL, NULL);
992
993 if (event->type == CLUTTER_TOUCH_BEGIN ||
994 event->type == CLUTTER_TOUCH_UPDATE ||
995 event->type == CLUTTER_TOUCH_END ||
996 event->type == CLUTTER_TOUCH_CANCEL)
997 return event->touch.sequence;
998 else if (event->type == CLUTTER_ENTER ||
999 event->type == CLUTTER_LEAVE)
1000 return event->crossing.sequence;
1001
1002 return NULL;
1003 }
1004
1005 /**
1006 * clutter_event_get_device_type:
1007 * @event: a #ClutterEvent
1008 *
1009 * Retrieves the type of the device for @event
1010 *
1011 * Return value: the #ClutterInputDeviceType for the device, if
1012 * any is set
1013 *
1014 * Since: 1.0
1015 */
1016 ClutterInputDeviceType
clutter_event_get_device_type(const ClutterEvent * event)1017 clutter_event_get_device_type (const ClutterEvent *event)
1018 {
1019 ClutterInputDevice *device = NULL;
1020
1021 g_return_val_if_fail (event != NULL, CLUTTER_POINTER_DEVICE);
1022
1023 device = clutter_event_get_device (event);
1024 if (device != NULL)
1025 return clutter_input_device_get_device_type (device);
1026
1027 return CLUTTER_POINTER_DEVICE;
1028 }
1029
1030 /**
1031 * clutter_event_set_device:
1032 * @event: a #ClutterEvent
1033 * @device: (allow-none): a #ClutterInputDevice, or %NULL
1034 *
1035 * Sets the device for @event.
1036 *
1037 * Since: 1.6
1038 */
1039 void
clutter_event_set_device(ClutterEvent * event,ClutterInputDevice * device)1040 clutter_event_set_device (ClutterEvent *event,
1041 ClutterInputDevice *device)
1042 {
1043 ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
1044
1045 g_return_if_fail (event != NULL);
1046 g_return_if_fail (device == NULL || CLUTTER_IS_INPUT_DEVICE (device));
1047
1048 g_set_object (&real_event->device, device);
1049
1050 switch (event->type)
1051 {
1052 case CLUTTER_NOTHING:
1053 case CLUTTER_EVENT_LAST:
1054 case CLUTTER_IM_COMMIT:
1055 case CLUTTER_IM_DELETE:
1056 case CLUTTER_IM_PREEDIT:
1057 break;
1058
1059 case CLUTTER_ENTER:
1060 case CLUTTER_LEAVE:
1061 event->crossing.device = device;
1062 break;
1063
1064 case CLUTTER_BUTTON_PRESS:
1065 case CLUTTER_BUTTON_RELEASE:
1066 event->button.device = device;
1067 break;
1068
1069 case CLUTTER_MOTION:
1070 event->motion.device = device;
1071 break;
1072
1073 case CLUTTER_SCROLL:
1074 event->scroll.device = device;
1075 break;
1076
1077 case CLUTTER_TOUCH_BEGIN:
1078 case CLUTTER_TOUCH_UPDATE:
1079 case CLUTTER_TOUCH_END:
1080 case CLUTTER_TOUCH_CANCEL:
1081 event->touch.device = device;
1082 break;
1083
1084 case CLUTTER_KEY_PRESS:
1085 case CLUTTER_KEY_RELEASE:
1086 event->key.device = device;
1087 break;
1088
1089 case CLUTTER_TOUCHPAD_PINCH:
1090 case CLUTTER_TOUCHPAD_SWIPE:
1091 /* Rely on priv data for these */
1092 break;
1093
1094 case CLUTTER_PROXIMITY_IN:
1095 case CLUTTER_PROXIMITY_OUT:
1096 event->proximity.device = device;
1097 break;
1098
1099 case CLUTTER_PAD_BUTTON_PRESS:
1100 case CLUTTER_PAD_BUTTON_RELEASE:
1101 event->pad_button.device = device;
1102 break;
1103
1104 case CLUTTER_PAD_STRIP:
1105 event->pad_strip.device = device;
1106 break;
1107
1108 case CLUTTER_PAD_RING:
1109 event->pad_ring.device = device;
1110 break;
1111
1112 case CLUTTER_DEVICE_ADDED:
1113 case CLUTTER_DEVICE_REMOVED:
1114 event->device.device = device;
1115 break;
1116 }
1117 }
1118
1119 /**
1120 * clutter_event_get_device:
1121 * @event: a #ClutterEvent
1122 *
1123 * Retrieves the #ClutterInputDevice for the event.
1124 * If you want the physical device the event originated from, use
1125 * clutter_event_get_source_device().
1126 *
1127 * The #ClutterInputDevice structure is completely opaque and should
1128 * be cast to the platform-specific implementation.
1129 *
1130 * Return value: (transfer none): the #ClutterInputDevice or %NULL. The
1131 * returned device is owned by the #ClutterEvent and it should not
1132 * be unreferenced
1133 *
1134 * Since: 1.0
1135 */
1136 ClutterInputDevice *
clutter_event_get_device(const ClutterEvent * event)1137 clutter_event_get_device (const ClutterEvent *event)
1138 {
1139 ClutterInputDevice *device = NULL;
1140 ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
1141
1142 g_return_val_if_fail (event != NULL, NULL);
1143
1144 if (real_event->device != NULL)
1145 return real_event->device;
1146
1147 switch (event->type)
1148 {
1149 case CLUTTER_NOTHING:
1150 case CLUTTER_IM_COMMIT:
1151 case CLUTTER_IM_DELETE:
1152 case CLUTTER_IM_PREEDIT:
1153 case CLUTTER_EVENT_LAST:
1154 break;
1155
1156 case CLUTTER_ENTER:
1157 case CLUTTER_LEAVE:
1158 device = event->crossing.device;
1159 break;
1160
1161 case CLUTTER_BUTTON_PRESS:
1162 case CLUTTER_BUTTON_RELEASE:
1163 device = event->button.device;
1164 break;
1165
1166 case CLUTTER_MOTION:
1167 device = event->motion.device;
1168 break;
1169
1170 case CLUTTER_SCROLL:
1171 device = event->scroll.device;
1172 break;
1173
1174 case CLUTTER_TOUCH_BEGIN:
1175 case CLUTTER_TOUCH_UPDATE:
1176 case CLUTTER_TOUCH_END:
1177 case CLUTTER_TOUCH_CANCEL:
1178 device = event->touch.device;
1179 break;
1180
1181 case CLUTTER_KEY_PRESS:
1182 case CLUTTER_KEY_RELEASE:
1183 device = event->key.device;
1184 break;
1185
1186 case CLUTTER_TOUCHPAD_PINCH:
1187 case CLUTTER_TOUCHPAD_SWIPE:
1188 /* Rely on priv data for these */
1189 break;
1190
1191 case CLUTTER_PROXIMITY_IN:
1192 case CLUTTER_PROXIMITY_OUT:
1193 device = event->proximity.device;
1194 break;
1195
1196 case CLUTTER_PAD_BUTTON_PRESS:
1197 case CLUTTER_PAD_BUTTON_RELEASE:
1198 device = event->pad_button.device;
1199 break;
1200
1201 case CLUTTER_PAD_STRIP:
1202 device = event->pad_strip.device;
1203 break;
1204
1205 case CLUTTER_PAD_RING:
1206 device = event->pad_ring.device;
1207 break;
1208
1209 case CLUTTER_DEVICE_ADDED:
1210 case CLUTTER_DEVICE_REMOVED:
1211 device = event->device.device;
1212 break;
1213 }
1214
1215 return device;
1216 }
1217
1218 /**
1219 * clutter_event_set_device_tool:
1220 * @event: a #ClutterEvent
1221 * @tool: (nullable): a #ClutterInputDeviceTool
1222 *
1223 * Sets the tool in use for this event
1224 *
1225 * Since: 1.28
1226 **/
1227 void
clutter_event_set_device_tool(ClutterEvent * event,ClutterInputDeviceTool * tool)1228 clutter_event_set_device_tool (ClutterEvent *event,
1229 ClutterInputDeviceTool *tool)
1230 {
1231 ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
1232
1233 g_return_if_fail (event != NULL);
1234
1235 real_event->tool = tool;
1236 }
1237
1238 /**
1239 * clutter_event_get_device_tool:
1240 * @event: a #ClutterEvent
1241 *
1242 * Returns the device tool that originated this event
1243 *
1244 * Returns: (transfer none): The tool of this event
1245 *
1246 * Since: 1.28
1247 **/
1248 ClutterInputDeviceTool *
clutter_event_get_device_tool(const ClutterEvent * event)1249 clutter_event_get_device_tool (const ClutterEvent *event)
1250 {
1251 ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
1252
1253 g_return_val_if_fail (event != NULL, NULL);
1254
1255 return real_event->tool;
1256 }
1257
1258 /**
1259 * clutter_event_new:
1260 * @type: The type of event.
1261 *
1262 * Creates a new #ClutterEvent of the specified type.
1263 *
1264 * Return value: (transfer full): A newly allocated #ClutterEvent.
1265 */
1266 ClutterEvent *
clutter_event_new(ClutterEventType type)1267 clutter_event_new (ClutterEventType type)
1268 {
1269 ClutterEvent *new_event;
1270 ClutterEventPrivate *priv;
1271
1272 priv = g_new0 (ClutterEventPrivate, 1);
1273
1274 new_event = (ClutterEvent *) priv;
1275 new_event->type = new_event->any.type = type;
1276
1277 return new_event;
1278 }
1279
1280 /**
1281 * clutter_event_copy:
1282 * @event: A #ClutterEvent.
1283 *
1284 * Copies @event.
1285 *
1286 * Return value: (transfer full): A newly allocated #ClutterEvent
1287 */
1288 ClutterEvent *
clutter_event_copy(const ClutterEvent * event)1289 clutter_event_copy (const ClutterEvent *event)
1290 {
1291 ClutterEvent *new_event;
1292 ClutterEventPrivate *new_real_event;
1293 ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
1294
1295 g_return_val_if_fail (event != NULL, NULL);
1296
1297 new_event = clutter_event_new (CLUTTER_NOTHING);
1298 new_real_event = (ClutterEventPrivate *) new_event;
1299
1300 *new_event = *event;
1301
1302 g_set_object (&new_real_event->device, real_event->device);
1303 g_set_object (&new_real_event->source_device, real_event->source_device);
1304 new_real_event->delta_x = real_event->delta_x;
1305 new_real_event->delta_y = real_event->delta_y;
1306 new_real_event->is_pointer_emulated = real_event->is_pointer_emulated;
1307 new_real_event->base_state = real_event->base_state;
1308 new_real_event->button_state = real_event->button_state;
1309 new_real_event->latched_state = real_event->latched_state;
1310 new_real_event->locked_state = real_event->locked_state;
1311 new_real_event->tool = real_event->tool;
1312
1313 switch (event->type)
1314 {
1315 case CLUTTER_BUTTON_PRESS:
1316 case CLUTTER_BUTTON_RELEASE:
1317 if (event->button.axes != NULL)
1318 {
1319 new_event->button.axes =
1320 g_memdup2 (event->button.axes,
1321 sizeof (double) * CLUTTER_INPUT_AXIS_LAST);
1322 }
1323 break;
1324
1325 case CLUTTER_SCROLL:
1326 if (event->scroll.axes != NULL)
1327 {
1328 new_event->scroll.axes =
1329 g_memdup2 (event->scroll.axes,
1330 sizeof (double) * CLUTTER_INPUT_AXIS_LAST);
1331 }
1332 break;
1333
1334 case CLUTTER_MOTION:
1335 if (event->motion.axes != NULL)
1336 {
1337 new_event->motion.axes =
1338 g_memdup2 (event->motion.axes,
1339 sizeof (double) * CLUTTER_INPUT_AXIS_LAST);
1340 }
1341 break;
1342
1343 case CLUTTER_TOUCH_BEGIN:
1344 case CLUTTER_TOUCH_UPDATE:
1345 case CLUTTER_TOUCH_END:
1346 case CLUTTER_TOUCH_CANCEL:
1347 if (event->touch.axes != NULL)
1348 {
1349 new_event->touch.axes =
1350 g_memdup2 (event->touch.axes,
1351 sizeof (double) * CLUTTER_INPUT_AXIS_LAST);
1352 }
1353 break;
1354
1355 case CLUTTER_DEVICE_ADDED:
1356 case CLUTTER_DEVICE_REMOVED:
1357 new_event->device.device = event->device.device;
1358 break;
1359 case CLUTTER_IM_COMMIT:
1360 case CLUTTER_IM_PREEDIT:
1361 new_event->im.text = g_strdup (event->im.text);
1362 break;
1363
1364 default:
1365 break;
1366 }
1367
1368 return new_event;
1369 }
1370
1371 /**
1372 * clutter_event_free:
1373 * @event: A #ClutterEvent.
1374 *
1375 * Frees all resources used by @event.
1376 */
1377 void
clutter_event_free(ClutterEvent * event)1378 clutter_event_free (ClutterEvent *event)
1379 {
1380 if (G_LIKELY (event != NULL))
1381 {
1382 ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
1383
1384 g_clear_object (&real_event->device);
1385 g_clear_object (&real_event->source_device);
1386
1387 switch (event->type)
1388 {
1389 case CLUTTER_BUTTON_PRESS:
1390 case CLUTTER_BUTTON_RELEASE:
1391 g_free (event->button.axes);
1392 break;
1393
1394 case CLUTTER_MOTION:
1395 g_free (event->motion.axes);
1396 break;
1397
1398 case CLUTTER_SCROLL:
1399 g_free (event->scroll.axes);
1400 break;
1401
1402 case CLUTTER_TOUCH_BEGIN:
1403 case CLUTTER_TOUCH_UPDATE:
1404 case CLUTTER_TOUCH_END:
1405 case CLUTTER_TOUCH_CANCEL:
1406 g_free (event->touch.axes);
1407 break;
1408
1409 case CLUTTER_IM_COMMIT:
1410 case CLUTTER_IM_PREEDIT:
1411 g_free (event->im.text);
1412 break;
1413
1414 default:
1415 break;
1416 }
1417
1418 g_free ((ClutterEventPrivate *) event);
1419 }
1420 }
1421
1422 /**
1423 * clutter_event_get:
1424 *
1425 * Pops an event off the event queue. Applications should not need to call
1426 * this.
1427 *
1428 * Return value: A #ClutterEvent or NULL if queue empty
1429 *
1430 * Since: 0.4
1431 */
1432 ClutterEvent *
clutter_event_get(void)1433 clutter_event_get (void)
1434 {
1435 ClutterMainContext *context = _clutter_context_get_default ();
1436 ClutterEvent *event;
1437
1438 event = g_async_queue_try_pop (context->events_queue);
1439
1440 return event;
1441 }
1442
1443 void
_clutter_event_push(const ClutterEvent * event,gboolean do_copy)1444 _clutter_event_push (const ClutterEvent *event,
1445 gboolean do_copy)
1446 {
1447 ClutterMainContext *context = _clutter_context_get_default ();
1448
1449 g_assert (context != NULL);
1450
1451 if (do_copy)
1452 {
1453 ClutterEvent *copy;
1454
1455 copy = clutter_event_copy (event);
1456 event = copy;
1457 }
1458
1459 g_async_queue_push (context->events_queue, (gpointer) event);
1460 g_main_context_wakeup (NULL);
1461 }
1462
1463 /**
1464 * clutter_event_put:
1465 * @event: a #ClutterEvent
1466 *
1467 * Puts a copy of the event on the back of the event queue. The event will
1468 * have the %CLUTTER_EVENT_FLAG_SYNTHETIC flag set. If the source is set
1469 * event signals will be emitted for this source and capture/bubbling for
1470 * its ancestors. If the source is not set it will be generated by picking
1471 * or use the actor that currently has keyboard focus
1472 *
1473 * Since: 0.6
1474 */
1475 void
clutter_event_put(const ClutterEvent * event)1476 clutter_event_put (const ClutterEvent *event)
1477 {
1478 _clutter_event_push (event, TRUE);
1479 }
1480
1481 /**
1482 * clutter_events_pending:
1483 *
1484 * Checks if events are pending in the event queue.
1485 *
1486 * Return value: TRUE if there are pending events, FALSE otherwise.
1487 *
1488 * Since: 0.4
1489 */
1490 gboolean
clutter_events_pending(void)1491 clutter_events_pending (void)
1492 {
1493 ClutterMainContext *context = _clutter_context_get_default ();
1494
1495 g_return_val_if_fail (context != NULL, FALSE);
1496
1497 return g_async_queue_length (context->events_queue) > 0;
1498 }
1499
1500 /**
1501 * clutter_get_current_event_time:
1502 *
1503 * Retrieves the timestamp of the last event, if there is an
1504 * event or if the event has a timestamp.
1505 *
1506 * Return value: the event timestamp, or %CLUTTER_CURRENT_TIME
1507 *
1508 * Since: 1.0
1509 */
1510 guint32
clutter_get_current_event_time(void)1511 clutter_get_current_event_time (void)
1512 {
1513 const ClutterEvent* event;
1514
1515 event = clutter_get_current_event ();
1516
1517 if (event != NULL)
1518 return clutter_event_get_time (event);
1519
1520 return CLUTTER_CURRENT_TIME;
1521 }
1522
1523 /**
1524 * clutter_get_current_event:
1525 *
1526 * If an event is currently being processed, return that event.
1527 * This function is intended to be used to access event state
1528 * that might not be exposed by higher-level widgets. For
1529 * example, to get the key modifier state from a Button 'clicked'
1530 * event.
1531 *
1532 * Return value: (transfer none): The current ClutterEvent, or %NULL if none
1533 *
1534 * Since: 1.2
1535 */
1536 const ClutterEvent *
clutter_get_current_event(void)1537 clutter_get_current_event (void)
1538 {
1539 ClutterMainContext *context = _clutter_context_get_default ();
1540
1541 g_return_val_if_fail (context != NULL, NULL);
1542
1543 return context->current_event != NULL ? context->current_event->data : NULL;
1544 }
1545
1546 /**
1547 * clutter_event_get_source_device:
1548 * @event: a #ClutterEvent
1549 *
1550 * Retrieves the hardware device that originated the event.
1551 *
1552 * If you need the virtual device, use clutter_event_get_device().
1553 *
1554 * If no hardware device originated this event, this function will
1555 * return the same device as clutter_event_get_device().
1556 *
1557 * Return value: (transfer none): a pointer to a #ClutterInputDevice
1558 * or %NULL
1559 *
1560 * Since: 1.6
1561 */
1562 ClutterInputDevice *
clutter_event_get_source_device(const ClutterEvent * event)1563 clutter_event_get_source_device (const ClutterEvent *event)
1564 {
1565 ClutterEventPrivate *real_event;
1566
1567 real_event = (ClutterEventPrivate *) event;
1568
1569 if (real_event->source_device != NULL)
1570 return real_event->source_device;
1571
1572 return clutter_event_get_device (event);
1573 }
1574
1575 /**
1576 * clutter_event_set_source_device:
1577 * @event: a #ClutterEvent
1578 * @device: (allow-none): a #ClutterInputDevice
1579 *
1580 * Sets the source #ClutterInputDevice for @event.
1581 *
1582 * The #ClutterEvent must have been created using clutter_event_new().
1583 *
1584 * Since: 1.8
1585 */
1586 void
clutter_event_set_source_device(ClutterEvent * event,ClutterInputDevice * device)1587 clutter_event_set_source_device (ClutterEvent *event,
1588 ClutterInputDevice *device)
1589 {
1590 ClutterEventPrivate *real_event;
1591
1592 g_return_if_fail (event != NULL);
1593 g_return_if_fail (device == NULL || CLUTTER_IS_INPUT_DEVICE (device));
1594
1595 real_event = (ClutterEventPrivate *) event;
1596 g_set_object (&real_event->source_device, device);
1597 }
1598
1599 /**
1600 * clutter_event_get_axes:
1601 * @event: a #ClutterEvent
1602 * @n_axes: (out): return location for the number of axes returned
1603 *
1604 * Retrieves the array of axes values attached to the event.
1605 *
1606 * Return value: (transfer none): an array of axis values
1607 *
1608 * Since: 1.6
1609 */
1610 gdouble *
clutter_event_get_axes(const ClutterEvent * event,guint * n_axes)1611 clutter_event_get_axes (const ClutterEvent *event,
1612 guint *n_axes)
1613 {
1614 gdouble *retval = NULL;
1615
1616 switch (event->type)
1617 {
1618 case CLUTTER_NOTHING:
1619 case CLUTTER_ENTER:
1620 case CLUTTER_LEAVE:
1621 case CLUTTER_KEY_PRESS:
1622 case CLUTTER_KEY_RELEASE:
1623 case CLUTTER_EVENT_LAST:
1624 case CLUTTER_PROXIMITY_IN:
1625 case CLUTTER_PROXIMITY_OUT:
1626 case CLUTTER_DEVICE_ADDED:
1627 case CLUTTER_DEVICE_REMOVED:
1628 break;
1629
1630 case CLUTTER_SCROLL:
1631 retval = event->scroll.axes;
1632 break;
1633
1634 case CLUTTER_BUTTON_PRESS:
1635 case CLUTTER_BUTTON_RELEASE:
1636 retval = event->button.axes;
1637 break;
1638
1639 case CLUTTER_TOUCH_BEGIN:
1640 case CLUTTER_TOUCH_UPDATE:
1641 case CLUTTER_TOUCH_END:
1642 case CLUTTER_TOUCH_CANCEL:
1643 retval = event->touch.axes;
1644 break;
1645
1646 case CLUTTER_MOTION:
1647 retval = event->motion.axes;
1648 break;
1649
1650 case CLUTTER_TOUCHPAD_PINCH:
1651 case CLUTTER_TOUCHPAD_SWIPE:
1652 case CLUTTER_PAD_BUTTON_PRESS:
1653 case CLUTTER_PAD_BUTTON_RELEASE:
1654 case CLUTTER_PAD_STRIP:
1655 case CLUTTER_PAD_RING:
1656 case CLUTTER_IM_COMMIT:
1657 case CLUTTER_IM_DELETE:
1658 case CLUTTER_IM_PREEDIT:
1659 break;
1660 }
1661
1662 if (n_axes)
1663 *n_axes = CLUTTER_INPUT_AXIS_LAST;
1664
1665 return retval;
1666 }
1667
1668 /**
1669 * clutter_event_get_distance:
1670 * @source: a #ClutterEvent
1671 * @target: a #ClutterEvent
1672 *
1673 * Retrieves the distance between two events, a @source and a @target.
1674 *
1675 * Return value: the distance between two #ClutterEvent
1676 *
1677 * Since: 1.12
1678 */
1679 float
clutter_event_get_distance(const ClutterEvent * source,const ClutterEvent * target)1680 clutter_event_get_distance (const ClutterEvent *source,
1681 const ClutterEvent *target)
1682 {
1683 graphene_point_t p0, p1;
1684
1685 clutter_event_get_position (source, &p0);
1686 clutter_event_get_position (source, &p1);
1687
1688 return graphene_point_distance (&p0, &p1, NULL, NULL);
1689 }
1690
1691 /**
1692 * clutter_event_get_angle:
1693 * @source: a #ClutterEvent
1694 * @target: a #ClutterEvent
1695 *
1696 * Retrieves the angle relative from @source to @target.
1697 *
1698 * The direction of the angle is from the position X axis towards
1699 * the positive Y axis.
1700 *
1701 * Return value: the angle between two #ClutterEvent
1702 *
1703 * Since: 1.12
1704 */
1705 double
clutter_event_get_angle(const ClutterEvent * source,const ClutterEvent * target)1706 clutter_event_get_angle (const ClutterEvent *source,
1707 const ClutterEvent *target)
1708 {
1709 graphene_point_t p0, p1;
1710 float x_distance, y_distance;
1711 double angle;
1712
1713 clutter_event_get_position (source, &p0);
1714 clutter_event_get_position (target, &p1);
1715
1716 if (graphene_point_equal (&p0, &p1))
1717 return 0;
1718
1719 graphene_point_distance (&p0, &p1, &x_distance, &y_distance);
1720
1721 angle = atan2 (x_distance, y_distance);
1722
1723 /* invert the angle, and shift it by 90 degrees */
1724 angle = (2.0 * G_PI) - angle;
1725 angle += G_PI / 2.0;
1726
1727 /* keep the angle within the [ 0, 360 ] interval */
1728 angle = fmod (angle, 2.0 * G_PI);
1729
1730 return angle;
1731 }
1732
1733 /**
1734 * clutter_event_has_shift_modifier:
1735 * @event: a #ClutterEvent
1736 *
1737 * Checks whether @event has the Shift modifier mask set.
1738 *
1739 * Return value: %TRUE if the event has the Shift modifier mask set
1740 *
1741 * Since: 1.12
1742 */
1743 gboolean
clutter_event_has_shift_modifier(const ClutterEvent * event)1744 clutter_event_has_shift_modifier (const ClutterEvent *event)
1745 {
1746 return (clutter_event_get_state (event) & CLUTTER_SHIFT_MASK) != FALSE;
1747 }
1748
1749 /**
1750 * clutter_event_has_control_modifier:
1751 * @event: a #ClutterEvent
1752 *
1753 * Checks whether @event has the Control modifier mask set.
1754 *
1755 * Return value: %TRUE if the event has the Control modifier mask set
1756 *
1757 * Since: 1.12
1758 */
1759 gboolean
clutter_event_has_control_modifier(const ClutterEvent * event)1760 clutter_event_has_control_modifier (const ClutterEvent *event)
1761 {
1762 return (clutter_event_get_state (event) & CLUTTER_CONTROL_MASK) != FALSE;
1763 }
1764
1765 /**
1766 * clutter_event_is_pointer_emulated:
1767 * @event: a #ClutterEvent
1768 *
1769 * Checks whether a pointer @event has been generated by the windowing
1770 * system. The returned value can be used to distinguish between events
1771 * synthesized by the windowing system itself (as opposed by Clutter).
1772 *
1773 * Return value: %TRUE if the event is pointer emulated
1774 *
1775 * Since: 1.12
1776 */
1777 gboolean
clutter_event_is_pointer_emulated(const ClutterEvent * event)1778 clutter_event_is_pointer_emulated (const ClutterEvent *event)
1779 {
1780 g_return_val_if_fail (event != NULL, FALSE);
1781
1782 return ((ClutterEventPrivate *) event)->is_pointer_emulated;
1783 }
1784
1785 gboolean
_clutter_event_process_filters(ClutterEvent * event)1786 _clutter_event_process_filters (ClutterEvent *event)
1787 {
1788 ClutterMainContext *context = _clutter_context_get_default ();
1789 GList *l, *next;
1790
1791 /* Event filters are handled in order from least recently added to
1792 * most recently added */
1793
1794 for (l = context->event_filters; l; l = next)
1795 {
1796 ClutterEventFilter *event_filter = l->data;
1797
1798 next = l->next;
1799
1800 if (event_filter->stage && event_filter->stage != event->any.stage)
1801 continue;
1802
1803 if (event_filter->func (event, event_filter->user_data) == CLUTTER_EVENT_STOP)
1804 return CLUTTER_EVENT_STOP;
1805 }
1806
1807 return CLUTTER_EVENT_PROPAGATE;
1808 }
1809
1810 /**
1811 * clutter_event_add_filter:
1812 * @stage: (allow-none): The #ClutterStage to capture events for
1813 * @func: The callback function which will be passed all events.
1814 * @notify: A #GDestroyNotify
1815 * @user_data: A data pointer to pass to the function.
1816 *
1817 * Adds a function which will be called for all events that Clutter
1818 * processes. The function will be called before any signals are
1819 * emitted for the event and it will take precedence over any grabs.
1820 *
1821 * Return value: an identifier for the event filter, to be used
1822 * with clutter_event_remove_filter().
1823 *
1824 * Since: 1.18
1825 */
1826 guint
clutter_event_add_filter(ClutterStage * stage,ClutterEventFilterFunc func,GDestroyNotify notify,gpointer user_data)1827 clutter_event_add_filter (ClutterStage *stage,
1828 ClutterEventFilterFunc func,
1829 GDestroyNotify notify,
1830 gpointer user_data)
1831 {
1832 ClutterMainContext *context = _clutter_context_get_default ();
1833 ClutterEventFilter *event_filter = g_new0 (ClutterEventFilter, 1);
1834 static guint event_filter_id = 0;
1835
1836 event_filter->stage = stage;
1837 event_filter->id = ++event_filter_id;
1838 event_filter->func = func;
1839 event_filter->notify = notify;
1840 event_filter->user_data = user_data;
1841
1842 /* The event filters are kept in order from least recently added to
1843 * most recently added so we must add it to the end */
1844 context->event_filters = g_list_append (context->event_filters, event_filter);
1845
1846 return event_filter->id;
1847 }
1848
1849 /**
1850 * clutter_event_remove_filter:
1851 * @id: The ID of the event filter, as returned from clutter_event_add_filter()
1852 *
1853 * Removes an event filter that was previously added with
1854 * clutter_event_add_filter().
1855 *
1856 * Since: 1.18
1857 */
1858 void
clutter_event_remove_filter(guint id)1859 clutter_event_remove_filter (guint id)
1860 {
1861 ClutterMainContext *context = _clutter_context_get_default ();
1862 GList *l;
1863
1864 for (l = context->event_filters; l; l = l->next)
1865 {
1866 ClutterEventFilter *event_filter = l->data;
1867
1868 if (event_filter->id == id)
1869 {
1870 if (event_filter->notify)
1871 event_filter->notify (event_filter->user_data);
1872
1873 context->event_filters = g_list_delete_link (context->event_filters, l);
1874 g_free (event_filter);
1875 return;
1876 }
1877 }
1878
1879 g_warning ("No event filter found for id: %d\n", id);
1880 }
1881
1882 /**
1883 * clutter_event_get_touchpad_gesture_finger_count:
1884 * @event: a touchpad swipe/pinch event
1885 *
1886 * Returns the number of fingers that is triggering the touchpad gesture.
1887 *
1888 * Returns: the number of fingers in the gesture.
1889 *
1890 * Since: 1.24
1891 **/
1892 guint
clutter_event_get_touchpad_gesture_finger_count(const ClutterEvent * event)1893 clutter_event_get_touchpad_gesture_finger_count (const ClutterEvent *event)
1894 {
1895 g_return_val_if_fail (event != NULL, 0);
1896 g_return_val_if_fail (event->type == CLUTTER_TOUCHPAD_SWIPE ||
1897 event->type == CLUTTER_TOUCHPAD_PINCH, 0);
1898
1899 if (event->type == CLUTTER_TOUCHPAD_SWIPE)
1900 return event->touchpad_swipe.n_fingers;
1901 else if (event->type == CLUTTER_TOUCHPAD_PINCH)
1902 return event->touchpad_pinch.n_fingers;
1903
1904 return 0;
1905 }
1906
1907 /**
1908 * clutter_event_get_gesture_pinch_angle_delta:
1909 * @event: a touchpad pinch event
1910 *
1911 * Returns the angle delta reported by this specific event.
1912 *
1913 * Returns: The angle delta relative to the previous event.
1914 *
1915 * Since: 1.24
1916 **/
1917 gdouble
clutter_event_get_gesture_pinch_angle_delta(const ClutterEvent * event)1918 clutter_event_get_gesture_pinch_angle_delta (const ClutterEvent *event)
1919 {
1920 g_return_val_if_fail (event != NULL, 0);
1921 g_return_val_if_fail (event->type == CLUTTER_TOUCHPAD_PINCH, 0);
1922
1923 return event->touchpad_pinch.angle_delta;
1924 }
1925
1926 /**
1927 * clutter_event_get_gesture_pinch_scale:
1928 * @event: a touchpad pinch event
1929 *
1930 * Returns the current scale as reported by @event, 1.0 being the original
1931 * distance at the time the corresponding event with phase
1932 * %CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN is received.
1933 * is received.
1934 *
1935 * Returns: the current pinch gesture scale
1936 *
1937 * Since: 1.24
1938 **/
1939 gdouble
clutter_event_get_gesture_pinch_scale(const ClutterEvent * event)1940 clutter_event_get_gesture_pinch_scale (const ClutterEvent *event)
1941 {
1942 g_return_val_if_fail (event != NULL, 0);
1943 g_return_val_if_fail (event->type == CLUTTER_TOUCHPAD_PINCH, 0);
1944
1945 return event->touchpad_pinch.scale;
1946 }
1947
1948 /**
1949 * clutter_event_get_gesture_phase:
1950 * @event: a touchpad gesture event
1951 *
1952 * Returns the phase of the event, See #ClutterTouchpadGesturePhase.
1953 *
1954 * Returns: the phase of the gesture event.
1955 **/
1956 ClutterTouchpadGesturePhase
clutter_event_get_gesture_phase(const ClutterEvent * event)1957 clutter_event_get_gesture_phase (const ClutterEvent *event)
1958 {
1959 g_return_val_if_fail (event != NULL, 0);
1960 g_return_val_if_fail (event->type == CLUTTER_TOUCHPAD_PINCH ||
1961 event->type == CLUTTER_TOUCHPAD_SWIPE, 0);
1962
1963 if (event->type == CLUTTER_TOUCHPAD_PINCH)
1964 return event->touchpad_pinch.phase;
1965 else if (event->type == CLUTTER_TOUCHPAD_SWIPE)
1966 return event->touchpad_swipe.phase;
1967
1968 /* Shouldn't ever happen */
1969 return CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN;
1970 };
1971
1972 /**
1973 * clutter_event_get_gesture_motion_delta:
1974 * @event: A clutter touchpad gesture event
1975 * @dx: (out) (allow-none): the displacement relative to the pointer
1976 * position in the X axis, or %NULL
1977 * @dy: (out) (allow-none): the displacement relative to the pointer
1978 * position in the Y axis, or %NULL
1979 *
1980 * Returns the gesture motion deltas relative to the current pointer
1981 * position.
1982 *
1983 * Since: 1.24
1984 **/
1985 void
clutter_event_get_gesture_motion_delta(const ClutterEvent * event,gdouble * dx,gdouble * dy)1986 clutter_event_get_gesture_motion_delta (const ClutterEvent *event,
1987 gdouble *dx,
1988 gdouble *dy)
1989 {
1990 g_return_if_fail (event != NULL);
1991 g_return_if_fail (event->type == CLUTTER_TOUCHPAD_PINCH ||
1992 event->type == CLUTTER_TOUCHPAD_SWIPE);
1993
1994 if (event->type == CLUTTER_TOUCHPAD_PINCH)
1995 {
1996 if (dx)
1997 *dx = event->touchpad_pinch.dx;
1998 if (dy)
1999 *dy = event->touchpad_pinch.dy;
2000 }
2001 else if (event->type == CLUTTER_TOUCHPAD_SWIPE)
2002 {
2003 if (dx)
2004 *dx = event->touchpad_swipe.dx;
2005 if (dy)
2006 *dy = event->touchpad_swipe.dy;
2007 }
2008 }
2009
2010 /**
2011 * clutter_event_get_gesture_motion_delta_unaccelerated:
2012 * @event: A clutter touchpad gesture event
2013 * @dx: (out) (allow-none): the displacement relative to the pointer
2014 * position in the X axis, or %NULL
2015 * @dy: (out) (allow-none): the displacement relative to the pointer
2016 * position in the Y axis, or %NULL
2017 *
2018 * Returns the unaccelerated gesture motion deltas relative to the current
2019 * pointer position. Unlike clutter_event_get_gesture_motion_delta(),
2020 * pointer acceleration is ignored.
2021 **/
2022 void
clutter_event_get_gesture_motion_delta_unaccelerated(const ClutterEvent * event,gdouble * dx,gdouble * dy)2023 clutter_event_get_gesture_motion_delta_unaccelerated (const ClutterEvent *event,
2024 gdouble *dx,
2025 gdouble *dy)
2026 {
2027 g_return_if_fail (event != NULL);
2028 g_return_if_fail (event->type == CLUTTER_TOUCHPAD_PINCH ||
2029 event->type == CLUTTER_TOUCHPAD_SWIPE);
2030
2031 if (event->type == CLUTTER_TOUCHPAD_PINCH)
2032 {
2033 if (dx)
2034 *dx = event->touchpad_pinch.dx_unaccel;
2035 if (dy)
2036 *dy = event->touchpad_pinch.dy_unaccel;
2037 }
2038 else if (event->type == CLUTTER_TOUCHPAD_SWIPE)
2039 {
2040 if (dx)
2041 *dx = event->touchpad_swipe.dx_unaccel;
2042 if (dy)
2043 *dy = event->touchpad_swipe.dy_unaccel;
2044 }
2045 }
2046 /**
2047 * clutter_event_get_scroll_source:
2048 * @event: an scroll event
2049 *
2050 * Returns the #ClutterScrollSource that applies to an scroll event.
2051 *
2052 * Returns: The source of scroll events
2053 *
2054 * Since: 1.26
2055 **/
2056 ClutterScrollSource
clutter_event_get_scroll_source(const ClutterEvent * event)2057 clutter_event_get_scroll_source (const ClutterEvent *event)
2058 {
2059 g_return_val_if_fail (event != NULL, CLUTTER_SCROLL_SOURCE_UNKNOWN);
2060 g_return_val_if_fail (event->type == CLUTTER_SCROLL,
2061 CLUTTER_SCROLL_SOURCE_UNKNOWN);
2062
2063 return event->scroll.scroll_source;
2064 }
2065
2066 /**
2067 * clutter_event_get_scroll_finish_flags:
2068 * @event: an scroll event
2069 *
2070 * Returns the #ClutterScrollFinishFlags of an scroll event. Those
2071 * can be used to determine whether post-scroll effects like kinetic
2072 * scrolling should be applied.
2073 *
2074 * Returns: The scroll finish flags
2075 *
2076 * Since: 1.26
2077 **/
2078 ClutterScrollFinishFlags
clutter_event_get_scroll_finish_flags(const ClutterEvent * event)2079 clutter_event_get_scroll_finish_flags (const ClutterEvent *event)
2080 {
2081 g_return_val_if_fail (event != NULL, CLUTTER_SCROLL_FINISHED_NONE);
2082 g_return_val_if_fail (event->type == CLUTTER_SCROLL,
2083 CLUTTER_SCROLL_FINISHED_NONE);
2084
2085 return event->scroll.finish_flags;
2086 }
2087
2088 guint
clutter_event_get_mode_group(const ClutterEvent * event)2089 clutter_event_get_mode_group (const ClutterEvent *event)
2090 {
2091 g_return_val_if_fail (event->type == CLUTTER_PAD_BUTTON_PRESS ||
2092 event->type == CLUTTER_PAD_BUTTON_RELEASE ||
2093 event->type == CLUTTER_PAD_RING ||
2094 event->type == CLUTTER_PAD_STRIP, 0);
2095 switch (event->type)
2096 {
2097 case CLUTTER_PAD_BUTTON_PRESS:
2098 case CLUTTER_PAD_BUTTON_RELEASE:
2099 return event->pad_button.group;
2100 case CLUTTER_PAD_RING:
2101 return event->pad_ring.group;
2102 case CLUTTER_PAD_STRIP:
2103 return event->pad_strip.group;
2104 default:
2105 return 0;
2106 }
2107 }
2108
2109 /**
2110 * clutter_event_get_pad_event_details:
2111 * @event: a pad event
2112 * @number: (out) (optional): ring/strip/button number
2113 * @mode: (out) (optional): pad mode as per the event
2114 * @value: (out) (optional): event axis value
2115 *
2116 * Returns the details of a pad event.
2117 *
2118 * Returns: #TRUE if event details could be obtained
2119 **/
2120 gboolean
clutter_event_get_pad_event_details(const ClutterEvent * event,guint * number,guint * mode,gdouble * value)2121 clutter_event_get_pad_event_details (const ClutterEvent *event,
2122 guint *number,
2123 guint *mode,
2124 gdouble *value)
2125 {
2126 guint n, m;
2127 gdouble v;
2128
2129 g_return_val_if_fail (event != NULL, FALSE);
2130 g_return_val_if_fail (event->type == CLUTTER_PAD_BUTTON_PRESS ||
2131 event->type == CLUTTER_PAD_BUTTON_RELEASE ||
2132 event->type == CLUTTER_PAD_RING ||
2133 event->type == CLUTTER_PAD_STRIP, FALSE);
2134
2135 switch (event->type)
2136 {
2137 case CLUTTER_PAD_BUTTON_PRESS:
2138 case CLUTTER_PAD_BUTTON_RELEASE:
2139 n = event->pad_button.button;
2140 m = event->pad_button.mode;
2141 v = 0.0;
2142 break;
2143 case CLUTTER_PAD_RING:
2144 n = event->pad_ring.ring_number;
2145 m = event->pad_ring.mode;
2146 v = event->pad_ring.angle;
2147 break;
2148 case CLUTTER_PAD_STRIP:
2149 n = event->pad_strip.strip_number;
2150 m = event->pad_strip.mode;
2151 v = event->pad_strip.value;
2152 break;
2153 default:
2154 return FALSE;
2155 }
2156
2157 if (number)
2158 *number = n;
2159 if (mode)
2160 *mode = m;
2161 if (value)
2162 *value = v;
2163
2164 return TRUE;
2165 }
2166
2167 uint32_t
clutter_event_get_event_code(const ClutterEvent * event)2168 clutter_event_get_event_code (const ClutterEvent *event)
2169 {
2170 if (event->type == CLUTTER_KEY_PRESS ||
2171 event->type == CLUTTER_KEY_RELEASE)
2172 return event->key.evdev_code;
2173 else if (event->type == CLUTTER_BUTTON_PRESS ||
2174 event->type == CLUTTER_BUTTON_RELEASE)
2175 return event->button.evdev_code;
2176
2177 return 0;
2178 }
2179
2180 int32_t
clutter_event_sequence_get_slot(const ClutterEventSequence * sequence)2181 clutter_event_sequence_get_slot (const ClutterEventSequence *sequence)
2182 {
2183 g_return_val_if_fail (sequence != NULL, -1);
2184
2185 return GPOINTER_TO_INT (sequence) - 1;
2186 }
2187
2188 int64_t
clutter_event_get_time_us(const ClutterEvent * event)2189 clutter_event_get_time_us (const ClutterEvent *event)
2190 {
2191 if (event->type == CLUTTER_MOTION)
2192 return event->motion.time_us;
2193
2194 return 0;
2195 }
2196
2197 gboolean
clutter_event_get_relative_motion(const ClutterEvent * event,double * dx,double * dy,double * dx_unaccel,double * dy_unaccel)2198 clutter_event_get_relative_motion (const ClutterEvent *event,
2199 double *dx,
2200 double *dy,
2201 double *dx_unaccel,
2202 double *dy_unaccel)
2203 {
2204 if (event->type == CLUTTER_MOTION &&
2205 event->motion.flags & CLUTTER_EVENT_FLAG_RELATIVE_MOTION)
2206 {
2207 if (dx)
2208 *dx = event->motion.dx;
2209 if (dy)
2210 *dy = event->motion.dy;
2211 if (dx_unaccel)
2212 *dx_unaccel = event->motion.dx_unaccel;
2213 if (dy_unaccel)
2214 *dy_unaccel = event->motion.dy_unaccel;
2215
2216 return TRUE;
2217 }
2218 else
2219 return FALSE;
2220 }
2221