apply FSL(Flora Software License)
[apps/home/ug-image-viewer-efl.git] / common / src / ivug-mouse-event.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *        http://www.tizenopensource.org/license
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 #include <Elementary.h>
19 #include <stdbool.h>
20 #include "ivug-debug.h"
21 #include "ivug-mouse-event.h"
22
23
24 // Click condition.
25 // Down Up duration under 300ms & Down pos, Up pos under 3 pixel
26
27
28 // Long pressed condition
29 // Down Up duration upper 1s & Down pos, Up pos under 5 pixel
30
31 typedef enum {
32         MOUSE_DOWN_UNKNWON,
33         MOUSE_DOWN_NONE,
34         MOUSE_DOWN_1,
35         MOUSE_DOWN_ERROR,       // Error
36 } MouseState;
37
38
39 #define INVALID_DEVICE_ID (-1)
40 #define NUM_MAX_BUTTON (1)
41
42 typedef struct _mouse_data_t{
43         void *pClientData;
44         Evas_Object *obj;
45
46         mouse_callback_t cb;
47
48         MouseState m_state;
49
50         bool bDown[NUM_MAX_BUTTON];             // For Mose down check before mouse move
51         bool bHold[NUM_MAX_BUTTON];
52
53         MouseEvent event[NUM_MAX_BUTTON];
54         MouseEvent down[NUM_MAX_BUTTON];
55         MouseEvent prve_up[NUM_MAX_BUTTON];
56
57         unsigned int prev_dist;
58
59         MouseEvent center;
60
61 // For debugging purpose, later will be removed.
62         char alias[100];                //
63 } mouse_data_t;
64
65
66 #ifndef __UNUSED__
67 #define __UNUSED__ __attribute__((unused))
68 #endif
69
70 static void _on_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
71 {
72         if ( data == NULL )
73         {
74                 MSG_MOUSE_ERROR("Debug me!!!!");
75                 return;
76         }
77
78         mouse_data_t *pData = (mouse_data_t *)data;
79         MouseEvent *ev = event_info;
80
81         if ( ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
82         {
83                 MSG_MOUSE_HIGH("[%s] %s On Hold. Dev=%d", pData->alias, __func__, ev->device);
84         }
85
86         int pressed = ev->device;
87
88         if(pressed >= NUM_MAX_BUTTON)
89         {
90                 MSG_MOUSE_FATAL("Invalid Pressed(%d)", pressed);
91                 return;
92         }
93
94         if ( pData->m_state == MOUSE_DOWN_UNKNWON )
95         {
96                 MSG_MOUSE_ERROR("[%s] Something wrong", pData->alias);
97         }
98
99         if \r( pData->bDown[pressed] == true )
100         {
101                 MSG_MOUSE_WARN("Mouse down is detected. but already pressed button. ignore");
102                 return;
103         }
104
105         pData->m_state++;
106         pData->bDown[pressed] = true;           // TODO : probably, can make memory overwritten issues.
107
108         if ( pData->m_state == MOUSE_DOWN_1 )
109         {
110                 MSG_MOUSE_HIGH("[%s] Callback Mouse Down : Dev=%d (%d,%d)", pData->alias, ev->device, ev->x, ev->y);
111
112                 if ( pData->cb.onMouseDown )
113                 {
114                         (pData->cb.onMouseDown)(pData->obj, ev, pData->pClientData);
115                 }
116
117                 MSG_MOUSE_MED("Func:%s Device=%d XY(%d,%d)", "_on_mouse_down", pressed, ev->x , ev->y );
118         }
119         else
120         {
121                 MSG_MOUSE_WARN("[%s] Ignore third finger! State=%d Dev=%d bPressed(%d,%d,%d)", pData->alias, pData->m_state, ev->device,
122                         pData->bDown[0],
123                         pData->bDown[1],
124                         pData->bDown[2]);
125
126                 return ;
127         }
128
129         pData->event[pressed] = *ev;
130         pData->down[pressed] = *ev;
131
132         return ;
133 }
134
135
136 static void _on_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
137 {
138
139         if ( data == NULL )
140         {
141                 MSG_MOUSE_ERROR("Debug me!!!!");
142                 return;
143         }
144
145         mouse_data_t *pData = (mouse_data_t *)data;
146         MouseEvent *ev = event_info;
147
148         int pressed = ev->device;
149
150         if(pressed >= NUM_MAX_BUTTON)
151         {
152                 MSG_MOUSE_FATAL("Invalid Pressed(%d)", pressed);
153                 return;
154         }
155
156         if ( pData->m_state == MOUSE_DOWN_UNKNWON )
157         {
158                 MSG_MOUSE_ERROR("[%s] Something wrong. Dev=%d",  pData->alias, ev->device);
159                 MSG_MOUSE_ERROR("[%s] Error! State=%d Dev=%d bPressed(%d,%d,%d)", pData->alias, pData->m_state, ev->device,
160                         pData->bDown[0],
161                         pData->bDown[1],
162                         pData->bDown[2]);
163
164         }
165
166         if ( pData->m_state == MOUSE_DOWN_NONE )
167         {
168                 MSG_MOUSE_WARN("[%s] Mouse up is detected. but state is NONE.", pData->alias);
169                 pData->bDown[0] = pData->bDown[1] = pData->bDown[2] = 0;
170                 return;
171         }
172
173         pData->m_state--;
174
175         if \r( pData->bDown[pressed] == false )
176         {
177                 MSG_MOUSE_ERROR("[%s] Something wrong", pData->alias);
178                 MSG_MOUSE_ERROR("[%s] Error! State=%d Dev=%d bPressed(%d,%d,%d)", pData->alias, pData->m_state, ev->device,
179                         pData->bDown[0],
180                         pData->bDown[1],
181                         pData->bDown[2]);
182         }
183
184         if ( ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
185         {
186                 MSG_MOUSE_HIGH("[%s] %s On Hold. Dev=%d", pData->alias, __func__, ev->device);
187                 pData->bHold[pressed] = true;
188         }
189
190         pData->bDown[pressed] = false;
191
192         if ( pData->m_state == MOUSE_DOWN_NONE )
193         {
194                 MSG_MOUSE_HIGH("[%s] Callback Mouse Up : Dev=%d (%d,%d)", pData->alias, ev->device, ev->x, ev->y);
195
196                 if ( ev->button_flags & EVAS_BUTTON_DOUBLE_CLICK)
197                 {
198                         if ( pData->cb.onMouseDlbClick )
199                         {
200                                 (pData->cb.onMouseDlbClick)(pData->obj, ev, pData->pClientData);
201                         }
202                         MSG_MOUSE_HIGH("[%s] %s Double click detected. Dev=%d (%d,%d)", pData->alias, __func__, ev->device, ev->x, ev->y);
203                 }
204                 if ( pData->cb.onMouseUp )
205                 {
206                         (pData->cb.onMouseUp)(pData->obj, ev, pData->pClientData);
207                 }
208
209                 pData->prve_up[pressed] = *ev;
210
211                 MSG_MOUSE_MED("Func:%s State=%d Device=%d XY(%d,%d)", "_on_mouse_up", pData->m_state, pressed, ev->x , ev->y);
212         }
213
214         return ;
215
216 }
217
218 static void _on_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
219 {
220         if ( data == NULL )
221         {
222                 MSG_MOUSE_ERROR("Debug me!!!!");
223                 return;
224         }
225
226         mouse_data_t *pData = (mouse_data_t *)data;
227         MouseEvent *ev = event_info;
228
229         int pressed = ev->device;
230
231         if ( ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
232         {
233                 MSG_MOUSE_HIGH("[%s] %s On Hold. Dev=%d", pData->alias, __func__, ev->device);
234         }
235
236         if(pressed >= NUM_MAX_BUTTON)
237         {
238                 MSG_MOUSE_FATAL("Invalid Pressed(%d)", pressed);
239                 return;
240         }
241
242         if ( pData->bDown[pressed] == false)
243         {
244                 // Move event prior down should be ignored
245                 MSG_MOUSE_MED("Ignore move event before click");
246                 return ;
247         }
248
249         switch ( pData->m_state )
250         {
251                 case MOUSE_DOWN_1:
252                 {
253                         MSG_MOUSE_MED("Func:%s. Device=%d Old(%d,%d) Cur(%d,%d)", __FUNCTION__, pressed,
254                                         pData->event[pressed].x, pData->event[pressed].y,
255                                         ev->x , ev->y);
256
257                         if ( pData->cb.onMouseMove )
258                         {
259                                 MSG_MOUSE_MED("[%s] Callback Mouse Move : (%d,%d)",  pData->alias, ev->x, ev->y);
260                                 (pData->cb.onMouseMove)(pData->obj, &pData->event[pressed], ev, pData->pClientData);
261                         }
262
263                         pData->event[pressed] = *ev;
264
265                         break;
266                 }
267                 default:
268                         MSG_MOUSE_ERROR("[%s] Something wrong. state=%d", pData->alias, pData->m_state);
269                         break;
270
271         }
272
273         return ;
274 }
275
276
277
278 static void _proxy_on_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
279 {
280         Evas_Event_Mouse_Down *ev = event_info;
281
282         MouseEvent event;
283
284         event.device = 0;
285         event.timestamp = ev->timestamp;
286         event.x = ev->canvas.x;
287         event.y = ev->canvas.y;
288         event.button_flags = ev->flags;
289         event.event_flags = ev->event_flags;
290
291         MSG_MOUSE_MED("%s Dev=%d Button=%d Flags=%d Event=%d", __func__, (int)ev->dev, ev->button, ev->flags, ev->event_flags);
292
293         _on_mouse_down(data, NULL, obj, (void *)&event);
294 }
295
296 static void _proxy_on_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
297 {
298         Evas_Event_Mouse_Up *ev = event_info;
299
300         MouseEvent event;
301
302         event.device = 0;
303         event.timestamp = ev->timestamp;
304         event.x = ev->canvas.x;
305         event.y = ev->canvas.y;
306         event.button_flags = ev->flags;
307         event.event_flags = ev->event_flags;
308
309
310         MSG_MOUSE_MED("%s Dev=%d Button=%d Flags=%d Event=%d", __func__, (int)ev->dev, ev->button, ev->flags, ev->event_flags);
311
312
313         _on_mouse_up(data, NULL, obj, (void *)&event);
314 }
315
316 static void _proxy_on_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
317 {
318         Evas_Event_Mouse_Move *ev = event_info;
319
320         MouseEvent event;
321
322         event.device = 0;
323         event.timestamp = ev->timestamp;
324         event.x = ev->cur.canvas.x;
325         event.y = ev->cur.canvas.y;
326         event.button_flags = 0;
327         event.event_flags = ev->event_flags;
328
329         MSG_MOUSE_MED("%s Dev=%d Button=%d Event=%d Prev(%d,%d) Cur(%d,%d)", __func__, (int)ev->dev, ev->buttons, ev->event_flags,
330                                 ev->prev.canvas.x, ev->prev.canvas.y, ev->cur.canvas.x, ev->cur.canvas.y);
331
332         _on_mouse_move(data, NULL, obj, (void *)&event);
333
334 }
335
336
337 Ivug_Event_Handle
338 ivug_mouse_event_add(Evas_Object *obj, mouse_callback_t *pCallback, void *client_data, const char *alias)
339 {
340         mouse_data_t *pData = NULL;
341 //TODO : Should check parameters
342
343         pData = calloc(1, sizeof(mouse_data_t));
344
345         pData->obj = obj;
346         pData->pClientData = client_data;
347         pData->m_state = MOUSE_DOWN_NONE;
348         strncpy(pData->alias, alias, sizeof(pData->alias));
349
350         memcpy(&pData->cb, pCallback, sizeof(mouse_callback_t));
351
352         evas_object_event_callback_add(pData->obj, EVAS_CALLBACK_MOUSE_DOWN, _proxy_on_mouse_down, pData);
353         evas_object_event_callback_add(pData->obj, EVAS_CALLBACK_MOUSE_UP, _proxy_on_mouse_up,  pData);
354         evas_object_event_callback_add(pData->obj, EVAS_CALLBACK_MOUSE_MOVE, _proxy_on_mouse_move, pData);
355
356         MSG_MOUSE_HIGH("Mouse Event Handler Add : Alias(%s) 0x%08x for Object(0x%08x)", alias, pData, obj);
357
358         return (Ivug_Event_Handle *)pData;
359 }
360
361
362 void ivug_mouse_event_del(Ivug_Event_Handle handle)
363 {
364         mouse_data_t *pData = handle;
365
366         evas_object_event_callback_del(pData->obj, EVAS_CALLBACK_MOUSE_DOWN, _proxy_on_mouse_down);
367         evas_object_event_callback_del(pData->obj, EVAS_CALLBACK_MOUSE_UP, _proxy_on_mouse_up);
368         evas_object_event_callback_del(pData->obj, EVAS_CALLBACK_MOUSE_MOVE, _proxy_on_mouse_move);
369
370         MSG_MOUSE_HIGH("Mouse Event Handler Remove : 0x%08x", pData);
371
372         free(handle);
373 }
374
375
376