2 * Copyright 2012 Samsung Electronics Co., Ltd
\r
4 * Licensed under the Flora License, Version 1.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.tizenopensource.org/license
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
17 #include <Elementary.h>
19 #include "ivug-debug.h"
20 #include "ivug-mouse-event.h"
24 // Down Up duration under 300ms & Down pos, Up pos under 3 pixel
27 // Long pressed condition
28 // Down Up duration upper 1s & Down pos, Up pos under 5 pixel
36 MOUSE_DOWN_4, // Invalid state.
41 #define INVALID_DEVICE_ID (-1)
42 #define MULTI_INDEX (9)
43 #define NUM_MAX_BUTTON (3)
45 typedef struct _mouse_data_t{
53 bool bDown[NUM_MAX_BUTTON]; // For Mose down check before mouse move
54 bool bHold[NUM_MAX_BUTTON];
56 MouseEvent event[NUM_MAX_BUTTON];
57 MouseEvent down[NUM_MAX_BUTTON];
58 MouseEvent prve_up[NUM_MAX_BUTTON];
60 unsigned int prev_dist;
62 int multi_min_idx; // multi min index is different in each target. Temp solution
68 // For debugging purpose, later will be removed.
74 #define __UNUSED__ __attribute__((unused))
77 static unsigned int _get_distance(int prevX, int prevY, int X, int Y)
83 return sqrt(dx*dx + dy*dy);
86 static void _on_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
90 MSG_MOUSE_ERROR("Debug me!!!!");
94 mouse_data_t *pData = (mouse_data_t *)data;
95 MouseEvent *ev = event_info;
97 if ( ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
99 MSG_MOUSE_HIGH("[%s] %s On Hold. Dev=%d", pData->alias, __func__, ev->device);
102 int pressed = ev->device;
104 if(pressed >= NUM_MAX_BUTTON)
106 MSG_MOUSE_FATAL("Invalid Pressed(%d)", pressed);
110 if ( pData->m_state == MOUSE_DOWN_UNKNWON )
112 MSG_MOUSE_ERROR("[%s] Something wrong", pData->alias);
115 if
\r( pData->bDown[pressed] == true )
117 MSG_MOUSE_WARN("Mouse down is detected. but already pressed button. ignore");
122 pData->bDown[pressed] = true; // TODO : probably, can make memory overwritten issues.
124 if ( pData->m_state == MOUSE_DOWN_1 )
126 MSG_MOUSE_HIGH("[%s] Callback Mouse Down : Dev=%d (%d,%d)", pData->alias, ev->device, ev->x, ev->y);
128 if ( pData->cb.onMouseDown )
130 (pData->cb.onMouseDown)(pData->obj, ev, pData->pClientData);
133 MSG_MOUSE_MED("Func:%s Device=%d XY(%d,%d)", "_on_mouse_down", pressed, ev->x , ev->y );
135 else if ( pData->m_state == MOUSE_DOWN_2 )
137 MouseEvent *other = NULL;
139 if ( pData->bDown[ (pressed + 1) % NUM_MAX_BUTTON] == true )
141 other = &pData->event[(pressed + 1) % NUM_MAX_BUTTON];
144 if ( pData->bDown[(pressed + 2) % NUM_MAX_BUTTON] == true )
148 MSG_MOUSE_ERROR("Error!!!");
150 other = &pData->event[(pressed + 2) % NUM_MAX_BUTTON];
155 MSG_MOUSE_ERROR("[%s] Error! Pressed(%d,%d,%d)", pData->alias,
160 return ; // Fix for B/S
163 int centerX = ( other->x + ev->x ) / 2;
164 int centerY = ( other->y + ev->y ) / 2;
166 int dist = _get_distance(other->x, other->y, ev->x, ev->y);
168 MSG_MOUSE_HIGH("[%s] Callback PinchStart : Dev=%d OtherDev=%d Center(%d,%d) Dist=%d", pData->alias, ev->device, other->device, centerX, centerY, dist);
170 if ( pData->cb.onPinchStart )
172 pData->center.x = centerX;
173 pData->center.y = centerY;
174 pData->center.timestamp = ev->timestamp;
175 pData->pinch_dist = dist;
177 (pData->cb.onPinchStart)(pData->obj, &pData->center, dist, pData->pClientData);
180 pData->prev_dist = dist;
182 MSG_MOUSE_HIGH("[%s] Two fingure is clicked. Distance=%d", pData->alias, pData->prev_dist);
186 MSG_MOUSE_WARN("[%s] Ignore third finger! State=%d Dev=%d bPressed(%d,%d,%d)", pData->alias, pData->m_state, ev->device,
194 pData->event[pressed] = *ev;
195 pData->down[pressed] = *ev;
201 static void _on_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
206 MSG_MOUSE_ERROR("Debug me!!!!");
210 mouse_data_t *pData = (mouse_data_t *)data;
211 MouseEvent *ev = event_info;
213 int pressed = ev->device;
215 if(pressed >= NUM_MAX_BUTTON)
217 MSG_MOUSE_FATAL("Invalid Pressed(%d)", pressed);
221 if ( pData->m_state == MOUSE_DOWN_UNKNWON )
223 MSG_MOUSE_ERROR("[%s] Something wrong. Dev=%d", pData->alias, ev->device);
224 MSG_MOUSE_ERROR("[%s] Error! State=%d Dev=%d bPressed(%d,%d,%d)", pData->alias, pData->m_state, ev->device,
231 if ( pData->m_state == MOUSE_DOWN_NONE )
233 MSG_MOUSE_WARN("[%s] Mouse up is detected. but state is NONE.", pData->alias);
234 pData->bDown[0] = pData->bDown[1] = pData->bDown[2] = 0;
240 if
\r( pData->bDown[pressed] == false )
242 MSG_MOUSE_ERROR("[%s] Something wrong", pData->alias);
243 MSG_MOUSE_ERROR("[%s] Error! State=%d Dev=%d bPressed(%d,%d,%d)", pData->alias, pData->m_state, ev->device,
249 if ( ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
251 MSG_MOUSE_HIGH("[%s] %s On Hold. Dev=%d", pData->alias, __func__, ev->device);
252 pData->bHold[pressed] = true;
255 pData->bDown[pressed] = false;
257 if ( pData->m_state == MOUSE_DOWN_1 )
259 MSG_MOUSE_HIGH("[%s] Callback Pinch End", pData->alias);
261 if ( pData->cb.onPinchEnd )
263 pData->bSendPinchStart = false;
264 (pData->cb.onPinchEnd)(pData->obj, ev, pData->pClientData);
267 else if ( pData->m_state == MOUSE_DOWN_NONE )
269 MSG_MOUSE_HIGH("[%s] Callback Mouse Up : Dev=%d (%d,%d)", pData->alias, ev->device, ev->x, ev->y);
271 if ( ev->button_flags & EVAS_BUTTON_DOUBLE_CLICK)
273 if ( pData->cb.onMouseDlbClick )
275 (pData->cb.onMouseDlbClick)(pData->obj, ev, pData->pClientData);
277 MSG_MOUSE_HIGH("[%s] %s Double click detected. Dev=%d (%d,%d)", pData->alias, __func__, ev->device, ev->x, ev->y);
279 if ( pData->cb.onMouseUp )
281 (pData->cb.onMouseUp)(pData->obj, ev, pData->pClientData);
284 pData->prve_up[pressed] = *ev;
286 MSG_MOUSE_MED("Func:%s State=%d Device=%d XY(%d,%d)", "_on_mouse_up", pData->m_state, pressed, ev->x , ev->y);
293 static void _on_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
297 MSG_MOUSE_ERROR("Debug me!!!!");
301 mouse_data_t *pData = (mouse_data_t *)data;
302 MouseEvent *ev = event_info;
304 int pressed = ev->device;
306 if ( ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
308 MSG_MOUSE_HIGH("[%s] %s On Hold. Dev=%d", pData->alias, __func__, ev->device);
311 if(pressed >= NUM_MAX_BUTTON)
313 MSG_MOUSE_FATAL("Invalid Pressed(%d)", pressed);
317 if ( pData->bDown[pressed] == false)
319 // Move event prior down should be ignored
320 MSG_MOUSE_MED("Ignore move event before click");
324 switch ( pData->m_state )
327 // Ignore Mouse Event when all 3 buttons is pressed.
331 MouseEvent *other = NULL;
333 if ( pData->bDown[ (pressed + 1) % NUM_MAX_BUTTON] == true )
335 other = &pData->event[(pressed + 1) % NUM_MAX_BUTTON];
338 if ( pData->bDown[(pressed + 2) % NUM_MAX_BUTTON] == true )
342 MSG_MOUSE_ERROR("Debug me!!!");
344 other = &pData->event[(pressed + 2) % NUM_MAX_BUTTON];
349 MSG_MOUSE_ERROR("[%s] Error! Pressed(%d,%d,%d)", pData->alias,
358 int centerX = ( other->x + ev->x ) / 2;
359 int centerY = ( other->y + ev->y ) / 2;
361 int dist = _get_distance(other->x, other->y, ev->x, ev->y);
363 if ( pData->cb.onPinchMove )
365 MSG_MOUSE_MED("Callback Pinch : (%d,%d) dDistance=%d", centerX, centerY, dist - pData->prev_dist);
367 pData->center.x = centerX;
368 pData->center.y = centerY;
369 pData->center.timestamp = ev->timestamp;
370 pData->pinch_dist = dist;
372 (pData->cb.onPinchMove)(pData->obj, &pData->center, pData->pinch_dist , pData->pClientData);
375 pData->prev_dist = dist;
377 MSG_MOUSE_LOW("Pinch zoom. Pos1(%d,%d) Pos2(%d,%d) Delta=%d", other->x, other->y, ev->x, ev->y, pData->prev_dist);
379 pData->event[pressed] = *ev;
386 MSG_MOUSE_MED("Func:%s. Device=%d Old(%d,%d) Cur(%d,%d)", __FUNCTION__, pressed,
387 pData->event[pressed].x, pData->event[pressed].y,
390 if ( pData->cb.onMouseMove )
392 MSG_MOUSE_MED("[%s] Callback Mouse Move : (%d,%d)", pData->alias, ev->x, ev->y);
393 (pData->cb.onMouseMove)(pData->obj, &pData->event[pressed], ev, pData->pClientData);
396 pData->event[pressed] = *ev;
401 MSG_MOUSE_ERROR("[%s] Something wrong. state=%d", pData->alias, pData->m_state);
411 static void _proxy_on_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
413 Evas_Event_Mouse_Down *ev = event_info;
418 event.timestamp = ev->timestamp;
419 event.x = ev->canvas.x;
420 event.y = ev->canvas.y;
421 event.button_flags = ev->flags;
422 event.event_flags = ev->event_flags;
424 MSG_MOUSE_MED("%s Dev=%d Button=%d Flags=%d Event=%d", __func__, (int)ev->dev, ev->button, ev->flags, ev->event_flags);
426 _on_mouse_down(data, NULL, obj, (void *)&event);
429 static void _proxy_on_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
431 Evas_Event_Mouse_Up *ev = event_info;
436 event.timestamp = ev->timestamp;
437 event.x = ev->canvas.x;
438 event.y = ev->canvas.y;
439 event.button_flags = ev->flags;
440 event.event_flags = ev->event_flags;
443 MSG_MOUSE_MED("%s Dev=%d Button=%d Flags=%d Event=%d", __func__, (int)ev->dev, ev->button, ev->flags, ev->event_flags);
446 _on_mouse_up(data, NULL, obj, (void *)&event);
449 static void _proxy_on_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
451 Evas_Event_Mouse_Move *ev = event_info;
456 event.timestamp = ev->timestamp;
457 event.x = ev->cur.canvas.x;
458 event.y = ev->cur.canvas.y;
459 event.button_flags = 0;
460 event.event_flags = ev->event_flags;
462 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,
463 ev->prev.canvas.x, ev->prev.canvas.y, ev->cur.canvas.x, ev->cur.canvas.y);
465 _on_mouse_move(data, NULL, obj, (void *)&event);
469 static void _proxy_on_mouse_multi_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
471 Evas_Event_Multi_Down *ev = event_info;
472 mouse_data_t *pData = data;
476 if ( pData->multi_min_idx == INVALID_DEVICE_ID)
478 MSG_MOUSE_HIGH("[%s] Min Device Index=%d", pData->alias, ev->device);
479 pData->multi_min_idx = ev->device -1; // Index start from 0. so -1 is needed
482 event.device = ev->device - pData->multi_min_idx; // ev->device is 10(for second), 11(3rd), 12(4th) finger
483 event.timestamp = ev->timestamp;
484 event.x = ev->canvas.x;
485 event.y = ev->canvas.y;
486 event.button_flags = 0;
487 event.event_flags = ev->event_flags;
490 if(event.device >= NUM_MAX_BUTTON)
492 MSG_MOUSE_FATAL("[%s] Invalid Device. Dev=%d Min=%d", pData->alias, event.device, pData->multi_min_idx);
496 MSG_MOUSE_MED("%s Dev=%d", __func__, ev->device);
498 _on_mouse_down(data, NULL, obj, (void *)&event);
501 static void _proxy_on_mouse_multi_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
503 Evas_Event_Multi_Up *ev = event_info;
504 mouse_data_t *pData = data;
508 if ( pData->multi_min_idx == INVALID_DEVICE_ID)
510 // Sometimes Multi up came ealry
511 MSG_MOUSE_HIGH("[%s] Min Device Index=%d", pData->alias, ev->device);
512 pData->multi_min_idx = ev->device -1; // Index start from 0. so -1 is needed
515 event.device = ev->device - pData->multi_min_idx;
516 event.timestamp = ev->timestamp;
517 event.x = ev->canvas.x;
518 event.y = ev->canvas.y;
519 event.button_flags = 0;
520 event.event_flags = ev->event_flags;
522 if(event.device >= NUM_MAX_BUTTON)
524 MSG_MOUSE_FATAL("[%s] Invalid Device. Dev=%d Min=%d", pData->alias, event.device, pData->multi_min_idx);
528 MSG_MOUSE_MED("%s Dev=%d", __func__, ev->device);
530 _on_mouse_up(data, NULL, obj, (void *)&event);
534 static void _proxy_on_mouse_multi_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
536 Evas_Event_Multi_Move *ev = event_info;
537 mouse_data_t *pData = data;
541 if ( pData->multi_min_idx == INVALID_DEVICE_ID)
543 // Mouse Move come faster than Mouse down
544 MSG_MOUSE_HIGH("[%s] Min Device Index=%d", pData->alias, ev->device);
545 pData->multi_min_idx = ev->device -1;
548 event.device = ev->device - pData->multi_min_idx;
549 event.timestamp = ev->timestamp;
550 event.x = ev->cur.canvas.x;
551 event.y = ev->cur.canvas.y;
552 event.button_flags = 0;
553 event.event_flags = ev->event_flags;
555 if(event.device >= NUM_MAX_BUTTON)
557 MSG_MOUSE_FATAL("[%s] Invalid Device. Dev=%d Min=%d", pData->alias, event.device, pData->multi_min_idx);
561 MSG_MOUSE_MED("%s Dev=%d", __func__, ev->device);
563 _on_mouse_move(data, NULL, obj, (void *)&event);
567 ivug_mouse_event_add(Evas_Object *obj, mouse_callback_t *pCallback, void *client_data, const char *alias)
569 mouse_data_t *pData = NULL;
570 //TODO : Should check parameters
572 pData = calloc(1, sizeof(mouse_data_t));
575 pData->pClientData = client_data;
576 pData->m_state = MOUSE_DOWN_NONE;
577 pData->multi_min_idx = INVALID_DEVICE_ID;
578 strncpy(pData->alias, alias, sizeof(pData->alias));
580 memcpy(&pData->cb, pCallback, sizeof(mouse_callback_t));
582 evas_object_event_callback_add(pData->obj, EVAS_CALLBACK_MOUSE_DOWN, _proxy_on_mouse_down, pData);
583 evas_object_event_callback_add(pData->obj, EVAS_CALLBACK_MOUSE_UP, _proxy_on_mouse_up, pData);
584 evas_object_event_callback_add(pData->obj, EVAS_CALLBACK_MOUSE_MOVE, _proxy_on_mouse_move, pData);
585 evas_object_event_callback_add(pData->obj, EVAS_CALLBACK_MULTI_DOWN, _proxy_on_mouse_multi_down, pData);
586 evas_object_event_callback_add(pData->obj, EVAS_CALLBACK_MULTI_UP, _proxy_on_mouse_multi_up, pData);
587 evas_object_event_callback_add(pData->obj, EVAS_CALLBACK_MULTI_MOVE, _proxy_on_mouse_multi_move, pData);
589 MSG_MOUSE_HIGH("Mouse Event Handler Add : Alias(%s) 0x%08x for Object(0x%08x)", alias, pData, obj);
591 return (Ivug_Event_Handle *)pData;
595 void ivug_mouse_event_del(Ivug_Event_Handle handle)
597 mouse_data_t *pData = handle;
599 evas_object_event_callback_del(pData->obj, EVAS_CALLBACK_MOUSE_DOWN, _proxy_on_mouse_down);
600 evas_object_event_callback_del(pData->obj, EVAS_CALLBACK_MOUSE_UP, _proxy_on_mouse_up);
601 evas_object_event_callback_del(pData->obj, EVAS_CALLBACK_MOUSE_MOVE, _proxy_on_mouse_move);
602 evas_object_event_callback_del(pData->obj, EVAS_CALLBACK_MULTI_DOWN, _proxy_on_mouse_multi_down);
603 evas_object_event_callback_del(pData->obj, EVAS_CALLBACK_MULTI_UP, _proxy_on_mouse_multi_up);
604 evas_object_event_callback_del(pData->obj, EVAS_CALLBACK_MULTI_MOVE, _proxy_on_mouse_multi_move);
606 MSG_MOUSE_HIGH("Mouse Event Handler Remove : 0x%08x", pData);