summaryrefslogtreecommitdiff
path: root/src/lib/ecore_input_evas
diff options
context:
space:
mode:
authorJi-Youn Park <jy0703.park@samsung.com>2015-06-16 15:33:43 +0900
committerJi-Youn Park <jy0703.park@samsung.com>2015-06-16 15:33:43 +0900
commit5cb6cdbc5e1a13ea0262e155983b494e6519abde (patch)
tree24a45ebca94d401e89cefa767ee81faf6564dada /src/lib/ecore_input_evas
parent0ee9a4ac63a116a5534d73f4df1f6b4507b23349 (diff)
Ecore_input: Add "ECORE_EVENT_MOUSE_BUTTON_CANCEL" event
If ecore get the mouse cancel event(ex: display off, or window stack change) from below, we need to deal with. Currently, evas also generates up event using evas_event_feed_mouse_cancel function when window hide is called. if cancel event occurs, ecore also call evas_event_mouse_feed_cancel like window hide situation. cancel event means all button or touch event should be canceled, but in the future, if we need to deal each cancel event according to touch point, we need to add api like evas_event_feed_multi_cancel @feature
Diffstat (limited to 'src/lib/ecore_input_evas')
-rw-r--r--src/lib/ecore_input_evas/Ecore_Input_Evas.h1
-rw-r--r--src/lib/ecore_input_evas/ecore_input_evas.c195
2 files changed, 152 insertions, 44 deletions
diff --git a/src/lib/ecore_input_evas/Ecore_Input_Evas.h b/src/lib/ecore_input_evas/Ecore_Input_Evas.h
index 22960488b3..d17dc7d5ff 100644
--- a/src/lib/ecore_input_evas/Ecore_Input_Evas.h
+++ b/src/lib/ecore_input_evas/Ecore_Input_Evas.h
@@ -50,6 +50,7 @@ EAPI Eina_Bool ecore_event_evas_mouse_move(void *data, int type, void *event);
50EAPI Eina_Bool ecore_event_evas_mouse_in(void *data, int type, void *event); 50EAPI Eina_Bool ecore_event_evas_mouse_in(void *data, int type, void *event);
51EAPI Eina_Bool ecore_event_evas_mouse_out(void *data, int type, void *event); 51EAPI Eina_Bool ecore_event_evas_mouse_out(void *data, int type, void *event);
52EAPI Eina_Bool ecore_event_evas_axis_update(void *data, int type, void *event); /**< @since 1.13 */ 52EAPI Eina_Bool ecore_event_evas_axis_update(void *data, int type, void *event); /**< @since 1.13 */
53EAPI Eina_Bool ecore_event_evas_mouse_button_cancel(void *data, int type, void *event); /**< @since 1.19 */
53 54
54EAPI void ecore_event_window_register(Ecore_Window id, void *window, Evas *evas, Ecore_Event_Mouse_Move_Cb move_mouse, Ecore_Event_Multi_Move_Cb move_multi, Ecore_Event_Multi_Down_Cb down_multi, Ecore_Event_Multi_Up_Cb up_multi); 55EAPI void ecore_event_window_register(Ecore_Window id, void *window, Evas *evas, Ecore_Event_Mouse_Move_Cb move_mouse, Ecore_Event_Multi_Move_Cb move_multi, Ecore_Event_Multi_Down_Cb down_multi, Ecore_Event_Multi_Up_Cb up_multi);
55EAPI void ecore_event_window_unregister(Ecore_Window id); 56EAPI void ecore_event_window_unregister(Ecore_Window id);
diff --git a/src/lib/ecore_input_evas/ecore_input_evas.c b/src/lib/ecore_input_evas/ecore_input_evas.c
index 5de76a86ac..41ee786e0c 100644
--- a/src/lib/ecore_input_evas/ecore_input_evas.c
+++ b/src/lib/ecore_input_evas/ecore_input_evas.c
@@ -29,9 +29,16 @@ typedef enum _Ecore_Input_State {
29 ECORE_INPUT_NONE = 0, 29 ECORE_INPUT_NONE = 0,
30 ECORE_INPUT_DOWN, 30 ECORE_INPUT_DOWN,
31 ECORE_INPUT_MOVE, 31 ECORE_INPUT_MOVE,
32 ECORE_INPUT_UP 32 ECORE_INPUT_UP,
33 ECORE_INPUT_CANCEL
33} Ecore_Input_State; 34} Ecore_Input_State;
34 35
36typedef enum _Ecore_Input_Action {
37 ECORE_INPUT_CONTINUE = 0,
38 ECORE_INPUT_IGNORE,
39 ECORE_INPUT_FAKE_UP
40} Ecore_Input_Action;
41
35typedef struct _Ecore_Input_Last Ecore_Event_Last; 42typedef struct _Ecore_Input_Last Ecore_Event_Last;
36struct _Ecore_Input_Last 43struct _Ecore_Input_Last
37{ 44{
@@ -46,7 +53,7 @@ struct _Ecore_Input_Last
46}; 53};
47 54
48static int _ecore_event_evas_init_count = 0; 55static int _ecore_event_evas_init_count = 0;
49static Ecore_Event_Handler *ecore_event_evas_handlers[9]; 56static Ecore_Event_Handler *ecore_event_evas_handlers[10];
50static Eina_Hash *_window_hash = NULL; 57static Eina_Hash *_window_hash = NULL;
51 58
52static Eina_List *_last_events = NULL; 59static Eina_List *_last_events = NULL;
@@ -57,6 +64,59 @@ static Eina_Bool _ecore_event_evas_mouse_button(Ecore_Event_Mouse_Button *e,
57 Ecore_Event_Press press, 64 Ecore_Event_Press press,
58 Eina_Bool faked); 65 Eina_Bool faked);
59 66
67static Ecore_Input_Action
68_ecore_event_last_check(Ecore_Event_Last *eel, Ecore_Event_Press press)
69{
70 switch (eel->state)
71 {
72 case ECORE_INPUT_NONE:
73 /* 1. ECORE_INPUT_NONE => ECORE_UP : impossible
74 * 2. ECORE_INPUT_NONE => ECORE_CANCEL : impossible
75 * 3. ECORE_INPUT_NONE => ECORE_DOWN : ok
76 */
77 return ECORE_INPUT_CONTINUE;
78
79 case ECORE_INPUT_DOWN:
80 /* 1. ECORE_INPUT_DOWN => ECORE_UP : ok
81 * 2. ECORE_INPUT_DOWN => ECORE_CANCEL : ok
82 */
83 if ((press == ECORE_UP) || (press == ECORE_CANCEL))
84 return ECORE_INPUT_CONTINUE;
85
86 /* 3. ECORE_INPUT_DOWN => ECORE_DOWN : emit a faked UP then */
87 INF("Down event occurs twice. device(%d), button(%d)", eel->device, eel->buttons);
88 return ECORE_INPUT_FAKE_UP;
89
90 case ECORE_INPUT_MOVE:
91 /* 1. ECORE_INPUT_MOVE => ECORE_UP : ok
92 * 2. ECORE_INPUT_MOVE => ECORE_CANCEL : ok
93 */
94 if ((press == ECORE_UP) || (press == ECORE_CANCEL))
95 return ECORE_INPUT_CONTINUE;
96
97 /* 3. ECORE_INPUT_MOVE => ECORE_DOWN : ok
98 * FIXME: handle fake button up and push for more delay here */
99 //TODO: How to deal with down event after move event?
100 INF("Down event occurs after move event. device(%d), button(%d)", eel->device, eel->buttons);
101 return ECORE_INPUT_FAKE_UP;
102
103 case ECORE_INPUT_UP:
104 case ECORE_INPUT_CANCEL:
105 /* 1. ECORE_INPUT_UP => ECORE_DOWN : ok */
106 /* 2. ECORE_INPUT_CANCEL => ECORE_DOWN : ok */
107 if (press == ECORE_DOWN)
108 return ECORE_INPUT_CONTINUE;
109
110 /* 3. ECORE_INPUT_UP => ECORE_UP : ignore */
111 /* 4. ECORE_INPUT_UP => ECORE_CANCEL : ignore */
112 /* 5. ECORE_INPUT_CANCEL => ECORE_UP : ignore */
113 /* 6. ECORE_INPUT_CANCEL => ECORE_CANCEL : ignore */
114 INF("Up/cancel event occurs after up/cancel event. device(%d), button(%d)", eel->device, eel->buttons);
115 return ECORE_INPUT_IGNORE;
116 }
117 return ECORE_INPUT_IGNORE;
118}
119
60static Ecore_Event_Last * 120static Ecore_Event_Last *
61_ecore_event_evas_lookup(unsigned int device, unsigned int buttons, Eina_Bool create_new) 121_ecore_event_evas_lookup(unsigned int device, unsigned int buttons, Eina_Bool create_new)
62{ 122{
@@ -91,6 +151,7 @@ _ecore_event_evas_push_fake(void *data)
91 { 151 {
92 case ECORE_INPUT_NONE: 152 case ECORE_INPUT_NONE:
93 case ECORE_INPUT_UP: 153 case ECORE_INPUT_UP:
154 case ECORE_INPUT_CANCEL:
94 /* should not happen */ 155 /* should not happen */
95 break; 156 break;
96 case ECORE_INPUT_DOWN: 157 case ECORE_INPUT_DOWN:
@@ -109,48 +170,45 @@ _ecore_event_evas_push_fake(void *data)
109 return EINA_FALSE; 170 return EINA_FALSE;
110} 171}
111 172
112static void 173static Eina_Bool
113_ecore_event_evas_push_mouse_button(Ecore_Event_Mouse_Button *e, Ecore_Event_Press press) 174_ecore_event_evas_push_mouse_button(Ecore_Event_Mouse_Button *e, Ecore_Event_Press press)
114{ 175{
115 Ecore_Event_Last *eel; 176 Ecore_Event_Last *eel;
177 Ecore_Input_Action action;
116 178
117 if (!_last_events_enable) return; 179 //_ecore_event_evas_mouse_button already check press or cancel without history
118
119 eel = _ecore_event_evas_lookup(e->multi.device, e->buttons, EINA_TRUE); 180 eel = _ecore_event_evas_lookup(e->multi.device, e->buttons, EINA_TRUE);
120 if (!eel) return; 181 if (!eel) return EINA_FALSE;
182 INF("dev(%d), button(%d), last_press(%d), press(%d)", e->multi.device, e->buttons, eel->state, press);
121 183
122 switch (eel->state) 184 action = _ecore_event_last_check(eel, press);
185 INF("action(%d)", action);
186 switch (action)
123 { 187 {
124 case ECORE_INPUT_NONE: 188 case ECORE_INPUT_FAKE_UP:
125 goto fine;
126 case ECORE_INPUT_DOWN:
127 if (press == ECORE_UP)
128 goto fine;
129
130 /* press == ECORE_DOWN => emit a faked UP then */
131 _ecore_event_evas_mouse_button(e, ECORE_UP, EINA_TRUE); 189 _ecore_event_evas_mouse_button(e, ECORE_UP, EINA_TRUE);
190 case ECORE_INPUT_CONTINUE:
132 break; 191 break;
133 case ECORE_INPUT_MOVE: 192 case ECORE_INPUT_IGNORE:
134 if (press == ECORE_UP) 193 default:
135 goto fine; 194 return EINA_FALSE;
136 195 }
137 /* FIXME: handle fake button up and push for more delay here */
138
139 /* press == ECORE_DOWN */
140 _ecore_event_evas_mouse_button(e, ECORE_DOWN, EINA_TRUE);
141 break;
142 case ECORE_INPUT_UP:
143 if (press == ECORE_DOWN)
144 goto fine;
145 196
146 /* press == ECORE_UP */ 197 switch (press)
147 _ecore_event_evas_mouse_button(e, ECORE_UP, EINA_TRUE); 198 {
148 break; 199 case ECORE_DOWN:
200 eel->state = ECORE_INPUT_DOWN;
201 break;
202 case ECORE_UP:
203 eel->state = ECORE_INPUT_UP;
204 break;
205 default:
206 break;
149 } 207 }
150 208
151 fine: 209 //if up event not occurs from under layers of ecore
152 eel->state = (press == ECORE_DOWN) ? ECORE_INPUT_DOWN : ECORE_INPUT_UP; 210 //up event is generated by ecore
153 if (_last_events_timeout) 211 if (_last_events_enable && _last_events_timeout)
154 { 212 {
155 if (eel->timer) ecore_timer_del(eel->timer); 213 if (eel->timer) ecore_timer_del(eel->timer);
156 eel->timer = NULL; 214 eel->timer = NULL;
@@ -158,7 +216,7 @@ _ecore_event_evas_push_mouse_button(Ecore_Event_Mouse_Button *e, Ecore_Event_Pre
158 { 216 {
159 /* Save the Ecore_Event somehow */ 217 /* Save the Ecore_Event somehow */
160 if (!eel->ev) eel->ev = malloc(sizeof (Ecore_Event_Mouse_Button)); 218 if (!eel->ev) eel->ev = malloc(sizeof (Ecore_Event_Mouse_Button));
161 if (!eel->ev) return; 219 if (!eel->ev) return EINA_FALSE;
162 memcpy(eel->ev, e, sizeof (Ecore_Event_Mouse_Button)); 220 memcpy(eel->ev, e, sizeof (Ecore_Event_Mouse_Button));
163 eel->timer = ecore_timer_add(_last_events_timeout, _ecore_event_evas_push_fake, eel); 221 eel->timer = ecore_timer_add(_last_events_timeout, _ecore_event_evas_push_fake, eel);
164 } 222 }
@@ -168,6 +226,7 @@ _ecore_event_evas_push_mouse_button(Ecore_Event_Mouse_Button *e, Ecore_Event_Pre
168 eel->ev = NULL; 226 eel->ev = NULL;
169 } 227 }
170 } 228 }
229 return EINA_TRUE;
171} 230}
172 231
173static void 232static void
@@ -183,7 +242,8 @@ _ecore_event_evas_push_mouse_move(Ecore_Event_Mouse_Move *e)
183 { 242 {
184 case ECORE_INPUT_NONE: 243 case ECORE_INPUT_NONE:
185 case ECORE_INPUT_UP: 244 case ECORE_INPUT_UP:
186 /* none or up and moving, sounds fine to me */ 245 case ECORE_INPUT_CANCEL:
246 /* (none, up, or cancel) => move, sounds fine to me */
187 break; 247 break;
188 case ECORE_INPUT_DOWN: 248 case ECORE_INPUT_DOWN:
189 case ECORE_INPUT_MOVE: 249 case ECORE_INPUT_MOVE:
@@ -355,6 +415,30 @@ _ecore_event_evas_key(Ecore_Event_Key *e, Ecore_Event_Press press)
355} 415}
356 416
357static Eina_Bool 417static Eina_Bool
418_ecore_event_evas_mouse_button_cancel(Ecore_Event_Mouse_Button *e)
419{
420 Ecore_Input_Window *lookup;
421 Ecore_Event_Last *eel;
422 Eina_List *l;
423
424 lookup = _ecore_event_window_match(e->event_window);
425 if (!lookup) return ECORE_CALLBACK_PASS_ON;
426
427 INF("ButtonEvent cancel, device(%d), button(%d)", e->multi.device, e->buttons);
428 evas_event_feed_mouse_cancel(lookup->evas, e->timestamp, NULL);
429
430 //the number of last event is small, simple check is ok.
431 EINA_LIST_FOREACH(_last_events, l, eel)
432 {
433 Ecore_Input_Action act = _ecore_event_last_check(eel, ECORE_CANCEL);
434 INF("ButtonEvent cancel, dev(%d), button(%d), last_press(%d), action(%d)", eel->device, eel->buttons, eel->state, act);
435 if (act == ECORE_INPUT_CONTINUE) eel->state = ECORE_INPUT_CANCEL;
436 }
437
438 return ECORE_CALLBACK_PASS_ON;
439}
440
441static Eina_Bool
358_ecore_event_evas_mouse_button(Ecore_Event_Mouse_Button *e, Ecore_Event_Press press, Eina_Bool faked) 442_ecore_event_evas_mouse_button(Ecore_Event_Mouse_Button *e, Ecore_Event_Press press, Eina_Bool faked)
359{ 443{
360 Ecore_Event_Last *eel; 444 Ecore_Event_Last *eel;
@@ -366,21 +450,35 @@ _ecore_event_evas_mouse_button(Ecore_Event_Mouse_Button *e, Ecore_Event_Press pr
366 if (e->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK; 450 if (e->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
367 if (e->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK; 451 if (e->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
368 INF("\tButtonEvent:ecore_event_evas press(%d), device(%d), button(%d), fake(%d)", press, e->multi.device, e->buttons, faked); 452 INF("\tButtonEvent:ecore_event_evas press(%d), device(%d), button(%d), fake(%d)", press, e->multi.device, e->buttons, faked);
369 if (_last_events_enable) 453
454 //handle all mouse error from under layers of ecore
455 //error handle
456 // 1. ecore up without ecore down
457 // 2. ecore cancel without ecore down
458 if (press != ECORE_DOWN)
370 { 459 {
371 //error handle: if ecore up without ecore down 460 //ECORE_UP or ECORE_CANCEL
372 if (press == ECORE_UP) 461 eel = _ecore_event_evas_lookup(e->multi.device, e->buttons, EINA_FALSE);
462 if (!eel)
463
464 if ((!eel) || (eel->state == ECORE_INPUT_UP) || (eel->state == ECORE_INPUT_CANCEL))
373 { 465 {
374 eel = _ecore_event_evas_lookup(e->multi.device, e->buttons, EINA_FALSE); 466 if (!eel)
375 if ((!eel) || (eel->state == ECORE_INPUT_UP)) 467 WRN("ButtonEvent has no history.");
376 { 468 else
377 INF("ButtonEvent: up event without down event."); 469 WRN("ButtonEvent has wrong history. Last state=%d", eel->state);
378 return ECORE_CALLBACK_PASS_ON; 470 return ECORE_CALLBACK_PASS_ON;
379 }
380 } 471 }
381 } 472 }
382 473
383 if (!faked) _ecore_event_evas_push_mouse_button(e, press); 474 if (!faked)
475 {
476 Eina_Bool ret = EINA_FALSE;
477 ret = _ecore_event_evas_push_mouse_button(e, press);
478 /* This ButtonEvent is worng */
479 if (!ret) return ECORE_CALLBACK_PASS_ON;
480 }
481
384 if (e->multi.device == 0) 482 if (e->multi.device == 0)
385 { 483 {
386 ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers); 484 ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers);
@@ -481,6 +579,12 @@ ecore_event_evas_mouse_button_up(void *data EINA_UNUSED, int type EINA_UNUSED, v
481 return _ecore_event_evas_mouse_button((Ecore_Event_Mouse_Button *)event, ECORE_UP, EINA_FALSE); 579 return _ecore_event_evas_mouse_button((Ecore_Event_Mouse_Button *)event, ECORE_UP, EINA_FALSE);
482} 580}
483 581
582EAPI Eina_Bool
583ecore_event_evas_mouse_button_cancel(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
584{
585 return _ecore_event_evas_mouse_button_cancel((Ecore_Event_Mouse_Button *)event);
586}
587
484static Eina_Bool 588static Eina_Bool
485_ecore_event_evas_mouse_io(Ecore_Event_Mouse_IO *e, Ecore_Event_IO io) 589_ecore_event_evas_mouse_io(Ecore_Event_Mouse_IO *e, Ecore_Event_IO io)
486{ 590{
@@ -609,6 +713,9 @@ ecore_event_evas_init(void)
609 ecore_event_evas_handlers[8] = ecore_event_handler_add(ECORE_EVENT_AXIS_UPDATE, 713 ecore_event_evas_handlers[8] = ecore_event_handler_add(ECORE_EVENT_AXIS_UPDATE,
610 ecore_event_evas_axis_update, 714 ecore_event_evas_axis_update,
611 NULL); 715 NULL);
716 ecore_event_evas_handlers[9] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_CANCEL,
717 ecore_event_evas_mouse_button_cancel,
718 NULL);
612 719
613 _window_hash = eina_hash_pointer_new(free); 720 _window_hash = eina_hash_pointer_new(free);
614 721