i think i may have fixed a bug in mosue grabs. not sure though as
[profile/ivi/evas.git] / src / lib / canvas / evas_events.c
1 #include "evas_common.h"
2 #include "evas_private.h"
3
4 static void
5 _evas_event_havemap_adjust(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
6 {
7    Evas_Object *pmap;
8    
9    if (!obj->havemap_parent) return;
10    pmap = obj->smart.parent;
11    if (!pmap) return;
12    while (pmap)
13      {
14         if ((pmap->cur.map) && (pmap->cur.map->count == 4) && (pmap->cur.usemap))
15           break;
16         pmap = pmap->smart.parent;
17      }
18    if (!pmap) return;
19    evas_map_coords_get(pmap->cur.map, *x, *y, x, y, obj->mouse_grabbed);
20    if (pmap->cur.map)
21      {
22         *x += pmap->cur.map->normal_geometry.x;
23         *y += pmap->cur.map->normal_geometry.y;
24      }
25 }
26
27 static Eina_List *
28 _evas_event_object_list_in_get(Evas *e, Eina_List *in,
29                                const Eina_Inlist *list, Evas_Object *stop, 
30                                int x, int y, int *no_rep, int parmap)
31 {
32    Evas_Object *obj;
33    if (!list) return in;
34    EINA_INLIST_REVERSE_FOREACH(list, obj)
35      {
36         if (parmap) obj->havemap_parent = 1;
37         else obj->havemap_parent = 0;
38         
39         if (obj == stop)
40           {
41              *no_rep = 1;
42              return in;
43           }
44         if (evas_event_passes_through(obj)) continue;
45         if ((obj->cur.visible) && (obj->delete_me == 0) &&
46             (!obj->clip.clipees) &&
47             (evas_object_clippers_is_visible(obj)))
48           {
49              if (obj->smart.smart)
50                {
51                   int norep;
52                   int inside;
53                   
54                   norep = 0;
55                   if (((obj->cur.map) && (obj->cur.map->count == 4) && (obj->cur.usemap)))
56                     {
57                        inside = evas_object_is_in_output_rect(obj, x, y, 1, 1);
58                        if (inside)
59                          {
60                             if (!evas_map_coords_get(obj->cur.map, x, y,
61                                                      &(obj->cur.map->mx),
62                                                      &(obj->cur.map->my), 0))
63                                inside = 0;
64                             else
65                                parmap = 1;
66                          }
67                        else
68                          inside = 0;
69                        if (inside)
70                          {
71                             in = _evas_event_object_list_in_get
72                               (e, in,
73                                evas_object_smart_members_get_direct(obj),
74                                stop, 
75                                obj->cur.geometry.x + obj->cur.map->mx, 
76                                obj->cur.geometry.y + obj->cur.map->my, 
77                                &norep, parmap);
78                          }
79                     }
80                   else
81                     {
82                        in = _evas_event_object_list_in_get
83                          (e, in, evas_object_smart_members_get_direct(obj),
84                           stop, x, y, &norep, parmap);
85                     }
86                   if (norep)
87                     {
88                        *no_rep = 1;
89                        return in;
90                     }
91                }
92              else
93                {
94                   int inside = 1;
95                   
96                   if (((obj->cur.map) && (obj->cur.map->count == 4) && (obj->cur.usemap)))
97                     {
98                        inside = evas_object_is_in_output_rect(obj, x, y, 1, 1);
99                        if (inside)
100                          {
101                             if (!evas_map_coords_get(obj->cur.map, x, y,
102                                                      &(obj->cur.map->mx),
103                                                      &(obj->cur.map->my), 0))
104                               inside = 0;
105                          }
106                        else
107                          inside = 0;
108                     }
109                   else
110                     inside = evas_object_is_in_output_rect(obj, x, y, 1, 1);
111                   if (inside && ((!obj->precise_is_inside) ||
112                                  (evas_object_is_inside(obj, x, y))))
113                     {
114                        in = eina_list_append(in, obj);
115                        if (!obj->repeat_events)
116                          {
117                             *no_rep = 1;
118                             return in;
119                          }
120                     }
121                }
122           }
123      }
124    *no_rep = 0;
125    return in;
126 }
127
128 Eina_List *
129 evas_event_objects_event_list(Evas *e, Evas_Object *stop, int x, int y)
130 {
131    Evas_Layer *lay;
132    Eina_List *in = NULL;
133
134    if (!e->layers) return NULL;
135    EINA_INLIST_REVERSE_FOREACH((EINA_INLIST_GET(e->layers)), lay)
136      {
137         int norep;
138
139         norep = 0;
140         in = _evas_event_object_list_in_get(e, in, 
141                                             EINA_INLIST_GET(lay->objects), 
142                                             stop, x, y, &norep, 0);
143         if (norep) return in;
144      }
145    return in;
146 }
147
148 static Eina_List *evas_event_list_copy(Eina_List *list);
149 static Eina_List *
150 evas_event_list_copy(Eina_List *list)
151 {
152    Eina_List *l, *new_l = NULL;
153    const void *data;
154
155    EINA_LIST_FOREACH(list, l, data)
156      new_l = eina_list_append(new_l, data);
157    return new_l;
158 }
159 /* public functions */
160
161 /**
162  * @addtogroup Evas_Event_Freezing_Group
163  * @{
164  */
165
166 /**
167  * Freeze all event processing.
168  * @param e The canvas to freeze event processing on.
169  *
170  * This function will indicate to evas that the canvas @p e is to have
171  * all event processing frozen until a matching evas_event_thaw()
172  * function is called on the same canvas. Every freeze call must be
173  * matched by a thaw call in order to completely thaw out a canvas.
174  *
175  * Example:
176  * @code
177  * extern Evas *evas;
178  * extern Evas_Object *object;
179  *
180  * evas_event_freeze(evas);
181  * evas_object_move(object, 50, 100);
182  * evas_object_resize(object, 200, 200);
183  * evas_event_thaw(evas);
184  * @endcode
185  */
186 EAPI void
187 evas_event_freeze(Evas *e)
188 {
189    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
190    return;
191    MAGIC_CHECK_END();
192    e->events_frozen++;
193 }
194
195 /**
196  * Thaw a canvas out after freezing.
197  *
198  * @param e The canvas to thaw out.
199  *
200  * This will thaw out a canvas after a matching evas_event_freeze()
201  * call. If this call completely thaws out a canvas, events will start
202  * being processed again after this call, but this call will not
203  * invole any "missed" events to be evaluated.
204  *
205  * See evas_event_freeze() for an example.
206  */
207 EAPI void
208 evas_event_thaw(Evas *e)
209 {
210    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
211    return;
212    MAGIC_CHECK_END();
213    e->events_frozen--;
214    if (e->events_frozen == 0)
215      {
216         Evas_Layer *lay;
217
218         EINA_INLIST_FOREACH((EINA_INLIST_GET(e->layers)), lay)
219           {
220              Evas_Object *obj;
221
222              EINA_INLIST_FOREACH(lay->objects, obj)
223                {
224                   evas_object_clip_recalc(obj);
225                   evas_object_recalc_clippees(obj);
226                }
227           }
228      }
229    if (e->events_frozen < 0)
230      evas_debug_generic("  Thaw of events when already thawed!!!\n");
231 }
232
233 /**
234  * @}
235  */
236
237 /**
238  * @addtogroup Evas_Event_Feeding_Group
239  * @{
240  */
241
242 /**
243  * Return the freeze count of a given canvas.
244  * @param e The canvas to fetch the freeze count from.
245  *
246  * This returns the number of times the canvas has been told to freeze
247  * events.  It is possible to call evas_event_freeze() multiple times,
248  * and these must be matched by evas_event_thaw() calls. This call
249  * allows the program to discover just how many times things have been
250  * frozen in case it may want to break out of a deep freeze state
251  * where the count is high.
252  *
253  * Example:
254  * @code
255  * extern Evas *evas;
256  *
257  * while (evas_event_freeze_get(evas) > 0) evas_event_thaw(evas);
258  * @endcode
259  *
260  */
261 EAPI int
262 evas_event_freeze_get(const Evas *e)
263 {
264    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
265    return 0;
266    MAGIC_CHECK_END();
267    return e->events_frozen;
268 }
269
270
271 /**
272  * Mouse down event feed.
273  *
274  * @param e The given canvas pointer.
275  * @param b The button number.
276  * @param flags The evas button flags.
277  * @param timestamp The timestamp of the mouse down event.
278  * @param data The data for canvas.
279  *
280  * This function will set some evas properties that is necessary when
281  * the mouse button is pressed. It prepares information to be treated
282  * by the callback function.
283  *
284  */
285 EAPI void
286 evas_event_feed_mouse_down(Evas *e, int b, Evas_Button_Flags flags, unsigned int timestamp, const void *data)
287 {
288    Eina_List *l, *copy;
289    Eina_List *ins;
290    Evas_Event_Mouse_Down ev;
291    Evas_Object *obj;
292
293    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
294    return;
295    MAGIC_CHECK_END();
296
297    if ((b < 1) || (b > 32)) return;
298
299    e->pointer.button |= (1 << (b - 1));
300
301    if (e->events_frozen > 0) return;
302    e->last_timestamp = timestamp;
303
304    _evas_object_event_new();
305
306    ev.button = b;
307    ev.output.x = e->pointer.x;
308    ev.output.y = e->pointer.y;
309    ev.canvas.x = e->pointer.x;
310    ev.canvas.y = e->pointer.y;
311    ev.data = (void *)data;
312    ev.modifiers = &(e->modifiers);
313    ev.locks = &(e->locks);
314    ev.flags = flags;
315    ev.timestamp = timestamp;
316    ev.event_flags = EVAS_EVENT_FLAG_NONE;
317
318    _evas_walk(e);
319    ins = evas_event_objects_event_list(e, NULL, e->pointer.x, e->pointer.y);
320    /* free our old list of ins */
321    e->pointer.object.in = eina_list_free(e->pointer.object.in);
322    /* and set up the new one */
323    e->pointer.object.in = ins;
324    copy = evas_event_list_copy(e->pointer.object.in);
325    EINA_LIST_FOREACH(copy, l, obj)
326      {
327         if (obj->delete_me) continue;
328         
329         ev.canvas.x = e->pointer.x;
330         ev.canvas.y = e->pointer.y;
331         _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y);
332         if (obj->pointer_mode != EVAS_OBJECT_POINTER_MODE_NOGRAB)
333           {
334              obj->mouse_grabbed++;
335              e->pointer.mouse_grabbed++;
336           }
337
338         if (e->events_frozen <= 0)
339           evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_DOWN, &ev);
340         if (e->delete_me) break;
341      }
342    if (copy) eina_list_free(copy);
343    e->last_mouse_down_counter++;
344    _evas_post_event_callback_call(e);
345    _evas_unwalk(e);
346 }
347
348 /**
349  * Mouse up event feed.
350  *
351  * @param e The given canvas pointer.
352  * @param b The button number.
353  * @param flags evas button flags.
354  * @param timestamp The timestamp of the mouse up event.
355  * @param data The data for canvas.
356  *
357  * This function will set some evas properties that is necessary when
358  * the mouse button is released. It prepares information to be treated
359  * by the callback function.
360  *
361  */
362 EAPI void
363 evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int timestamp, const void *data)
364 {
365    Eina_List *l, *copy;
366
367    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
368    return;
369    MAGIC_CHECK_END();
370
371    if ((b < 1) || (b > 32)) return;
372
373    e->pointer.button &= ~(1 << (b - 1));
374
375    if (e->events_frozen > 0) return;
376    e->last_timestamp = timestamp;
377
378      {
379         Evas_Event_Mouse_Up ev;
380         Evas_Object *obj;
381
382         _evas_object_event_new();
383
384         ev.button = b;
385         ev.output.x = e->pointer.x;
386         ev.output.y = e->pointer.y;
387         ev.canvas.x = e->pointer.x;
388         ev.canvas.y = e->pointer.y;
389         ev.data = (void *)data;
390         ev.modifiers = &(e->modifiers);
391         ev.locks = &(e->locks);
392         ev.flags = flags;
393         ev.timestamp = timestamp;
394         ev.event_flags = EVAS_EVENT_FLAG_NONE;
395
396         _evas_walk(e);
397         copy = evas_event_list_copy(e->pointer.object.in);
398         EINA_LIST_FOREACH(copy, l, obj)
399           {
400              ev.canvas.x = e->pointer.x;
401              ev.canvas.y = e->pointer.y;
402              _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y);
403              if ((obj->pointer_mode != EVAS_OBJECT_POINTER_MODE_NOGRAB) &&
404                  (obj->mouse_in) && (obj->mouse_grabbed > 0))
405                {
406                   obj->mouse_grabbed--;
407                   e->pointer.mouse_grabbed--;
408                }
409              if (!obj->delete_me)
410                {
411                   if (e->events_frozen <= 0)
412                      evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_UP, &ev);
413                }
414              if (e->delete_me) break;
415           }
416         if (copy) copy = eina_list_free(copy);
417         e->last_mouse_up_counter++;
418         _evas_post_event_callback_call(e);
419      }
420
421    if (!e->pointer.button)
422      {
423         Eina_List *ins;
424         Eina_List *l;
425           {
426              Evas_Event_Mouse_Out ev;
427              Evas_Object *obj;
428
429              _evas_object_event_new();
430
431              ev.buttons = e->pointer.button;
432              ev.output.x = e->pointer.x;
433              ev.output.y = e->pointer.y;
434              ev.canvas.x = e->pointer.x;
435              ev.canvas.y = e->pointer.y;
436              ev.data = (void *)data;
437              ev.modifiers = &(e->modifiers);
438              ev.locks = &(e->locks);
439              ev.timestamp = timestamp;
440              ev.event_flags = EVAS_EVENT_FLAG_NONE;
441
442              /* get new list of ins */
443              ins = evas_event_objects_event_list(e, NULL, e->pointer.x, e->pointer.y);
444              /* go thru old list of in objects */
445              copy = evas_event_list_copy(e->pointer.object.in);
446              EINA_LIST_FOREACH(copy, l, obj)
447                {
448                   ev.canvas.x = e->pointer.x;
449                   ev.canvas.y = e->pointer.y;
450                   _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y);
451                   if ((!eina_list_data_find(ins, obj)) ||
452                       (!e->pointer.inside))
453                     {
454                        obj->mouse_in = 0;
455                        if (e->events_frozen <= 0)
456                          evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_OUT, &ev);
457                     }
458                   if (e->delete_me) break;
459                }
460              _evas_post_event_callback_call(e);
461           }
462         if (copy) copy = eina_list_free(copy);
463         if (e->pointer.inside)
464           {
465              Evas_Event_Mouse_In ev;
466              Evas_Object *obj;
467
468              _evas_object_event_new();
469
470              ev.buttons = e->pointer.button;
471              ev.output.x = e->pointer.x;
472              ev.output.y = e->pointer.y;
473              ev.canvas.x = e->pointer.x;
474              ev.canvas.y = e->pointer.y;
475              ev.data = (void *)data;
476              ev.modifiers = &(e->modifiers);
477              ev.locks = &(e->locks);
478              ev.timestamp = timestamp;
479              ev.event_flags = EVAS_EVENT_FLAG_NONE;
480
481              EINA_LIST_FOREACH(ins, l, obj)
482                {
483                   ev.canvas.x = e->pointer.x;
484                   ev.canvas.y = e->pointer.y;
485                   _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y);
486                   if (!eina_list_data_find(e->pointer.object.in, obj))
487                     {
488                        obj->mouse_in = 1;
489                        if (e->events_frozen <= 0)
490                          evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_IN, &ev);
491                     }
492                   if (e->delete_me) break;
493                }
494              _evas_post_event_callback_call(e);
495           }
496         else
497           {
498              ins = eina_list_free(ins);
499           }
500         /* free our old list of ins */
501         e->pointer.object.in = eina_list_free(e->pointer.object.in);
502         /* and set up the new one */
503         e->pointer.object.in = ins;
504         if (e->pointer.inside)
505           evas_event_feed_mouse_move(e, e->pointer.x, e->pointer.y, timestamp, data);
506      }
507
508    if (e->pointer.mouse_grabbed < 0)
509      {
510         ERR("BUG? e->pointer.mouse_grabbed (=%d) < 0!",
511               e->pointer.mouse_grabbed);
512      }
513
514    if ((e->pointer.button == 0) && (e->pointer.mouse_grabbed != 0))
515      {
516         INF("restore to 0 grabs (from %i)", e->pointer.mouse_grabbed);
517         e->pointer.mouse_grabbed = 0;
518      }
519    _evas_unwalk(e);
520 }
521
522
523 /**
524  * Mouse cancel event feed.
525  *
526  * @param e The given canvas pointer.
527  * @param timestamp The timestamp of the mouse up event.
528  * @param data The data for canvas.
529  *
530  * This function will call evas_event_feed_mouse_up() when a
531  * mouse cancel event happens.
532  *
533  */
534 EAPI void
535 evas_event_feed_mouse_cancel(Evas *e, unsigned int timestamp, const void *data)
536 {
537    int i;
538
539    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
540    return;
541    MAGIC_CHECK_END();
542
543    if (e->events_frozen > 0) return;
544
545    _evas_walk(e);
546    for (i = 0; i < 32; i++)
547      {
548         if ((e->pointer.button & (1 << i)))
549           evas_event_feed_mouse_up(e, i + 1, 0, timestamp, data);
550      }
551    _evas_unwalk(e);
552 }
553
554 /**
555  * Mouse wheel event feed.
556  *
557  * @param e The given canvas pointer.
558  * @param direction The wheel mouse direction.
559  * @param z How much mouse wheel was scrolled up or down.
560  * @param timestamp The timestamp of the mouse up event.
561  * @param data The data for canvas.
562  *
563  * This function will set some evas properties that is necessary when
564  * the mouse wheel is scrolled up or down. It prepares information to
565  * be treated by the callback function.
566  *
567  */
568 EAPI void
569 evas_event_feed_mouse_wheel(Evas *e, int direction, int z, unsigned int timestamp, const void *data)
570 {
571    Eina_List *l, *copy;
572    Evas_Event_Mouse_Wheel ev;
573    Evas_Object *obj;
574
575    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
576    return;
577    MAGIC_CHECK_END();
578
579    if (e->events_frozen > 0) return;
580    e->last_timestamp = timestamp;
581
582    _evas_object_event_new();
583
584    ev.direction = direction;
585    ev.z = z;
586    ev.output.x = e->pointer.x;
587    ev.output.y = e->pointer.y;
588    ev.canvas.x = e->pointer.x;
589    ev.canvas.y = e->pointer.y;
590    ev.data = (void *) data;
591    ev.modifiers = &(e->modifiers);
592    ev.locks = &(e->locks);
593    ev.timestamp = timestamp;
594    ev.event_flags = EVAS_EVENT_FLAG_NONE;
595
596    _evas_walk(e);
597    copy = evas_event_list_copy(e->pointer.object.in);
598
599    EINA_LIST_FOREACH(copy, l, obj)
600      {
601         ev.canvas.x = e->pointer.x;
602         ev.canvas.y = e->pointer.y;
603         _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y);
604         if (e->events_frozen <= 0)
605           evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_WHEEL, &ev);
606         if (e->delete_me) break;
607      }
608    if (copy) copy = eina_list_free(copy);
609    _evas_post_event_callback_call(e);
610
611    _evas_unwalk(e);
612 }
613
614 /**
615  * Mouse move event feed.
616  *
617  * @param e The given canvas pointer.
618  * @param x The horizontal position of the mouse pointer.
619  * @param y The vertical position of the mouse pointer.
620  * @param timestamp The timestamp of the mouse up event.
621  * @param data The data for canvas.
622  *
623  * This function will set some evas properties that is necessary when
624  * the mouse is moved from its last position. It prepares information
625  * to be treated by the callback function.
626  *
627  */
628 EAPI void
629 evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const void *data)
630 {
631    int px, py;
632 ////   Evas_Coord pcx, pcy;
633
634    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
635    return;
636    MAGIC_CHECK_END();
637
638    px = e->pointer.x;
639    py = e->pointer.y;
640 ////   pcx = e->pointer.canvas_x;
641 ////   pcy = e->pointer.canvas_y;
642
643    if (e->events_frozen > 0) return;
644    e->last_timestamp = timestamp;
645
646    e->pointer.x = x;
647    e->pointer.y = y;
648 ////   e->pointer.canvas_x = x;
649 ////   e->pointer.canvas_y = y;
650 ////   e->pointer.canvas_x = evas_coord_screen_x_to_world(e, x);
651 ////   e->pointer.canvas_y = evas_coord_screen_y_to_world(e, y);
652    if ((!e->pointer.inside) && (e->pointer.mouse_grabbed == 0)) return;
653    _evas_walk(e);
654    /* if our mouse button is grabbed to any objects */
655    if (e->pointer.mouse_grabbed > 0)
656      {
657         /* go thru old list of in objects */
658         Eina_List *outs = NULL;
659         Eina_List *l, *copy;
660
661           {
662              Evas_Event_Mouse_Move ev;
663              Evas_Object *obj;
664
665              _evas_object_event_new();
666
667              ev.buttons = e->pointer.button;
668              ev.cur.output.x = e->pointer.x;
669              ev.cur.output.y = e->pointer.y;
670              ev.cur.canvas.x = e->pointer.x;
671              ev.cur.canvas.y = e->pointer.y;
672              ev.prev.output.x = px;
673              ev.prev.output.y = py;
674              ev.prev.canvas.x = px;
675              ev.prev.canvas.y = py;
676              ev.data = (void *)data;
677              ev.modifiers = &(e->modifiers);
678              ev.locks = &(e->locks);
679              ev.timestamp = timestamp;
680              ev.event_flags = EVAS_EVENT_FLAG_NONE;
681              copy = evas_event_list_copy(e->pointer.object.in);
682              EINA_LIST_FOREACH(copy, l, obj)
683                {
684                   ev.cur.canvas.x = e->pointer.x;
685                   ev.cur.canvas.y = e->pointer.y;
686                   _evas_event_havemap_adjust(obj, &ev.cur.canvas.x, &ev.cur.canvas.y);
687                   if ((obj->cur.visible) &&
688                       (evas_object_clippers_is_visible(obj)) &&
689                       (!evas_event_passes_through(obj)) &&
690                       (!obj->clip.clipees))
691                     {
692                        if ((px != x) || (py != y))
693                          {
694                             if (e->events_frozen <= 0)
695                               evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_MOVE, &ev);
696                          }
697                     }
698                   else
699                     outs = eina_list_append(outs, obj);
700                   if (e->delete_me) break;
701                }
702              _evas_post_event_callback_call(e);
703           }
704           {
705              Evas_Event_Mouse_Out ev;
706
707              _evas_object_event_new();
708
709              ev.buttons = e->pointer.button;
710              ev.output.x = e->pointer.x;
711              ev.output.y = e->pointer.y;
712              ev.canvas.x = e->pointer.x;
713              ev.canvas.y = e->pointer.y;
714              ev.data = (void *)data;
715              ev.modifiers = &(e->modifiers);
716              ev.locks = &(e->locks);
717              ev.timestamp = timestamp;
718              ev.event_flags = EVAS_EVENT_FLAG_NONE;
719
720              if (copy) copy = eina_list_free(copy);
721              while (outs)
722                {
723                   Evas_Object *obj;
724
725                   obj = outs->data;
726                   outs = eina_list_remove(outs, obj);
727                   if ((obj->mouse_grabbed == 0) && (!e->delete_me))
728                     {
729                        ev.canvas.x = e->pointer.x;
730                        ev.canvas.y = e->pointer.y;
731                        _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y);
732                        e->pointer.object.in = eina_list_remove(e->pointer.object.in, obj);
733                        obj->mouse_in = 0;
734                        if (!obj->delete_me)
735                          {
736                             if (e->events_frozen <= 0)
737                                evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_OUT, &ev);
738                          }
739                     }
740                }
741              _evas_post_event_callback_call(e);
742           }
743      }
744    else
745      {
746         Eina_List *ins;
747         Eina_List *l, *copy;
748         Evas_Event_Mouse_Move ev;
749         Evas_Event_Mouse_Out ev2;
750         Evas_Event_Mouse_In ev3;
751         Evas_Object *obj;
752
753         _evas_object_event_new();
754
755         ev.buttons = e->pointer.button;
756         ev.cur.output.x = e->pointer.x;
757         ev.cur.output.y = e->pointer.y;
758         ev.cur.canvas.x = e->pointer.x;
759         ev.cur.canvas.y = e->pointer.y;
760         ev.prev.output.x = px;
761         ev.prev.output.y = py;
762         ev.prev.canvas.x = px;
763         ev.prev.canvas.y = py;
764         ev.data = (void *)data;
765         ev.modifiers = &(e->modifiers);
766         ev.locks = &(e->locks);
767         ev.timestamp = timestamp;
768         ev.event_flags = EVAS_EVENT_FLAG_NONE;
769
770         ev2.buttons = e->pointer.button;
771         ev2.output.x = e->pointer.x;
772         ev2.output.y = e->pointer.y;
773         ev2.canvas.x = e->pointer.x;
774         ev2.canvas.y = e->pointer.y;
775         ev2.data = (void *)data;
776         ev2.modifiers = &(e->modifiers);
777         ev2.locks = &(e->locks);
778         ev2.timestamp = timestamp;
779         ev2.event_flags = EVAS_EVENT_FLAG_NONE;
780
781         ev3.buttons = e->pointer.button;
782         ev3.output.x = e->pointer.x;
783         ev3.output.y = e->pointer.y;
784         ev3.canvas.x = e->pointer.x;
785         ev3.canvas.y = e->pointer.y;
786         ev3.data = (void *)data;
787         ev3.modifiers = &(e->modifiers);
788         ev3.locks = &(e->locks);
789         ev3.timestamp = timestamp;
790         ev3.event_flags = EVAS_EVENT_FLAG_NONE;
791
792         /* get all new in objects */
793         ins = evas_event_objects_event_list(e, NULL, x, y);
794         /* go thru old list of in objects */
795         copy = evas_event_list_copy(e->pointer.object.in);
796         EINA_LIST_FOREACH(copy, l, obj)
797           {
798              /* if its under the pointer and its visible and its in the new */
799              /* in list */
800 // FIXME: i don't think we need this
801 //           evas_object_clip_recalc(obj);
802              if (evas_object_is_in_output_rect(obj, x, y, 1, 1) &&
803                  (obj->cur.visible) &&
804                  (evas_object_clippers_is_visible(obj)) &&
805                  (eina_list_data_find(ins, obj)) &&
806                  (!evas_event_passes_through(obj)) &&
807                  (!obj->clip.clipees) &&
808                  ((!obj->precise_is_inside) ||
809                   (evas_object_is_inside(obj, x, y))))
810                {
811                   if ((px != x) || (py != y))
812                     {
813                        ev.cur.canvas.x = e->pointer.x;
814                        ev.cur.canvas.y = e->pointer.y;
815                        _evas_event_havemap_adjust(obj, &ev.cur.canvas.x, &ev.cur.canvas.y);
816                        if (e->events_frozen <= 0)
817                          evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_MOVE, &ev);
818                     }
819                }
820              /* otherwise it has left the object */
821              else
822                {
823                   obj->mouse_in = 0;
824                   ev2.canvas.x = e->pointer.x;
825                   ev2.canvas.y = e->pointer.y;
826                   _evas_event_havemap_adjust(obj, &ev2.canvas.x, &ev2.canvas.y);
827                   if (e->events_frozen <= 0)
828                     evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_OUT, &ev2);
829                }
830              if (e->delete_me) break;
831           }
832         _evas_post_event_callback_call(e);
833
834         _evas_object_event_new();
835
836         if (copy) copy = eina_list_free(copy);
837         /* go thru our current list of ins */
838         EINA_LIST_FOREACH(ins, l, obj)
839           {
840              ev3.canvas.x = e->pointer.x;
841              ev3.canvas.y = e->pointer.y;
842              _evas_event_havemap_adjust(obj, &ev3.canvas.x, &ev3.canvas.y);
843              /* if its not in the old list of ins send an enter event */
844              if (!eina_list_data_find(e->pointer.object.in, obj))
845                {
846                   obj->mouse_in = 1;
847                   if (e->events_frozen <= 0)
848                     evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_IN, &ev3);
849                }
850              if (e->delete_me) break;
851           }
852         /* free our old list of ins */
853         eina_list_free(e->pointer.object.in);
854         /* and set up the new one */
855         e->pointer.object.in = ins;
856         _evas_post_event_callback_call(e);
857      }
858    _evas_unwalk(e);
859 }
860
861 /**
862  * Mouse in event feed.
863  *
864  * @param e The given canvas pointer.
865  * @param timestamp The timestamp of the mouse up event.
866  * @param data The data for canvas.
867  *
868  * This function will set some evas properties that is necessary when
869  * the mouse in event happens. It prepares information to be treated
870  * by the callback function.
871  *
872  */
873 EAPI void
874 evas_event_feed_mouse_in(Evas *e, unsigned int timestamp, const void *data)
875 {
876    Eina_List *ins;
877    Eina_List *l;
878    Evas_Event_Mouse_In ev;
879    Evas_Object *obj;
880
881    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
882    return;
883    MAGIC_CHECK_END();
884    e->pointer.inside = 1;
885
886    if (e->events_frozen > 0) return;
887    e->last_timestamp = timestamp;
888
889    if (e->pointer.mouse_grabbed != 0) return;
890
891    _evas_object_event_new();
892
893    ev.buttons = e->pointer.button;
894    ev.output.x = e->pointer.x;
895    ev.output.y = e->pointer.y;
896    ev.canvas.x = e->pointer.x;
897    ev.canvas.y = e->pointer.y;
898    ev.data = (void *)data;
899    ev.modifiers = &(e->modifiers);
900    ev.locks = &(e->locks);
901    ev.timestamp = timestamp;
902    ev.event_flags = EVAS_EVENT_FLAG_NONE;
903
904    _evas_walk(e);
905    /* get new list of ins */
906    ins = evas_event_objects_event_list(e, NULL, e->pointer.x, e->pointer.y);
907    EINA_LIST_FOREACH(ins, l, obj)
908      {
909         ev.canvas.x = e->pointer.x;
910         ev.canvas.y = e->pointer.y;
911         _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y);
912         if (!eina_list_data_find(e->pointer.object.in, obj))
913           {
914              obj->mouse_in = 1;
915              if (e->events_frozen <= 0)
916                evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_IN, &ev);
917           }
918         if (e->delete_me) break;
919      }
920    /* free our old list of ins */
921    e->pointer.object.in = eina_list_free(e->pointer.object.in);
922    /* and set up the new one */
923    e->pointer.object.in = ins;
924    _evas_post_event_callback_call(e);
925    evas_event_feed_mouse_move(e, e->pointer.x, e->pointer.y, timestamp, data);
926    _evas_unwalk(e);
927 }
928
929 /**
930  * Mouse out event feed.
931  *
932  * @param e The given canvas pointer.
933  * @param timestamp Timestamp of the mouse up event.
934  * @param data The data for canvas.
935  *
936  * This function will set some evas properties that is necessary when
937  * the mouse out event happens. It prepares information to be treated
938  * by the callback function.
939  *
940  */
941 EAPI void
942 evas_event_feed_mouse_out(Evas *e, unsigned int timestamp, const void *data)
943 {
944    Evas_Event_Mouse_Out ev;
945
946    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
947    return;
948    MAGIC_CHECK_END();
949    e->pointer.inside = 0;
950
951    if (e->events_frozen > 0) return;
952    e->last_timestamp = timestamp;
953
954    _evas_object_event_new();
955
956    ev.buttons = e->pointer.button;
957    ev.output.x = e->pointer.x;
958    ev.output.y = e->pointer.y;
959    ev.canvas.x = e->pointer.x;
960    ev.canvas.y = e->pointer.y;
961    ev.data = (void *)data;
962    ev.modifiers = &(e->modifiers);
963    ev.locks = &(e->locks);
964    ev.timestamp = timestamp;
965    ev.event_flags = EVAS_EVENT_FLAG_NONE;
966
967    _evas_walk(e);
968    /* if our mouse button is grabbed to any objects */
969    if (e->pointer.mouse_grabbed == 0)
970      {
971         /* go thru old list of in objects */
972         Eina_List *l, *copy;
973         Evas_Object *obj;
974
975         copy = evas_event_list_copy(e->pointer.object.in);
976         EINA_LIST_FOREACH(copy, l, obj)
977           {
978              ev.canvas.x = e->pointer.x;
979              ev.canvas.y = e->pointer.y;
980              _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y);
981              obj->mouse_in = 0;
982              if (!obj->delete_me)
983                {
984                   if (e->events_frozen <= 0)
985                      evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_OUT, &ev);
986                }
987             if (e->delete_me) break;
988           }
989         if (copy) copy = eina_list_free(copy);
990         /* free our old list of ins */
991         e->pointer.object.in =  eina_list_free(e->pointer.object.in);
992         _evas_post_event_callback_call(e);
993      }
994    _evas_unwalk(e);
995 }
996
997 EAPI void
998 evas_event_feed_multi_down(Evas *e, 
999                            int d, int x, int y, 
1000                            double rad, double radx, double rady,
1001                            double pres, double ang,
1002                            double fx, double fy,
1003                            Evas_Button_Flags flags, unsigned int timestamp, 
1004                            const void *data)
1005 {
1006    Eina_List *l, *copy;
1007    Evas_Event_Multi_Down ev;
1008    Evas_Object *obj;
1009
1010    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
1011    return;
1012    MAGIC_CHECK_END();
1013
1014    if (e->events_frozen > 0) return;
1015    e->last_timestamp = timestamp;
1016
1017    _evas_object_event_new();
1018
1019    ev.device = d;
1020    ev.output.x = x;
1021    ev.output.y = y;
1022    ev.canvas.x = x;
1023    ev.canvas.y = y;
1024    ev.radius = rad;
1025    ev.radius_x = radx;
1026    ev.radius_y = rady;
1027    ev.pressure = pres;
1028    ev.angle = ang;
1029    ev.canvas.xsub = fx;
1030    ev.canvas.ysub = fy;
1031    ev.data = (void *)data;
1032    ev.modifiers = &(e->modifiers);
1033    ev.locks = &(e->locks);
1034    ev.flags = flags;
1035    ev.timestamp = timestamp;
1036    ev.event_flags = EVAS_EVENT_FLAG_NONE;
1037
1038    _evas_walk(e);
1039    copy = evas_event_list_copy(e->pointer.object.in);
1040    EINA_LIST_FOREACH(copy, l, obj)
1041      {
1042         ev.canvas.x = x;
1043         ev.canvas.y = y;
1044         ev.canvas.xsub = fx;
1045         ev.canvas.ysub = fy;
1046         _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y);
1047         if (x != ev.canvas.x) 
1048           ev.canvas.xsub = ev.canvas.x; // fixme - lost precision
1049         if (y != ev.canvas.y)
1050           ev.canvas.ysub = ev.canvas.y; // fixme - lost precision
1051         if (e->events_frozen <= 0)
1052           evas_object_event_callback_call(obj, EVAS_CALLBACK_MULTI_DOWN, &ev);
1053         if (e->delete_me) break;
1054      }
1055    if (copy) eina_list_free(copy);
1056    _evas_post_event_callback_call(e);
1057    _evas_unwalk(e);
1058 }
1059
1060 EAPI void
1061 evas_event_feed_multi_up(Evas *e, 
1062                          int d, int x, int y, 
1063                          double rad, double radx, double rady,
1064                          double pres, double ang,
1065                          double fx, double fy,
1066                          Evas_Button_Flags flags, unsigned int timestamp, 
1067                          const void *data)
1068 {
1069    Eina_List *l, *copy;
1070    Evas_Event_Multi_Up ev;
1071    Evas_Object *obj;
1072
1073    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
1074    return;
1075    MAGIC_CHECK_END();
1076
1077    if (e->events_frozen > 0) return;
1078    e->last_timestamp = timestamp;
1079
1080    _evas_object_event_new();
1081
1082    ev.device = d;
1083    ev.output.x = x;
1084    ev.output.y = y;
1085    ev.canvas.x = x;
1086    ev.canvas.y = y;
1087    ev.radius = rad;
1088    ev.radius_x = radx;
1089    ev.radius_y = rady;
1090    ev.pressure = pres;
1091    ev.angle = ang;
1092    ev.canvas.xsub = fx;
1093    ev.canvas.ysub = fy;
1094    ev.data = (void *)data;
1095    ev.modifiers = &(e->modifiers);
1096    ev.locks = &(e->locks);
1097    ev.flags = flags;
1098    ev.timestamp = timestamp;
1099    ev.event_flags = EVAS_EVENT_FLAG_NONE;
1100    
1101    _evas_walk(e);
1102    copy = evas_event_list_copy(e->pointer.object.in);
1103    EINA_LIST_FOREACH(copy, l, obj)
1104      {
1105         ev.canvas.x = x;
1106         ev.canvas.y = y;
1107         ev.canvas.xsub = fx;
1108         ev.canvas.ysub = fy;
1109         _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y);
1110         if (x != ev.canvas.x) 
1111           ev.canvas.xsub = ev.canvas.x; // fixme - lost precision
1112         if (y != ev.canvas.y)
1113           ev.canvas.ysub = ev.canvas.y; // fixme - lost precision
1114         if (e->events_frozen <= 0)
1115           evas_object_event_callback_call(obj, EVAS_CALLBACK_MULTI_UP, &ev);
1116         if (e->delete_me) break;
1117      }
1118    if (copy) copy = eina_list_free(copy);
1119    _evas_post_event_callback_call(e);
1120    _evas_unwalk(e);
1121 }
1122
1123 EAPI void
1124 evas_event_feed_multi_move(Evas *e, 
1125                            int d, int x, int y, 
1126                            double rad, double radx, double rady,
1127                            double pres, double ang,
1128                            double fx, double fy,
1129                            unsigned int timestamp, const void *data)
1130 {
1131    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
1132    return;
1133    MAGIC_CHECK_END();
1134
1135    if (e->events_frozen > 0) return;
1136    e->last_timestamp = timestamp;
1137
1138    if (!e->pointer.inside) return;
1139    
1140    _evas_walk(e);
1141    /* if our mouse button is grabbed to any objects */
1142    if (e->pointer.mouse_grabbed > 0)
1143      {
1144         /* go thru old list of in objects */
1145         Eina_List *l, *copy;
1146         Evas_Event_Multi_Move ev;
1147         Evas_Object *obj;
1148
1149         _evas_object_event_new();
1150
1151         ev.device = d;
1152         ev.cur.output.x = x;
1153         ev.cur.output.y = y;
1154         ev.cur.canvas.x = x;
1155         ev.cur.canvas.y = y;
1156         ev.radius = rad;
1157         ev.radius_x = radx;
1158         ev.radius_y = rady;
1159         ev.pressure = pres;
1160         ev.angle = ang;
1161         ev.cur.canvas.xsub = fx;
1162         ev.cur.canvas.ysub = fy;
1163         ev.data = (void *)data;
1164         ev.modifiers = &(e->modifiers);
1165         ev.locks = &(e->locks);
1166         ev.timestamp = timestamp;
1167         ev.event_flags = EVAS_EVENT_FLAG_NONE;
1168
1169         copy = evas_event_list_copy(e->pointer.object.in);
1170         EINA_LIST_FOREACH(copy, l, obj)
1171           {
1172              if ((obj->cur.visible) &&
1173                  (evas_object_clippers_is_visible(obj)) &&
1174                  (!evas_event_passes_through(obj)) &&
1175                  (!obj->clip.clipees))
1176                {
1177                   ev.cur.canvas.x = x;
1178                   ev.cur.canvas.y = y;
1179                   ev.cur.canvas.xsub = fx;
1180                   ev.cur.canvas.ysub = fy;
1181                   _evas_event_havemap_adjust(obj, &ev.cur.canvas.x, &ev.cur.canvas.y);
1182                   if (x != ev.cur.canvas.x) 
1183                     ev.cur.canvas.xsub = ev.cur.canvas.x; // fixme - lost precision
1184                   if (y != ev.cur.canvas.y)
1185                     ev.cur.canvas.ysub = ev.cur.canvas.y; // fixme - lost precision
1186                   if (e->events_frozen <= 0)
1187                     evas_object_event_callback_call(obj, EVAS_CALLBACK_MULTI_MOVE, &ev);
1188                }
1189              if (e->delete_me) break;
1190           }
1191         _evas_post_event_callback_call(e);
1192      }
1193    else
1194      {
1195         Eina_List *ins;
1196         Eina_List *l, *copy;
1197         Evas_Event_Multi_Move ev;
1198         Evas_Object *obj;
1199
1200         _evas_object_event_new();
1201
1202         ev.device = d;
1203         ev.cur.output.x = x;
1204         ev.cur.output.y = y;
1205         ev.cur.canvas.x = x;
1206         ev.cur.canvas.y = y;
1207         ev.radius = rad;
1208         ev.radius_x = radx;
1209         ev.radius_y = rady;
1210         ev.pressure = pres;
1211         ev.angle = ang;
1212         ev.cur.canvas.xsub = fx;
1213         ev.cur.canvas.ysub = fy;
1214         ev.data = (void *)data;
1215         ev.modifiers = &(e->modifiers);
1216         ev.locks = &(e->locks);
1217         ev.timestamp = timestamp;
1218         ev.event_flags = EVAS_EVENT_FLAG_NONE;
1219         
1220         /* get all new in objects */
1221         ins = evas_event_objects_event_list(e, NULL, x, y);
1222         /* go thru old list of in objects */
1223         copy = evas_event_list_copy(e->pointer.object.in);
1224         EINA_LIST_FOREACH(copy, l, obj)
1225           {
1226              /* if its under the pointer and its visible and its in the new */
1227              /* in list */
1228 // FIXME: i don't think we need this
1229 //           evas_object_clip_recalc(obj);
1230              if (evas_object_is_in_output_rect(obj, x, y, 1, 1) &&
1231                  (obj->cur.visible) &&
1232                  (evas_object_clippers_is_visible(obj)) &&
1233                  (eina_list_data_find(ins, obj)) &&
1234                  (!evas_event_passes_through(obj)) &&
1235                  (!obj->clip.clipees) &&
1236                  ((!obj->precise_is_inside) ||
1237                   (evas_object_is_inside(obj, x, y))))
1238                {
1239                   ev.cur.canvas.x = x;
1240                   ev.cur.canvas.y = y;
1241                   ev.cur.canvas.xsub = fx;
1242                   ev.cur.canvas.ysub = fy;
1243                   _evas_event_havemap_adjust(obj, &ev.cur.canvas.x, &ev.cur.canvas.y);
1244                   if (x != ev.cur.canvas.x) 
1245                     ev.cur.canvas.xsub = ev.cur.canvas.x; // fixme - lost precision
1246                   if (y != ev.cur.canvas.y)
1247                     ev.cur.canvas.ysub = ev.cur.canvas.y; // fixme - lost precision
1248                   if (e->events_frozen <= 0)
1249                     evas_object_event_callback_call(obj, EVAS_CALLBACK_MULTI_MOVE, &ev);
1250                }
1251              if (e->delete_me) break;
1252           }
1253         if (copy) copy = eina_list_free(copy);
1254         /* free our old list of ins */
1255         eina_list_free(e->pointer.object.in);
1256         /* and set up the new one */
1257         e->pointer.object.in = ins;
1258         _evas_post_event_callback_call(e);
1259      }
1260    _evas_unwalk(e);
1261 }
1262
1263 /**
1264  * Key down event feed
1265  *
1266  * @param e The canvas to thaw out
1267  * @param keyname  Name of the key
1268  * @param key The key pressed.
1269  * @param string A String
1270  * @param compose The compose string
1271  * @param timestamp Timestamp of the mouse up event
1272  * @param data Data for canvas.
1273  *
1274  * This function will set some evas properties that is necessary when
1275  * a key is pressed. It prepares information to be treated by the
1276  * callback function.
1277  *
1278  */
1279 EAPI void
1280 evas_event_feed_key_down(Evas *e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data)
1281 {
1282    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
1283    return;
1284    MAGIC_CHECK_END();
1285    if (!keyname) return;
1286    if (e->events_frozen > 0) return;
1287    e->last_timestamp = timestamp;
1288    _evas_walk(e);
1289      {
1290         Evas_Event_Key_Down ev;
1291         int exclusive;
1292
1293         _evas_object_event_new();
1294
1295         exclusive = 0;
1296         ev.keyname = (char *)keyname;
1297         ev.data = (void *)data;
1298         ev.modifiers = &(e->modifiers);
1299         ev.locks = &(e->locks);
1300         ev.key = key;
1301         ev.string = string;
1302         ev.compose = compose;
1303         ev.timestamp = timestamp;
1304         ev.event_flags = EVAS_EVENT_FLAG_NONE;
1305         if (e->grabs)
1306           {
1307              Eina_List *l;
1308              Evas_Key_Grab *g;
1309
1310              e->walking_grabs++;
1311              EINA_LIST_FOREACH(e->grabs, l, g)
1312                {
1313                   if (g->just_added)
1314                     {
1315                        g->just_added = 0;
1316                        continue;
1317                     }
1318                   if (g->delete_me) continue;
1319                   if (((e->modifiers.mask & g->modifiers) ||
1320                        (g->modifiers == e->modifiers.mask)) &&
1321                       (!strcmp(keyname, g->keyname)))
1322                     {
1323                        if (!(e->modifiers.mask & g->not_modifiers))
1324                          {
1325                             if (e->events_frozen <= 0)
1326                               evas_object_event_callback_call(g->object, EVAS_CALLBACK_KEY_DOWN, &ev);
1327                             if (g->exclusive) exclusive = 1;
1328                          }
1329                     }
1330                   if (e->delete_me) break;
1331                }
1332              e->walking_grabs--;
1333              if (e->walking_grabs <= 0)
1334                {
1335                   while (e->delete_grabs > 0)
1336                     {
1337                        e->delete_grabs--;
1338                        for (l = e->grabs; l;)
1339                          {
1340                             g = eina_list_data_get(l);
1341                             l = eina_list_next(l);
1342                             if (g->delete_me)
1343                               evas_key_grab_free(g->object, g->keyname, g->modifiers, g->not_modifiers);
1344                          }
1345                     }
1346                }
1347           }
1348         if ((e->focused) && (!exclusive))
1349           {
1350              if (e->events_frozen <= 0)
1351                evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_DOWN, &ev);
1352           }
1353         _evas_post_event_callback_call(e);
1354      }
1355    _evas_unwalk(e);
1356 }
1357
1358 /**
1359  * Key up event feed
1360  *
1361  * @param e The canvas to thaw out
1362  * @param keyname  Name of the key
1363  * @param key The key released.
1364  * @param string string
1365  * @param compose compose
1366  * @param timestamp Timestamp of the mouse up event
1367  * @param data Data for canvas.
1368  *
1369  * This function will set some evas properties that is necessary when
1370  * a key is released. It prepares information to be treated by the
1371  * callback function.
1372  *
1373  */
1374 EAPI void
1375 evas_event_feed_key_up(Evas *e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data)
1376 {
1377    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
1378    return;
1379    MAGIC_CHECK_END();
1380    if (!keyname) return;
1381    if (e->events_frozen > 0) return;
1382    e->last_timestamp = timestamp;
1383    _evas_walk(e);
1384      {
1385         Evas_Event_Key_Up ev;
1386         int exclusive;
1387
1388         _evas_object_event_new();
1389
1390         exclusive = 0;
1391         ev.keyname = (char *)keyname;
1392         ev.data = (void *)data;
1393         ev.modifiers = &(e->modifiers);
1394         ev.locks = &(e->locks);
1395         ev.key = key;
1396         ev.string = string;
1397         ev.compose = compose;
1398         ev.timestamp = timestamp;
1399         ev.event_flags = EVAS_EVENT_FLAG_NONE;
1400         if (e->grabs)
1401           {
1402              Eina_List *l;
1403              Evas_Key_Grab *g;
1404
1405              e->walking_grabs++;
1406              EINA_LIST_FOREACH(e->grabs, l, g)
1407                {
1408                   if (g->just_added)
1409                     {
1410                        g->just_added = 0;
1411                        continue;
1412                     }
1413                   if (g->delete_me) continue;
1414                   if (((e->modifiers.mask & g->modifiers) ||
1415                        (g->modifiers == e->modifiers.mask)) &&
1416                       (!((e->modifiers.mask & g->not_modifiers) ||
1417                          (g->not_modifiers == ~e->modifiers.mask))) &&
1418                       (!strcmp(keyname, g->keyname)))
1419                     {
1420                        if (e->events_frozen <= 0)
1421                          evas_object_event_callback_call(g->object, EVAS_CALLBACK_KEY_UP, &ev);
1422                        if (g->exclusive) exclusive = 1;
1423                     }
1424                   if (e->delete_me) break;
1425                }
1426              e->walking_grabs--;
1427              if (e->walking_grabs <= 0)
1428                {
1429                   while (e->delete_grabs > 0)
1430                     {
1431                        Eina_List *l, *l_next;
1432                        Evas_Key_Grab *g;
1433
1434                        e->delete_grabs--;
1435                        EINA_LIST_FOREACH_SAFE(e->grabs, l, l_next, g)
1436                          {
1437                             if (g->delete_me)
1438                               evas_key_grab_free(g->object, g->keyname, g->modifiers, g->not_modifiers);
1439                          }
1440                     }
1441                }
1442           }
1443         if ((e->focused) && (!exclusive))
1444           {
1445              if (e->events_frozen <= 0)
1446                evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_UP, &ev);
1447           }
1448         _evas_post_event_callback_call(e);
1449      }
1450    _evas_unwalk(e);
1451 }
1452
1453 /**
1454  * Hold event feed
1455  *
1456  * @param e The given canvas pointer.
1457  * @param hold The hold.
1458  * @param timestamp The timestamp of the mouse up event.
1459  * @param data The data for canvas.
1460  *
1461  * This function makes the object to stop sending events.
1462  *
1463  */
1464 EAPI void
1465 evas_event_feed_hold(Evas *e, int hold, unsigned int timestamp, const void *data)
1466 {
1467    Eina_List *l, *copy;
1468    Evas_Event_Hold ev;
1469    Evas_Object *obj;
1470
1471    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
1472    return;
1473    MAGIC_CHECK_END();
1474
1475    if (e->events_frozen > 0) return;
1476    e->last_timestamp = timestamp;
1477
1478    _evas_object_event_new();
1479
1480    ev.hold = hold;
1481    ev.data = (void *)data;
1482    ev.timestamp = timestamp;
1483    ev.event_flags = EVAS_EVENT_FLAG_NONE;
1484
1485    _evas_walk(e);
1486    copy = evas_event_list_copy(e->pointer.object.in);
1487    EINA_LIST_FOREACH(copy, l, obj)
1488      {
1489         if (e->events_frozen <= 0)
1490           evas_object_event_callback_call(obj, EVAS_CALLBACK_HOLD, &ev);
1491         if (e->delete_me) break;
1492      }
1493    if (copy) copy = eina_list_free(copy);
1494    _evas_post_event_callback_call(e);
1495    _evas_unwalk(e);
1496    _evas_object_event_new();
1497 }
1498
1499 /**
1500  * @}
1501  */
1502
1503 /**
1504  * @addtogroup Evas_Object_Group_Events
1505  * @{
1506  */
1507
1508 /**
1509  * Set an object's pass events state.
1510  * @param obj the evas object
1511  * @param pass whether to pass events or not
1512  *
1513  * If @p pass is true, this will cause events on @p obj to be ignored.
1514  * They will be triggered on the next lower object (that is not set to
1515  * pass events) instead.
1516  *
1517  * If @p pass is false, events will be processed as normal.
1518  */
1519 EAPI void
1520 evas_object_pass_events_set(Evas_Object *obj, Eina_Bool pass)
1521 {
1522    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1523    return;
1524    MAGIC_CHECK_END();
1525    if (obj->pass_events == !!pass) return;
1526    obj->pass_events = pass;
1527    evas_object_smart_member_cache_invalidate(obj);
1528    if (evas_object_is_in_output_rect(obj,
1529                                      obj->layer->evas->pointer.x,
1530                                      obj->layer->evas->pointer.y, 1, 1) &&
1531        ((!obj->precise_is_inside) ||
1532         (evas_object_is_inside(obj,
1533                                obj->layer->evas->pointer.x,
1534                                obj->layer->evas->pointer.y))))
1535      evas_event_feed_mouse_move(obj->layer->evas,
1536                                 obj->layer->evas->pointer.x,
1537                                 obj->layer->evas->pointer.y,
1538                                 obj->layer->evas->last_timestamp,
1539                                 NULL);
1540 }
1541
1542 /**
1543  * Determine whether an object is set to pass events.
1544  * @param obj
1545  * @return pass events state
1546  */
1547 EAPI Eina_Bool
1548 evas_object_pass_events_get(const Evas_Object *obj)
1549 {
1550    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1551    return 0;
1552    MAGIC_CHECK_END();
1553    return obj->pass_events;
1554 }
1555
1556 /**
1557  * Set an object's repeat events state.
1558  * @param obj the object
1559  * @param repeat wheter to repeat events or not
1560  *
1561  * If @p repeat is true, this will cause events on @p obj to trigger
1562  * callbacks, but also to be repeated on the next lower object in the
1563  * stack.
1564  *
1565  * If @p repeat is false, events occuring on @p obj will be processed
1566  * normally.
1567  */
1568 EAPI void
1569 evas_object_repeat_events_set(Evas_Object *obj, Eina_Bool repeat)
1570 {
1571    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1572    return;
1573    MAGIC_CHECK_END();
1574    if (obj->repeat_events == !!repeat) return;
1575    obj->repeat_events = repeat;
1576    if (evas_object_is_in_output_rect(obj,
1577                                      obj->layer->evas->pointer.x,
1578                                      obj->layer->evas->pointer.y, 1, 1) &&
1579        ((!obj->precise_is_inside) ||
1580         (evas_object_is_inside(obj,
1581                                obj->layer->evas->pointer.x,
1582                                obj->layer->evas->pointer.y))))
1583      evas_event_feed_mouse_move(obj->layer->evas,
1584                                 obj->layer->evas->pointer.x,
1585                                 obj->layer->evas->pointer.y,
1586                                 obj->layer->evas->last_timestamp,
1587                                 NULL);
1588 }
1589
1590 /**
1591  * Determine whether an object is set to repeat events.
1592  * @param obj
1593  * @return repeat events state
1594  */
1595 EAPI Eina_Bool
1596 evas_object_repeat_events_get(const Evas_Object *obj)
1597 {
1598    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1599    return 0;
1600    MAGIC_CHECK_END();
1601    return obj->repeat_events;
1602 }
1603
1604 /**
1605  * Set whether events on a smart member object should propagate to its
1606  * parent.
1607  *
1608  * @param obj the smart member object
1609  * @param prop wheter to propagate events or not
1610  *
1611  * This function has no effect if @p obj is not a member of a smart
1612  * object.
1613  *
1614  * If @p prop is true, events occuring on this object will propagate on
1615  * to the smart object of which @p obj is a member.
1616  *
1617  * If @p prop is false, events for which callbacks are set on the member
1618  * object, @p obj, will not be passed on to the parent smart object.
1619  *
1620  * The default value is true.
1621  */
1622 EAPI void
1623 evas_object_propagate_events_set(Evas_Object *obj, Eina_Bool prop)
1624 {
1625    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1626    return;
1627    MAGIC_CHECK_END();
1628    obj->no_propagate = !prop;
1629 }
1630
1631 /**
1632  * Determine whether an object is set to propagate events.
1633  * @param obj
1634  * @return propogate events state
1635  */
1636 EAPI Eina_Bool
1637 evas_object_propagate_events_get(const Evas_Object *obj)
1638 {
1639    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1640    return 0;
1641    MAGIC_CHECK_END();
1642    return !(obj->no_propagate);
1643 }
1644
1645 /**
1646  * @}
1647  */
1648
1649 /**
1650  * Set pointer behavior.
1651  *
1652  * @param obj
1653  * @param setting desired behavior.
1654  *
1655  * This function has direct effect on event callbacks related to
1656  * mouse.
1657  *
1658  * If @p setting is EVAS_OBJECT_POINTER_MODE_AUTOGRAB, then when mouse
1659  * is down at this object, events will be restricted to it as source,
1660  * mouse moves, for example, will be emitted even if outside this
1661  * object area.
1662  *
1663  * If @p setting is EVAS_OBJECT_POINTER_MODE_NOGRAB, then events will
1664  * be emitted just when inside this object area.
1665  *
1666  * The default value is EVAS_OBJECT_POINTER_MODE_AUTOGRAB.
1667  *
1668  * @ingroup Evas_Object_Group_Extras
1669  */
1670 EAPI void
1671 evas_object_pointer_mode_set(Evas_Object *obj, Evas_Object_Pointer_Mode setting)
1672 {
1673    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1674    return;
1675    MAGIC_CHECK_END();
1676    obj->pointer_mode = setting;
1677 }
1678
1679 /**
1680  * Determine how pointer will behave.
1681  * @param obj
1682  * @return pointer behavior.
1683  * @ingroup Evas_Object_Group_Extras
1684  */
1685 EAPI Evas_Object_Pointer_Mode
1686 evas_object_pointer_mode_get(const Evas_Object *obj)
1687 {
1688    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1689    return 0;
1690    MAGIC_CHECK_END();
1691    return obj->pointer_mode;
1692 }