update to 1.10.4
[profile/ivi/clutter.git] / clutter / clutter-event.c
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 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "clutter-backend-private.h"
31 #include "clutter-debug.h"
32 #include "clutter-event-private.h"
33 #include "clutter-keysyms.h"
34 #include "clutter-private.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   gpointer platform_data;
56
57   guint is_pointer_emulated : 1;
58 } ClutterEventPrivate;
59
60 static GHashTable *all_events = NULL;
61
62 G_DEFINE_BOXED_TYPE (ClutterEvent, clutter_event,
63                      clutter_event_copy,
64                      clutter_event_free);
65
66 static gboolean
67 is_event_allocated (const ClutterEvent *event)
68 {
69   if (all_events == NULL)
70     return FALSE;
71
72   return g_hash_table_lookup (all_events, event) != NULL;
73 }
74
75 /*
76  * _clutter_event_get_platform_data:
77  * @event: a #ClutterEvent
78  *
79  * Retrieves the pointer to platform-specific data inside an event
80  *
81  * Return value: a pointer to platform-specific data
82  *
83  * Since: 1.4
84  */
85 gpointer
86 _clutter_event_get_platform_data (const ClutterEvent *event)
87 {
88   if (!is_event_allocated (event))
89     return NULL;
90
91   return ((ClutterEventPrivate *) event)->platform_data;
92 }
93
94 /*< private >
95  * _clutter_event_set_platform_data:
96  * @event: a #ClutterEvent
97  * @data: a pointer to platform-specific data
98  *
99  * Sets the pointer to platform-specific data inside an event
100  *
101  * Since: 1.4
102  */
103 void
104 _clutter_event_set_platform_data (ClutterEvent *event,
105                                   gpointer      data)
106 {
107   if (!is_event_allocated (event))
108     return;
109
110   ((ClutterEventPrivate *) event)->platform_data = data;
111 }
112
113 void
114 _clutter_event_set_pointer_emulated (ClutterEvent *event,
115                                      gboolean      is_emulated)
116 {
117   if (!is_event_allocated (event))
118     return;
119
120   ((ClutterEventPrivate *) event)->is_pointer_emulated = !!is_emulated;
121 }
122
123 /**
124  * clutter_event_type:
125  * @event: a #ClutterEvent
126  *
127  * Retrieves the type of the event.
128  *
129  * Return value: a #ClutterEventType
130  */
131 ClutterEventType
132 clutter_event_type (const ClutterEvent *event)
133 {
134   g_return_val_if_fail (event != NULL, CLUTTER_NOTHING);
135
136   return event->type;
137 }
138
139 /**
140  * clutter_event_get_time:
141  * @event: a #ClutterEvent
142  *
143  * Retrieves the time of the event.
144  *
145  * Return value: the time of the event, or %CLUTTER_CURRENT_TIME
146  *
147  * Since: 0.4
148  */
149 guint32
150 clutter_event_get_time (const ClutterEvent *event)
151 {
152   g_return_val_if_fail (event != NULL, CLUTTER_CURRENT_TIME);
153
154   return event->any.time;
155 }
156
157 /**
158  * clutter_event_set_time:
159  * @event: a #ClutterEvent
160  * @time_: the time of the event
161  *
162  * Sets the time of the event.
163  *
164  * Since: 1.8
165  */
166 void
167 clutter_event_set_time (ClutterEvent *event,
168                         guint32       time_)
169 {
170   g_return_if_fail (event != NULL);
171
172   event->any.time = time_;
173 }
174
175 /**
176  * clutter_event_get_state:
177  * @event: a #ClutterEvent
178  *
179  * Retrieves the modifier state of the event.
180  *
181  * Return value: the modifier state parameter, or 0
182  *
183  * Since: 0.4
184  */
185 ClutterModifierType
186 clutter_event_get_state (const ClutterEvent *event)
187 {
188   g_return_val_if_fail (event != NULL, 0);
189
190   switch (event->type)
191     {
192     case CLUTTER_KEY_PRESS:
193     case CLUTTER_KEY_RELEASE:
194       return event->key.modifier_state;
195
196     case CLUTTER_BUTTON_PRESS:
197     case CLUTTER_BUTTON_RELEASE:
198       return event->button.modifier_state;
199
200     case CLUTTER_TOUCH_BEGIN:
201     case CLUTTER_TOUCH_UPDATE:
202     case CLUTTER_TOUCH_END:
203     case CLUTTER_TOUCH_CANCEL:
204       return event->touch.modifier_state;
205
206     case CLUTTER_MOTION:
207       return event->motion.modifier_state;
208
209     case CLUTTER_SCROLL:
210       return event->scroll.modifier_state;
211
212     default:
213       break;
214     }
215
216   return 0;
217 }
218
219 /**
220  * clutter_event_set_state:
221  * @event: a #ClutterEvent
222  * @state: the modifier state to set
223  *
224  * Sets the modifier state of the event.
225  *
226  * Since: 1.8
227  */
228 void
229 clutter_event_set_state (ClutterEvent        *event,
230                          ClutterModifierType  state)
231 {
232   g_return_if_fail (event != NULL);
233
234   switch (event->type)
235     {
236     case CLUTTER_KEY_PRESS:
237     case CLUTTER_KEY_RELEASE:
238       event->key.modifier_state = state;
239       break;
240
241     case CLUTTER_BUTTON_PRESS:
242     case CLUTTER_BUTTON_RELEASE:
243       event->button.modifier_state = state;
244       break;
245
246     case CLUTTER_MOTION:
247       event->motion.modifier_state = state;
248       break;
249
250     case CLUTTER_TOUCH_BEGIN:
251     case CLUTTER_TOUCH_UPDATE:
252     case CLUTTER_TOUCH_END:
253     case CLUTTER_TOUCH_CANCEL:
254       event->touch.modifier_state = state;
255       break;
256
257     case CLUTTER_SCROLL:
258       event->scroll.modifier_state = state;
259       break;
260
261     default:
262       break;
263     }
264 }
265
266 /**
267  * clutter_event_get_coords:
268  * @event: a #ClutterEvent
269  * @x: (out): return location for the X coordinate, or %NULL
270  * @y: (out): return location for the Y coordinate, or %NULL
271  *
272  * Retrieves the coordinates of @event and puts them into @x and @y.
273  *
274  * Since: 0.4
275  */
276 void
277 clutter_event_get_coords (const ClutterEvent *event,
278                           gfloat             *x,
279                           gfloat             *y)
280 {
281   gfloat event_x, event_y;
282
283   g_return_if_fail (event != NULL);
284
285   event_x = event_y = 0;
286
287   switch (event->type)
288     {
289     case CLUTTER_NOTHING:
290     case CLUTTER_KEY_PRESS:
291     case CLUTTER_KEY_RELEASE:
292     case CLUTTER_STAGE_STATE:
293     case CLUTTER_DESTROY_NOTIFY:
294     case CLUTTER_CLIENT_MESSAGE:
295     case CLUTTER_DELETE:
296     case CLUTTER_EVENT_LAST:
297       break;
298
299     case CLUTTER_ENTER:
300     case CLUTTER_LEAVE:
301       event_x = event->crossing.x;
302       event_y = event->crossing.y;
303       break;
304
305     case CLUTTER_BUTTON_PRESS:
306     case CLUTTER_BUTTON_RELEASE:
307       event_x = event->button.x;
308       event_y = event->button.y;
309       break;
310
311     case CLUTTER_MOTION:
312       event_x = event->motion.x;
313       event_y = event->motion.y;
314       break;
315
316     case CLUTTER_TOUCH_BEGIN:
317     case CLUTTER_TOUCH_UPDATE:
318     case CLUTTER_TOUCH_END:
319     case CLUTTER_TOUCH_CANCEL:
320       event_x = event->touch.x;
321       event_y = event->touch.y;
322       break;
323
324     case CLUTTER_SCROLL:
325       event_x = event->scroll.x;
326       event_y = event->scroll.y;
327       break;
328     }
329
330   if (x)
331     *x = event_x;
332
333   if (y)
334     *y = event_y;
335 }
336
337 /**
338  * clutter_event_set_coords:
339  * @event: a #ClutterEvent
340  * @x: the X coordinate of the event
341  * @y: the Y coordinate of the event
342  *
343  * Sets the coordinates of the @event.
344  *
345  * Since: 1.8
346  */
347 void
348 clutter_event_set_coords (ClutterEvent *event,
349                           gfloat        x,
350                           gfloat        y)
351 {
352   g_return_if_fail (event != NULL);
353
354   switch (event->type)
355     {
356     case CLUTTER_NOTHING:
357     case CLUTTER_KEY_PRESS:
358     case CLUTTER_KEY_RELEASE:
359     case CLUTTER_STAGE_STATE:
360     case CLUTTER_DESTROY_NOTIFY:
361     case CLUTTER_CLIENT_MESSAGE:
362     case CLUTTER_DELETE:
363     case CLUTTER_EVENT_LAST:
364       break;
365
366     case CLUTTER_ENTER:
367     case CLUTTER_LEAVE:
368       event->crossing.x = x;
369       event->crossing.y = y;
370       break;
371
372     case CLUTTER_BUTTON_PRESS:
373     case CLUTTER_BUTTON_RELEASE:
374       event->button.x = x;
375       event->button.y = y;
376       break;
377
378     case CLUTTER_MOTION:
379       event->motion.x = x;
380       event->motion.y = y;
381       break;
382
383     case CLUTTER_TOUCH_BEGIN:
384     case CLUTTER_TOUCH_UPDATE:
385     case CLUTTER_TOUCH_END:
386     case CLUTTER_TOUCH_CANCEL:
387       event->touch.x = x;
388       event->touch.y = y;
389       break;
390
391     case CLUTTER_SCROLL:
392       event->scroll.x = x;
393       event->scroll.y = y;
394       break;
395     }
396 }
397
398 /**
399  * clutter_event_get_source:
400  * @event: a #ClutterEvent
401  *
402  * Retrieves the source #ClutterActor the event originated from, or
403  * NULL if the event has no source.
404  *
405  * Return value: (transfer none): a #ClutterActor
406  *
407  * Since: 0.6
408  */
409 ClutterActor *
410 clutter_event_get_source (const ClutterEvent *event)
411 {
412   g_return_val_if_fail (event != NULL, NULL);
413
414   return event->any.source;
415 }
416
417 /**
418  * clutter_event_set_source:
419  * @event: a #ClutterEvent
420  * @actor: (allow-none): a #ClutterActor, or %NULL
421  *
422  * Sets the source #ClutterActor of @event.
423  *
424  * Since: 1.8
425  */
426 void
427 clutter_event_set_source (ClutterEvent *event,
428                           ClutterActor *actor)
429 {
430   g_return_if_fail (event != NULL);
431   g_return_if_fail (actor == NULL || CLUTTER_IS_ACTOR (actor));
432
433   event->any.source = actor;
434 }
435
436 /**
437  * clutter_event_get_stage:
438  * @event: a #ClutterEvent
439  *
440  * Retrieves the source #ClutterStage the event originated for, or
441  * %NULL if the event has no stage.
442  *
443  * Return value: (transfer none): a #ClutterStage
444  *
445  * Since: 0.8
446  */
447 ClutterStage *
448 clutter_event_get_stage (const ClutterEvent *event)
449 {
450   g_return_val_if_fail (event != NULL, NULL);
451
452   return event->any.stage;
453 }
454
455 /**
456  * clutter_event_set_stage:
457  * @event: a #ClutterEvent
458  * @stage: (allow-none): a #ClutterStage, or %NULL
459  *
460  * Sets the source #ClutterStage of the event.
461  *
462  * Since: 1.8
463  */
464 void
465 clutter_event_set_stage (ClutterEvent *event,
466                          ClutterStage *stage)
467 {
468   g_return_if_fail (event != NULL);
469   g_return_if_fail (stage == NULL || CLUTTER_IS_STAGE (stage));
470
471   if (event->any.stage == stage)
472     return;
473
474   event->any.stage = stage;
475 }
476
477 /**
478  * clutter_event_get_flags:
479  * @event: a #ClutterEvent
480  *
481  * Retrieves the #ClutterEventFlags of @event
482  *
483  * Return value: the event flags
484  *
485  * Since: 1.0
486  */
487 ClutterEventFlags
488 clutter_event_get_flags (const ClutterEvent *event)
489 {
490   g_return_val_if_fail (event != NULL, CLUTTER_EVENT_NONE);
491
492   return event->any.flags;
493 }
494
495 /**
496  * clutter_event_set_flags:
497  * @event: a #ClutterEvent
498  * @flags: a binary OR of #ClutterEventFlags values
499  *
500  * Sets the #ClutterEventFlags of @event
501  *
502  * Since: 1.8
503  */
504 void
505 clutter_event_set_flags (ClutterEvent      *event,
506                          ClutterEventFlags  flags)
507 {
508   g_return_if_fail (event != NULL);
509
510   if (event->any.flags == flags)
511     return;
512
513   event->any.flags = flags;
514   event->any.flags |= CLUTTER_EVENT_FLAG_SYNTHETIC;
515 }
516
517 /**
518  * clutter_event_get_related:
519  * @event: a #ClutterEvent of type %CLUTTER_ENTER or of
520  *   type %CLUTTER_LEAVE
521  *
522  * Retrieves the related actor of a crossing event.
523  *
524  * Return value: (transfer none): the related #ClutterActor, or %NULL
525  *
526  * Since: 1.0
527  */
528 ClutterActor *
529 clutter_event_get_related (const ClutterEvent *event)
530 {
531   g_return_val_if_fail (event != NULL, NULL);
532   g_return_val_if_fail (event->type == CLUTTER_ENTER ||
533                         event->type == CLUTTER_LEAVE, NULL);
534
535   return event->crossing.related;
536 }
537
538 /**
539  * clutter_event_set_related:
540  * @event: a #ClutterEvent of type %CLUTTER_ENTER or %CLUTTER_LEAVE
541  * @actor: (allow-none): a #ClutterActor or %NULL
542  *
543  * Sets the related actor of a crossing event
544  *
545  * Since: 1.8
546  */
547 void
548 clutter_event_set_related (ClutterEvent *event,
549                            ClutterActor *actor)
550 {
551   g_return_if_fail (event != NULL);
552   g_return_if_fail (event->type == CLUTTER_ENTER ||
553                     event->type == CLUTTER_LEAVE);
554   g_return_if_fail (actor == NULL || CLUTTER_IS_ACTOR (actor));
555
556   if (event->crossing.related == actor)
557     return;
558
559   event->crossing.related = actor;
560 }
561
562 /**
563  * clutter_event_set_scroll_delta:
564  * @event: a #ClutterEvent of type %CLUTTER_SCROLL
565  * @dx: delta on the horizontal axis
566  * @dy: delta on the vertical axis
567  *
568  * Sets the precise scrolling information of @event.
569  *
570  * Since: 1.10
571  */
572 void
573 clutter_event_set_scroll_delta (ClutterEvent *event,
574                                 gdouble       dx,
575                                 gdouble       dy)
576 {
577   g_return_if_fail (event != NULL);
578   g_return_if_fail (event->type == CLUTTER_SCROLL);
579
580   if (!is_event_allocated (event))
581     return;
582
583   event->scroll.direction = CLUTTER_SCROLL_SMOOTH;
584
585   ((ClutterEventPrivate *) event)->delta_x = dx;
586   ((ClutterEventPrivate *) event)->delta_y = dy;
587 }
588
589 /**
590  * clutter_event_get_scroll_delta:
591  * @event: a #ClutterEvent of type %CLUTTER_SCROLL
592  * @dx: (out): return location for the delta on the horizontal axis
593  * @dy: (out): return location for the delta on the vertical axis
594  *
595  * Retrieves the precise scrolling information of @event.
596  *
597  * The @event has to have a #ClutterScrollEvent.direction value
598  * of %CLUTTER_SCROLL_SMOOTH.
599  *
600  * Since: 1.10
601  */
602 void
603 clutter_event_get_scroll_delta (const ClutterEvent *event,
604                                 gdouble            *dx,
605                                 gdouble            *dy)
606 {
607   gdouble delta_x, delta_y;
608
609   g_return_if_fail (event != NULL);
610   g_return_if_fail (event->type == CLUTTER_SCROLL);
611   g_return_if_fail (event->scroll.direction == CLUTTER_SCROLL_SMOOTH);
612
613   delta_x = delta_y = 0;
614
615   if (is_event_allocated (event))
616     {
617       delta_x = ((ClutterEventPrivate *) event)->delta_x;
618       delta_y = ((ClutterEventPrivate *) event)->delta_y;
619     }
620
621   if (dx != NULL)
622     *dx = delta_x;
623
624   if (dy != NULL)
625     *dy = delta_y;
626 }
627
628 /**
629  * clutter_event_get_scroll_direction:
630  * @event: a #ClutterEvent of type %CLUTTER_SCROLL
631  *
632  * Retrieves the direction of the scrolling of @event
633  *
634  * Return value: the scrolling direction
635  *
636  * Since: 1.0
637  */
638 ClutterScrollDirection
639 clutter_event_get_scroll_direction (const ClutterEvent *event)
640 {
641   g_return_val_if_fail (event != NULL, CLUTTER_SCROLL_UP);
642   g_return_val_if_fail (event->type == CLUTTER_SCROLL, CLUTTER_SCROLL_UP);
643
644   return event->scroll.direction;
645 }
646
647 /**
648  * clutter_event_set_scroll_direction:
649  * @event: a #ClutterEvent
650  * @direction: the scrolling direction
651  *
652  * Sets the direction of the scrolling of @event
653  *
654  * Since: 1.8
655  */
656 void
657 clutter_event_set_scroll_direction (ClutterEvent           *event,
658                                     ClutterScrollDirection  direction)
659 {
660   g_return_if_fail (event != NULL);
661   g_return_if_fail (event->type == CLUTTER_SCROLL);
662
663   event->scroll.direction = direction;
664 }
665
666 /**
667  * clutter_event_get_button:
668  * @event: a #ClutterEvent of type %CLUTTER_BUTTON_PRESS or
669  *   of type %CLUTTER_BUTTON_RELEASE
670  *
671  * Retrieves the button number of @event
672  *
673  * Return value: the button number
674  *
675  * Since: 1.0
676  */
677 guint32
678 clutter_event_get_button (const ClutterEvent *event)
679 {
680   g_return_val_if_fail (event != NULL, 0);
681   g_return_val_if_fail (event->type == CLUTTER_BUTTON_PRESS ||
682                         event->type == CLUTTER_BUTTON_RELEASE, 0);
683
684   return event->button.button;
685 }
686
687 /**
688  * clutter_event_set_button:
689  * @event: a #ClutterEvent or type %CLUTTER_BUTTON_PRESS or
690  *   of type %CLUTTER_BUTTON_RELEASE
691  * @button: the button number
692  *
693  * Sets the button number of @event
694  *
695  * Since: 1.8
696  */
697 void
698 clutter_event_set_button (ClutterEvent *event,
699                           guint32       button)
700 {
701   g_return_if_fail (event != NULL);
702   g_return_if_fail (event->type == CLUTTER_BUTTON_PRESS ||
703                     event->type == CLUTTER_BUTTON_RELEASE);
704
705   event->button.button = button;
706 }
707
708 /**
709  * clutter_event_get_click_count:
710  * @event: a #ClutterEvent of type %CLUTTER_BUTTON_PRESS or
711  *   of type %CLUTTER_BUTTON_RELEASE
712  *
713  * Retrieves the number of clicks of @event
714  *
715  * Return value: the click count
716  *
717  * Since: 1.0
718  */
719 guint32
720 clutter_event_get_click_count (const ClutterEvent *event)
721 {
722   g_return_val_if_fail (event != NULL, 0);
723   g_return_val_if_fail (event->type == CLUTTER_BUTTON_PRESS ||
724                         event->type == CLUTTER_BUTTON_RELEASE, 0);
725
726   return event->button.click_count;
727 }
728
729 /* keys */
730
731 /**
732  * clutter_event_get_key_symbol:
733  * @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS or
734  *   of type %CLUTTER_KEY_RELEASE
735  *
736  * Retrieves the key symbol of @event
737  *
738  * Return value: the key symbol representing the key
739  *
740  * Since: 1.0
741  */
742 guint
743 clutter_event_get_key_symbol (const ClutterEvent *event)
744 {
745   g_return_val_if_fail (event != NULL, 0);
746   g_return_val_if_fail (event->type == CLUTTER_KEY_PRESS ||
747                         event->type == CLUTTER_KEY_RELEASE, 0);
748
749   return event->key.keyval;
750 }
751
752 /**
753  * clutter_event_set_key_symbol:
754  * @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS
755  *   or %CLUTTER_KEY_RELEASE
756  * @key_sym: the key symbol representing the key
757  *
758  * Sets the key symbol of @event.
759  *
760  * Since: 1.8
761  */
762 void
763 clutter_event_set_key_symbol (ClutterEvent *event,
764                               guint         key_sym)
765 {
766   g_return_if_fail (event != NULL);
767   g_return_if_fail (event->type == CLUTTER_KEY_PRESS ||
768                     event->type == CLUTTER_KEY_RELEASE);
769
770   event->key.keyval = key_sym;
771 }
772
773 /**
774  * clutter_event_get_key_code:
775  * @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS or
776  *    of type %CLUTTER_KEY_RELEASE
777  *
778  * Retrieves the keycode of the key that caused @event
779  *
780  * Return value: The keycode representing the key
781  *
782  * Since: 1.0
783  */
784 guint16
785 clutter_event_get_key_code (const ClutterEvent *event)
786 {
787   g_return_val_if_fail (event != NULL, 0);
788   g_return_val_if_fail (event->type == CLUTTER_KEY_PRESS ||
789                         event->type == CLUTTER_KEY_RELEASE, 0);
790
791   return event->key.hardware_keycode;
792 }
793
794 /**
795  * clutter_event_set_key_code:
796  * @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS
797  *   or %CLUTTER_KEY_RELEASE
798  * @key_code: the keycode representing the key
799  *
800  * Sets the keycode of the @event.
801  *
802  * Since: 1.8
803  */
804 void
805 clutter_event_set_key_code (ClutterEvent *event,
806                             guint16       key_code)
807 {
808   g_return_if_fail (event != NULL);
809   g_return_if_fail (event->type == CLUTTER_KEY_PRESS ||
810                     event->type == CLUTTER_KEY_RELEASE);
811
812   event->key.hardware_keycode = key_code;
813 }
814
815 /**
816  * clutter_event_get_key_unicode:
817  * @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS
818  *   or %CLUTTER_KEY_RELEASE
819  *
820  * Retrieves the unicode value for the key that caused @keyev.
821  *
822  * Return value: The unicode value representing the key
823  */
824 guint32
825 clutter_event_get_key_unicode (const ClutterEvent *event)
826 {
827   g_return_val_if_fail (event != NULL, 0);
828   g_return_val_if_fail (event->type == CLUTTER_KEY_PRESS ||
829                         event->type == CLUTTER_KEY_RELEASE, 0);
830
831   if (event->key.unicode_value)
832     return event->key.unicode_value;
833   else
834     return clutter_keysym_to_unicode (event->key.keyval);
835 }
836
837 /**
838  * clutter_event_set_key_unicode:
839  * @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS
840  *   or %CLUTTER_KEY_RELEASE
841  * @key_unicode: the Unicode value representing the key
842  *
843  * Sets the Unicode value of @event.
844  *
845  * Since: 1.8
846  */
847 void
848 clutter_event_set_key_unicode (ClutterEvent *event,
849                                guint32       key_unicode)
850 {
851   g_return_if_fail (event != NULL);
852   g_return_if_fail (event->type == CLUTTER_KEY_PRESS ||
853                     event->type == CLUTTER_KEY_RELEASE);
854
855   event->key.unicode_value = key_unicode;
856 }
857
858 /**
859  * clutter_event_get_event_sequence:
860  * @event: a #ClutterEvent of type %CLUTTER_TOUCH_BEGIN,
861  *   %CLUTTER_TOUCH_UPDATE, %CLUTTER_TOUCH_END, or
862  *   %CLUTTER_TOUCH_CANCEL
863  *
864  * Retrieves the #ClutterEventSequence of @event.
865  *
866  * Return value: (transfer none): the event sequence, or %NULL
867  *
868  * Since: 1.10
869  */
870 ClutterEventSequence *
871 clutter_event_get_event_sequence (const ClutterEvent *event)
872 {
873   g_return_val_if_fail (event != NULL, NULL);
874
875   if (event->type == CLUTTER_TOUCH_BEGIN ||
876       event->type == CLUTTER_TOUCH_UPDATE ||
877       event->type == CLUTTER_TOUCH_END ||
878       event->type == CLUTTER_TOUCH_CANCEL)
879     return event->touch.sequence;
880
881   return NULL;
882 }
883
884 /**
885  * clutter_event_get_device_id:
886  * @event: a clutter event 
887  *
888  * Retrieves the events device id if set.
889  *
890  * Return value: A unique identifier for the device or -1 if the event has
891  *   no specific device set.
892  */
893 gint
894 clutter_event_get_device_id (const ClutterEvent *event)
895 {
896   ClutterInputDevice *device = NULL;
897
898   g_return_val_if_fail (event != NULL, CLUTTER_POINTER_DEVICE);
899
900   device = clutter_event_get_device (event);
901   if (device != NULL)
902     return clutter_input_device_get_device_id (device);
903
904   return -1;
905 }
906
907 /**
908  * clutter_event_get_device_type:
909  * @event: a #ClutterEvent
910  *
911  * Retrieves the type of the device for @event
912  *
913  * Return value: the #ClutterInputDeviceType for the device, if
914  *   any is set
915  *
916  * Since: 1.0
917  */
918 ClutterInputDeviceType
919 clutter_event_get_device_type (const ClutterEvent *event)
920 {
921   ClutterInputDevice *device = NULL;
922
923   g_return_val_if_fail (event != NULL, CLUTTER_POINTER_DEVICE);
924
925   device = clutter_event_get_device (event);
926   if (device != NULL)
927     return clutter_input_device_get_device_type (device);
928
929   return CLUTTER_POINTER_DEVICE;
930 }
931
932 /**
933  * clutter_event_set_device:
934  * @event: a #ClutterEvent
935  * @device: (allow-none): a #ClutterInputDevice, or %NULL
936  *
937  * Sets the device for @event.
938  *
939  * Since: 1.6
940  */
941 void
942 clutter_event_set_device (ClutterEvent       *event,
943                           ClutterInputDevice *device)
944 {
945   g_return_if_fail (event != NULL);
946   g_return_if_fail (device == NULL || CLUTTER_IS_INPUT_DEVICE (device));
947
948   if (is_event_allocated (event))
949     {
950       ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
951
952       real_event->device = device;
953     }
954
955   switch (event->type)
956     {
957     case CLUTTER_NOTHING:
958     case CLUTTER_STAGE_STATE:
959     case CLUTTER_DESTROY_NOTIFY:
960     case CLUTTER_CLIENT_MESSAGE:
961     case CLUTTER_DELETE:
962     case CLUTTER_EVENT_LAST:
963       break;
964
965     case CLUTTER_ENTER:
966     case CLUTTER_LEAVE:
967       event->crossing.device = device;
968       break;
969
970     case CLUTTER_BUTTON_PRESS:
971     case CLUTTER_BUTTON_RELEASE:
972       event->button.device = device;
973       break;
974
975     case CLUTTER_MOTION:
976       event->motion.device = device;
977       break;
978
979     case CLUTTER_SCROLL:
980       event->scroll.device = device;
981       break;
982
983     case CLUTTER_TOUCH_BEGIN:
984     case CLUTTER_TOUCH_UPDATE:
985     case CLUTTER_TOUCH_END:
986     case CLUTTER_TOUCH_CANCEL:
987       event->touch.device = device;
988       break;
989
990     case CLUTTER_KEY_PRESS:
991     case CLUTTER_KEY_RELEASE:
992       event->key.device = device;
993       break;
994     }
995 }
996
997 /**
998  * clutter_event_get_device:
999  * @event: a #ClutterEvent
1000  *
1001  * Retrieves the #ClutterInputDevice for the event.
1002  *
1003  * The #ClutterInputDevice structure is completely opaque and should
1004  * be cast to the platform-specific implementation.
1005  *
1006  * Return value: (transfer none): the #ClutterInputDevice or %NULL. The
1007  *   returned device is owned by the #ClutterEvent and it should not
1008  *   be unreferenced
1009  *
1010  * Since: 1.0
1011  */
1012 ClutterInputDevice *
1013 clutter_event_get_device (const ClutterEvent *event)
1014 {
1015   ClutterInputDevice *device = NULL;
1016
1017   g_return_val_if_fail (event != NULL, NULL);
1018
1019   if (is_event_allocated (event))
1020     {
1021       ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
1022
1023       if (real_event->device != NULL)
1024         return real_event->device;
1025     }
1026
1027   switch (event->type)
1028     {
1029     case CLUTTER_NOTHING:
1030     case CLUTTER_STAGE_STATE:
1031     case CLUTTER_DESTROY_NOTIFY:
1032     case CLUTTER_CLIENT_MESSAGE:
1033     case CLUTTER_DELETE:
1034     case CLUTTER_EVENT_LAST:
1035       break;
1036
1037     case CLUTTER_ENTER:
1038     case CLUTTER_LEAVE:
1039       device = event->crossing.device;
1040       break;
1041
1042     case CLUTTER_BUTTON_PRESS:
1043     case CLUTTER_BUTTON_RELEASE:
1044       device = event->button.device;
1045       break;
1046
1047     case CLUTTER_MOTION:
1048       device = event->motion.device;
1049       break;
1050
1051     case CLUTTER_SCROLL:
1052       device = event->scroll.device;
1053       break;
1054
1055     case CLUTTER_TOUCH_BEGIN:
1056     case CLUTTER_TOUCH_UPDATE:
1057     case CLUTTER_TOUCH_END:
1058     case CLUTTER_TOUCH_CANCEL:
1059       device = event->touch.device;
1060       break;
1061
1062     case CLUTTER_KEY_PRESS:
1063     case CLUTTER_KEY_RELEASE:
1064       device = event->key.device;
1065       break;
1066     }
1067
1068   return device;
1069 }
1070
1071 /**
1072  * clutter_event_new:
1073  * @type: The type of event.
1074  *
1075  * Creates a new #ClutterEvent of the specified type.
1076  *
1077  * Return value: (transfer full): A newly allocated #ClutterEvent.
1078  */
1079 ClutterEvent *
1080 clutter_event_new (ClutterEventType type)
1081 {
1082   ClutterEvent *new_event;
1083   ClutterEventPrivate *priv;
1084
1085   priv = g_slice_new0 (ClutterEventPrivate);
1086
1087   new_event = (ClutterEvent *) priv;
1088   new_event->type = new_event->any.type = type;
1089
1090   if (G_UNLIKELY (all_events == NULL))
1091     all_events = g_hash_table_new (NULL, NULL);
1092
1093   g_hash_table_replace (all_events, priv, GUINT_TO_POINTER (1));
1094
1095   return new_event;
1096 }
1097
1098 /**
1099  * clutter_event_copy:
1100  * @event: A #ClutterEvent.
1101  *
1102  * Copies @event.
1103  *
1104  * Return value: (transfer full): A newly allocated #ClutterEvent
1105  */
1106 ClutterEvent *
1107 clutter_event_copy (const ClutterEvent *event)
1108 {
1109   ClutterEvent *new_event;
1110   ClutterEventPrivate *new_real_event;
1111   ClutterInputDevice *device;
1112   gint n_axes = 0;
1113
1114   g_return_val_if_fail (event != NULL, NULL);
1115
1116   new_event = clutter_event_new (CLUTTER_NOTHING);
1117   new_real_event = (ClutterEventPrivate *) new_event;
1118
1119   *new_event = *event;
1120
1121   if (is_event_allocated (event))
1122     {
1123       ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
1124
1125       new_real_event->device = real_event->device;
1126       new_real_event->source_device = real_event->source_device;
1127       new_real_event->delta_x = real_event->delta_x;
1128       new_real_event->delta_y = real_event->delta_y;
1129     }
1130
1131   device = clutter_event_get_device (event);
1132   if (device != NULL)
1133     n_axes = clutter_input_device_get_n_axes (device);
1134
1135   switch (event->type)
1136     {
1137     case CLUTTER_BUTTON_PRESS:
1138     case CLUTTER_BUTTON_RELEASE:
1139       if (event->button.axes != NULL)
1140         new_event->button.axes = g_memdup (event->button.axes,
1141                                            sizeof (gdouble) * n_axes);
1142       break;
1143
1144     case CLUTTER_SCROLL:
1145       if (event->scroll.axes != NULL)
1146         new_event->scroll.axes = g_memdup (event->scroll.axes,
1147                                            sizeof (gdouble) * n_axes);
1148       break;
1149
1150     case CLUTTER_MOTION:
1151       if (event->motion.axes != NULL)
1152         new_event->motion.axes = g_memdup (event->motion.axes,
1153                                            sizeof (gdouble) * n_axes);
1154       break;
1155
1156     case CLUTTER_TOUCH_BEGIN:
1157     case CLUTTER_TOUCH_UPDATE:
1158     case CLUTTER_TOUCH_END:
1159     case CLUTTER_TOUCH_CANCEL:
1160       if (event->touch.axes != NULL)
1161         new_event->touch.axes = g_memdup (event->motion.axes,
1162                                           sizeof (gdouble) * n_axes);
1163       break;
1164
1165     default:
1166       break;
1167     }
1168
1169   if (is_event_allocated (event))
1170     _clutter_backend_copy_event_data (clutter_get_default_backend (),
1171                                       event,
1172                                       new_event);
1173
1174   return new_event;
1175 }
1176
1177 /**
1178  * clutter_event_free:
1179  * @event: A #ClutterEvent.
1180  *
1181  * Frees all resources used by @event.
1182  */
1183 void
1184 clutter_event_free (ClutterEvent *event)
1185 {
1186   if (G_LIKELY (event != NULL))
1187     {
1188       _clutter_backend_free_event_data (clutter_get_default_backend (), event);
1189
1190       switch (event->type)
1191         {
1192         case CLUTTER_BUTTON_PRESS:
1193         case CLUTTER_BUTTON_RELEASE:
1194           g_free (event->button.axes);
1195           break;
1196
1197         case CLUTTER_MOTION:
1198           g_free (event->motion.axes);
1199           break;
1200
1201         case CLUTTER_SCROLL:
1202           g_free (event->scroll.axes);
1203           break;
1204
1205         case CLUTTER_TOUCH_BEGIN:
1206         case CLUTTER_TOUCH_UPDATE:
1207         case CLUTTER_TOUCH_END:
1208         case CLUTTER_TOUCH_CANCEL:
1209           g_free (event->touch.axes);
1210           break;
1211
1212         default:
1213           break;
1214         }
1215
1216       g_hash_table_remove (all_events, event);
1217       g_slice_free (ClutterEventPrivate, (ClutterEventPrivate *) event);
1218     }
1219 }
1220
1221 /**
1222  * clutter_event_get:
1223  *
1224  * Pops an event off the event queue. Applications should not need to call 
1225  * this.
1226  *
1227  * Return value: A #ClutterEvent or NULL if queue empty
1228  *
1229  * Since: 0.4
1230  */
1231 ClutterEvent *
1232 clutter_event_get (void)
1233 {
1234   ClutterMainContext *context = _clutter_context_get_default ();
1235
1236   if (context->events_queue == NULL)
1237     return NULL;
1238
1239   if (g_queue_is_empty (context->events_queue))
1240     return NULL;
1241
1242   return g_queue_pop_tail (context->events_queue);
1243 }
1244
1245 /**
1246  * clutter_event_peek:
1247  * 
1248  * Returns a pointer to the first event from the event queue but 
1249  * does not remove it. 
1250  *
1251  * Return value: (transfer none): A #ClutterEvent or NULL if queue empty.
1252  *
1253  * Since: 0.4
1254  */
1255 ClutterEvent *
1256 clutter_event_peek (void)
1257 {
1258   ClutterMainContext *context = _clutter_context_get_default ();
1259
1260   g_return_val_if_fail (context != NULL, NULL);
1261   
1262   if (context->events_queue == NULL)
1263     return NULL;
1264
1265   if (g_queue_is_empty (context->events_queue))
1266     return NULL;
1267
1268   return g_queue_peek_tail (context->events_queue);
1269 }
1270
1271 void
1272 _clutter_event_push (const ClutterEvent *event,
1273                      gboolean            do_copy)
1274 {
1275   ClutterMainContext *context = _clutter_context_get_default ();
1276   ClutterInputDevice *device;
1277
1278   g_assert (context != NULL);
1279
1280   if (context->events_queue == NULL)
1281     context->events_queue = g_queue_new ();
1282
1283   /* disabled devices don't propagate events */
1284   device = clutter_event_get_device (event);
1285   if (device != NULL)
1286     {
1287       if (!clutter_input_device_get_enabled (device))
1288         return;
1289     }
1290
1291   if (do_copy)
1292     {
1293       ClutterEvent *copy;
1294
1295       copy = clutter_event_copy (event);
1296       event = copy;
1297     }
1298
1299   g_queue_push_head (context->events_queue, (gpointer) event);
1300 }
1301
1302 /**
1303  * clutter_event_put:
1304  * @event: a #ClutterEvent
1305  *
1306  * Puts a copy of the event on the back of the event queue. The event will
1307  * have the %CLUTTER_EVENT_FLAG_SYNTHETIC flag set. If the source is set
1308  * event signals will be emitted for this source and capture/bubbling for
1309  * its ancestors. If the source is not set it will be generated by picking
1310  * or use the actor that currently has keyboard focus
1311  *
1312  * Since: 0.6
1313  */
1314 void
1315 clutter_event_put (const ClutterEvent *event)
1316 {
1317   _clutter_event_push (event, TRUE);
1318 }
1319
1320 /**
1321  * clutter_events_pending:
1322  *
1323  * Checks if events are pending in the event queue.
1324  *
1325  * Return value: TRUE if there are pending events, FALSE otherwise.
1326  *
1327  * Since: 0.4
1328  */
1329 gboolean
1330 clutter_events_pending (void)
1331 {
1332   ClutterMainContext *context = _clutter_context_get_default ();
1333
1334   g_return_val_if_fail (context != NULL, FALSE);
1335
1336   if (context->events_queue == NULL)
1337     return FALSE;
1338
1339   return g_queue_is_empty (context->events_queue) == FALSE;
1340 }
1341
1342 /**
1343  * clutter_get_current_event_time:
1344  *
1345  * Retrieves the timestamp of the last event, if there is an
1346  * event or if the event has a timestamp.
1347  *
1348  * Return value: the event timestamp, or %CLUTTER_CURRENT_TIME
1349  *
1350  * Since: 1.0
1351  */
1352 guint32
1353 clutter_get_current_event_time (void)
1354 {
1355   ClutterMainContext *context = _clutter_context_get_default ();
1356
1357   g_return_val_if_fail (context != NULL, FALSE);
1358
1359   if (context->last_event_time != 0)
1360     return context->last_event_time;
1361
1362   return CLUTTER_CURRENT_TIME;
1363 }
1364
1365 /**
1366  * clutter_get_current_event:
1367  *
1368  * If an event is currently being processed, return that event.
1369  * This function is intended to be used to access event state
1370  * that might not be exposed by higher-level widgets.  For
1371  * example, to get the key modifier state from a Button 'clicked'
1372  * event.
1373  *
1374  * Return value: (transfer none): The current ClutterEvent, or %NULL if none
1375  *
1376  * Since: 1.2
1377  */
1378 const ClutterEvent *
1379 clutter_get_current_event (void)
1380 {
1381   ClutterMainContext *context = _clutter_context_get_default ();
1382
1383   g_return_val_if_fail (context != NULL, NULL);
1384
1385   return context->current_event;
1386 }
1387
1388 /**
1389  * clutter_event_get_source_device:
1390  * @event: a #ClutterEvent
1391  *
1392  * Retrieves the hardware device that originated the event.
1393  *
1394  * If you need the virtual device, use clutter_event_get_device().
1395  *
1396  * If no hardware device originated this event, this function will
1397  * return the same device as clutter_event_get_device().
1398  *
1399  * Return value: (transfer none): a pointer to a #ClutterInputDevice
1400  *   or %NULL
1401  *
1402  * Since: 1.6
1403  */
1404 ClutterInputDevice *
1405 clutter_event_get_source_device (const ClutterEvent *event)
1406 {
1407   ClutterEventPrivate *real_event;
1408
1409   if (!is_event_allocated (event))
1410     return NULL;
1411
1412   real_event = (ClutterEventPrivate *) event;
1413
1414   if (real_event->source_device != NULL)
1415     return real_event->source_device;
1416
1417   return clutter_event_get_device (event);
1418 }
1419
1420 /**
1421  * clutter_event_set_source_device:
1422  * @event: a #ClutterEvent
1423  * @device: (allow-none): a #ClutterInputDevice
1424  *
1425  * Sets the source #ClutterInputDevice for @event.
1426  *
1427  * The #ClutterEvent must have been created using clutter_event_new().
1428  *
1429  * Since: 1.8
1430  */
1431 void
1432 clutter_event_set_source_device (ClutterEvent       *event,
1433                                  ClutterInputDevice *device)
1434 {
1435   ClutterEventPrivate *real_event;
1436
1437   g_return_if_fail (event != NULL);
1438   g_return_if_fail (device == NULL || CLUTTER_IS_INPUT_DEVICE (device));
1439
1440   if (!is_event_allocated (event))
1441     return;
1442
1443   real_event = (ClutterEventPrivate *) event;
1444   real_event->source_device = device;
1445 }
1446
1447 /**
1448  * clutter_event_get_axes:
1449  * @event: a #ClutterEvent
1450  * @n_axes: (out): return location for the number of axes returned
1451  *
1452  * Retrieves the array of axes values attached to the event.
1453  *
1454  * Return value: (transfer none): an array of axis values
1455  *
1456  * Since: 1.6
1457  */
1458 gdouble *
1459 clutter_event_get_axes (const ClutterEvent *event,
1460                         guint              *n_axes)
1461 {
1462   gdouble *retval = NULL;
1463   guint len = 0;
1464
1465   switch (event->type)
1466     {
1467     case CLUTTER_NOTHING:
1468     case CLUTTER_STAGE_STATE:
1469     case CLUTTER_DESTROY_NOTIFY:
1470     case CLUTTER_CLIENT_MESSAGE:
1471     case CLUTTER_DELETE:
1472     case CLUTTER_ENTER:
1473     case CLUTTER_LEAVE:
1474     case CLUTTER_KEY_PRESS:
1475     case CLUTTER_KEY_RELEASE:
1476     case CLUTTER_EVENT_LAST:
1477       break;
1478
1479     case CLUTTER_SCROLL:
1480       retval = event->scroll.axes;
1481       break;
1482
1483     case CLUTTER_BUTTON_PRESS:
1484     case CLUTTER_BUTTON_RELEASE:
1485       retval = event->button.axes;
1486       break;
1487
1488     case CLUTTER_TOUCH_BEGIN:
1489     case CLUTTER_TOUCH_UPDATE:
1490     case CLUTTER_TOUCH_END:
1491     case CLUTTER_TOUCH_CANCEL:
1492       retval = event->touch.axes;
1493       break;
1494
1495     case CLUTTER_MOTION:
1496       retval = event->motion.axes;
1497       break;
1498     }
1499
1500   if (retval != NULL)
1501     {
1502       ClutterInputDevice *device;
1503
1504       device = clutter_event_get_device (event);
1505       if (device != NULL)
1506         len = clutter_input_device_get_n_axes (device);
1507       else
1508         retval = NULL;
1509     }
1510
1511   if (n_axes)
1512     *n_axes = len;
1513
1514   return retval;
1515 }