2 * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include "sclevents-efl.h"
20 #include "sclcontroller.h"
21 #include "sclgraphics.h"
22 #include "scluibuilder.h"
23 #include "sclerroradjustment.h"
24 #include "sclresource.h"
25 #include "sclresourcecache.h"
26 #include "sclres_manager.h"
28 #include <Elementary.h>
31 #include <Ecore_Wayland.h>
36 #include "sclkeyfocushandler.h"
41 #define HANDLE_KEY_EVENTS
44 #define E_PROP_TOUCH_INPUT "X_TouchInput"
47 #define E_KEYBOARD_SERVICE_BUS_NAME "org.tizen.keyboard"
48 #define E_KEYBOARD_SERVICE_NAVI_IFC_NAME "org.tizen.KBGestureNavigation"
49 #define E_KEYBOARD_SERVICE_NAVI_OBJ_PATH "/org/tizen/KBGestureNavigation"
50 static Eldbus_Connection *eldbus_conn = NULL;
51 typedef enum _Gesture {
53 ONE_FINGER_SINGLE_TAP = 15,
54 ONE_FINGER_DOUBLE_TAP = 16
59 Gesture type; // Type of recognized gesture
65 static sclboolean mouse_pressed = FALSE; /* Checks whether mouse is pressed or not */
66 static sclwindow pressed_window = SCLWINDOW_INVALID;
68 /* If the gap between two timestamps are bigger than 1 sec, do not compare */
69 const unsigned int _touch_event_timestamp_compare_range = 1000;
70 /* If the gap between two timestamps are smaller than 50 msec, do not process */
71 const unsigned int _touch_event_timestamp_valid_threshold = 50;
72 extern unsigned int g_timestamp_last_base_window_resized;
74 #define MIN_XY_DIFF 14
76 static Eina_Bool mouse_press(void *data, int type, void *event_info);
77 static Eina_Bool mouse_move(void *data, int type, void *event_info);
78 static Eina_Bool mouse_release(void *data, int type, void *event_info);
81 static Eina_Bool client_message_cb(void *data, int type, void *event);
84 #ifdef HANDLE_KEY_EVENTS
85 static Eina_Bool key_pressed(void *data, int type, void *event_info);
88 static sclboolean get_window_rect(const sclwindow window, SclRectangle *rect)
91 sclboolean ret = FALSE;
92 CSCLUtils *utils = CSCLUtils::get_instance();
93 CSCLWindows *windows = CSCLWindows::get_instance();
94 CSCLContext *context = CSCLContext::get_instance();
95 if (windows && context && utils && rect) {
96 SclWindowContext *window_context = windows->get_window_context(window);
99 if (window_context && utils->get_screen_resolution(&scr_w, &scr_h)) {
100 switch (context->get_rotation()) {
103 rect->height = window_context->geometry.width;
104 rect->width = window_context->geometry.height;
105 rect->y = scr_w - rect->height - window_context->geometry.x;
106 rect->x = window_context->geometry.y;
111 rect->width = window_context->geometry.width;
112 rect->height = window_context->geometry.height;
113 rect->x = scr_w - window_context->geometry.x - rect->width;
114 rect->y = scr_h - window_context->geometry.y - rect->height;
117 case ROTATION_90_CCW:
119 rect->height = window_context->geometry.width;
120 rect->width = window_context->geometry.height;
121 rect->y = window_context->geometry.x;
122 rect->x = scr_h - window_context->geometry.y - rect->width;
127 rect->x = window_context->geometry.x;
128 rect->y = window_context->geometry.y;
129 rect->width = window_context->geometry.width;
130 rect->height = window_context->geometry.height;
136 rect->x = rect->y = rect->width = rect->height = 0;
143 /* In wayland, root.x / root.y is not available, so need to apply virtual offset
144 when event occurred on a virtual window */
145 static void apply_virtual_offset(SclRectangle rect, int *adjustx, int *adjusty)
147 int virtual_offset_x = 0;
148 int virtual_offset_y = 0;
149 SclRectangle base_rect = {0, 0, 0, 0};
151 CSCLWindows *windows = CSCLWindows::get_instance();
153 if (get_window_rect(windows->get_base_window(), &base_rect)) {
154 virtual_offset_x = rect.x - base_rect.x;
155 virtual_offset_y = rect.y - base_rect.y;
157 if (adjustx && adjusty) {
158 *adjustx -= virtual_offset_x;
159 *adjusty -= virtual_offset_y;
168 CSCLEventsImplEfl::CSCLEventsImplEfl()
172 m_mouse_down_handler = NULL;
173 m_mouse_move_handler = NULL;
174 m_mouse_up_handler = NULL;
177 m_xclient_msg_handler = NULL;
179 m_key_pressed_handler = NULL;
183 static void gesture_cb(void *data, const Eldbus_Message *msg)
185 LOGD("GestureDetected callback");
187 static int last_pos_x = -1;
188 static int last_pos_y = -1;
191 LOGD("Incoming message is empty");
194 CSCLController *controller = CSCLController::get_instance();
195 CSCLWindows *windows = CSCLWindows::get_instance();
197 if (!windows || !controller) return;
199 sclwindow base_window = windows->get_base_window();
200 SclWindowContext *window_context = windows->get_window_context(base_window);
202 if (!window_context) return;
203 if (window_context->hidden) return;
205 LOGD("window_context->geometry.x=%d y=%d w=%d h=%d",
206 window_context->geometry.x, window_context->geometry.y,
207 window_context->geometry.width, window_context->geometry.height);
209 Gesture_Info *info = (Gesture_Info *)calloc(sizeof(Gesture_Info), 1);
210 if (!eldbus_message_arguments_get(msg, "iii", &g_type, &info->x,
212 LOGD("Getting message arguments failed");
217 info->type = (Gesture)g_type;
218 LOGD("Incoming gesture name is %d : %d %d", info->type, info->x, info->y);
220 if (info->type == ONE_FINGER_HOVER || info->type == ONE_FINGER_SINGLE_TAP) {
221 if (info->y >= window_context->geometry.y) {
222 last_pos_x = info->x;
223 last_pos_y = info->y - window_context->geometry.y;
224 LOGD("hover last_pos_x=%d last_pos_y=%d", last_pos_x, last_pos_y);
225 controller->mouse_over(base_window, last_pos_x, last_pos_y);
227 } else if (info->type == ONE_FINGER_DOUBLE_TAP) {
228 if (info->y >= window_context->geometry.y) {
229 last_pos_x = info->x;
230 last_pos_y = info->y - window_context->geometry.y;
231 LOGD("double last_pos_x=%d last_pos_y=%d", last_pos_x, last_pos_y);
232 controller->mouse_press(base_window, last_pos_x, last_pos_y);
233 controller->mouse_release(base_window, last_pos_x, last_pos_y);
239 static void gestures_tracker_register()
245 LOGD("Registering callback for GestureDetected signal");
246 if (!(eldbus_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION))) {
247 LOGD("Error: Unable to get session bus");
250 obj = eldbus_object_get(eldbus_conn, E_KEYBOARD_SERVICE_BUS_NAME, E_KEYBOARD_SERVICE_NAVI_OBJ_PATH);
251 if (!obj) LOGD("Error: Getting object failed");
253 proxy = eldbus_proxy_get(obj, E_KEYBOARD_SERVICE_NAVI_IFC_NAME);
254 if (!proxy) LOGD("Error: Getting proxy failed");
255 if (!eldbus_proxy_signal_handler_add(proxy, "KBGestureDetected", gesture_cb, NULL))
256 LOGD("No signal handler returned");
257 LOGD("Callback registration successful");
261 static void gestures_tracker_unregister()
264 eldbus_connection_unref(eldbus_conn);
274 CSCLEventsImplEfl::~CSCLEventsImplEfl()
281 void CSCLEventsImplEfl::init()
283 /* Initializes all window resources */
284 m_mouse_down_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, mouse_press, NULL);
285 m_mouse_move_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, mouse_move, NULL);
286 m_mouse_up_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, mouse_release, NULL);
289 m_xclient_msg_handler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, client_message_cb, NULL);
291 gestures_tracker_register();
294 #ifdef HANDLE_KEY_EVENTS
295 m_key_pressed_handler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, key_pressed, NULL);
299 void CSCLEventsImplEfl::fini()
301 if (m_mouse_down_handler) ecore_event_handler_del(m_mouse_down_handler);
302 m_mouse_down_handler = NULL;
303 if (m_mouse_move_handler) ecore_event_handler_del(m_mouse_move_handler);
304 m_mouse_move_handler = NULL;
305 if (m_mouse_up_handler) ecore_event_handler_del(m_mouse_up_handler);
306 m_mouse_up_handler = NULL;
307 #ifdef HANDLE_KEY_EVENTS
308 if (m_key_pressed_handler) ecore_event_handler_del(m_key_pressed_handler);
310 m_key_pressed_handler = NULL;
312 if (m_xclient_msg_handler) ecore_event_handler_del(m_xclient_msg_handler);
314 gestures_tracker_unregister();
318 /** Here x and y contains "actual" x and y position relative to portrait root window,
319 and window_context->width,height contains the window's orientation dependant width and height */
320 SclPoint get_rotated_local_coords(sclint x, sclint y, SCLRotation rotation, SclRectangle *rect) {
321 SclPoint ret = {0, 0};
327 ret.x = (rect->y + rect->width) - y;
333 ret.x = (rect->x + rect->width) - x;
334 ret.y = (rect->y + rect->height) - y;
337 case ROTATION_90_CCW:
340 ret.y = (rect->x + rect->height) - x;
354 static Eina_Bool check_timestamp_outdated(unsigned int timestamp)
356 /* Skip events that were generated nearly at the same time when our base window resized */
357 timestamp -= _touch_event_timestamp_valid_threshold;
358 unsigned int gap = (g_timestamp_last_base_window_resized > timestamp) ?
359 (g_timestamp_last_base_window_resized - timestamp) :
360 (timestamp - g_timestamp_last_base_window_resized);
361 if (gap < _touch_event_timestamp_compare_range) {
362 if (g_timestamp_last_base_window_resized > timestamp) {
363 /* This event was generated before the base window resize event, ignore */
364 LOGD("Skipping event since turned out to be outdated : %u, %u",
365 g_timestamp_last_base_window_resized, timestamp);
372 //void mouse_press (void *data, Evas *e, Evas_Object *object, void *event_info)
373 static Eina_Bool mouse_press(void *data, int type, void *event_info)
377 Ecore_Wl_Window *wl_base_window;
378 Ecore_Wl_Window *wl_magnifier_window;
379 Ecore_Wl_Window *wl_window;
382 CSCLController *controller = CSCLController::get_instance();
383 CSCLWindows *windows = CSCLWindows::get_instance();
384 CSCLContext *context = CSCLContext::get_instance();
385 CSCLUtils *utils = CSCLUtils::get_instance();
386 CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
388 Ecore_Event_Mouse_Button *ev = (Ecore_Event_Mouse_Button*)event_info;
390 if (ev && check_timestamp_outdated(ev->timestamp)) {
394 if (controller && windows && context && utils && adjustment && ev) {
395 LOGD("mouse_press : %d %d, %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y,
396 g_timestamp_last_base_window_resized, ev->timestamp);
399 sclboolean processed = FALSE;
400 sclwindow window = SCLWINDOW_INVALID;
403 Ecore_X_Window inputWindow = 0;
404 Ecore_X_Atom inputAtom = ecore_x_atom_get("DeviceMgr Input Window");
405 ecore_x_window_prop_xid_get(ecore_x_window_root_first_get(),
406 inputAtom, ECORE_X_ATOM_WINDOW, &inputWindow, 1);
407 if (inputWindow == 0) {
408 utils->log("Error : input window NULL!");
411 unsigned int touch_input = 0;
412 int res = ecore_x_window_prop_card32_get(inputWindow,
413 ecore_x_atom_get(E_PROP_TOUCH_INPUT), &touch_input, 1);
415 utils->log("E_PROP_TOUCH_INPUT : %d %d\n", res, touch_input);
418 if (1 == touch_input) {
419 adjustment->enable_touch_offset(TRUE);
420 } else if (0 == touch_input) {
421 adjustment->enable_touch_offset(FALSE);
425 sclboolean is_scl_window = FALSE;
427 sclboolean is_magnifier_window = FALSE;
428 wl_base_window = elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
429 wl_magnifier_window = (elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_magnifier_window())));
430 if (wl_base_window && (unsigned int)ecore_wl_window_id_get(wl_base_window) == ev->window) {
431 is_scl_window = TRUE;
432 } else if (wl_magnifier_window && (unsigned int)ecore_wl_window_id_get(wl_magnifier_window) == ev->window) {
433 is_scl_window = TRUE;
434 is_magnifier_window = TRUE;
436 if (elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window())) == ev->window) {
437 is_scl_window = TRUE;
438 } else if (elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_magnifier_window())) == ev->window) {
439 is_scl_window = TRUE;
443 window = windows->get_nth_window_in_Z_order_list(index);
444 SclWindowContext *window_context = windows->get_window_context(window);
445 if (window_context) {
446 if (window_context->is_virtual) {
447 is_scl_window = TRUE;
449 } else if ((wl_window = elm_win_wl_window_get(static_cast<Evas_Object*>(window)))) {
450 if ((unsigned int)ecore_wl_window_id_get(wl_window) == ev->window)
451 is_scl_window = TRUE;
453 } else if (elm_win_xwindow_get(static_cast<Evas_Object*>(window)) == ev->window) {
454 is_scl_window = TRUE;
459 } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID);
462 if (!is_scl_window) return TRUE;
464 SclRectangle rect = {0, 0, 0, 0};
466 window = windows->get_nth_window_in_Z_order_list(index);
468 // Update the position of the target window
469 //windows->get_window_context(window, TRUE);
470 SclWindowContext *window_context = windows->get_window_context(window);
471 if (window_context) {
472 windows->get_window_rect(window, &(window_context->geometry));
473 if (get_window_rect(window, &rect)) {
477 if (is_magnifier_window) {
478 SclRectangle magnifier_rect = { 0, 0, 0, 0 };
479 if (get_window_rect(windows->get_magnifier_window(), &magnifier_rect)) {
480 root_x = ev->x + magnifier_rect.x;
481 root_y = ev->y + magnifier_rect.y;
484 root_x = ev->x + rect.x;
485 root_y = ev->y + rect.y;
487 if (window_context->is_virtual) {
488 apply_virtual_offset(rect, &root_x, &root_y);
491 int root_x = ev->root.x;
492 int root_y = ev->root.y;
494 int adjust_x = root_x;
495 int adjust_y = root_y;
497 SclResParserManager *sclres_manager = SclResParserManager::get_instance();
498 PSclDefaultConfigure default_configure = NULL;
499 if (sclres_manager) {
500 default_configure = sclres_manager->get_default_configure();
503 if (default_configure) {
504 SCLDisplayMode display_mode = context->get_display_mode();
505 if (scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
506 adjustment->apply_touch_offset(
507 default_configure->touch_offset_level[display_mode],
508 &adjust_x, &adjust_y);
512 sclint win_width = rect.width;
513 sclint win_height = rect.height;
514 if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
515 rect.height = win_width;
516 rect.width = win_height;
519 /* Check whether will-be-adjusted coordinate is within the window area */
520 sclboolean process_event = FALSE;
521 if ((adjust_x >= rect.x && adjust_x <= (rect.x + win_width)) &&
522 (adjust_y >= rect.y && adjust_y <= (rect.y + win_height))) {
523 process_event = TRUE;
526 /* Now convert the global coordinate to appropriate local coordinate */
527 SclPoint coords = get_rotated_local_coords(
528 root_x, root_y, context->get_rotation(), &rect);
529 controller->mouse_press(window, coords.x, coords.y, ev->multi.device);
530 mouse_pressed = TRUE;
532 pressed_window = window;
538 } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed);
541 window = pressed_window;
542 SclWindowContext *window_context = windows->get_window_context(window);
543 if (window_context && get_window_rect(window, &rect)) {
544 if (context->get_rotation() == ROTATION_90_CW || context->get_rotation() == ROTATION_90_CCW) {
545 sclint temp = rect.width;
546 rect.width = rect.height;
550 // Now convert the global coordinate to appropriate local coordinate
552 int root_x = ev->x + rect.x;
553 int root_y = ev->y + rect.y;
554 if (window_context->is_virtual) {
555 apply_virtual_offset(rect, &root_x, &root_y);
558 int root_x = ev->root.x;
559 int root_y = ev->root.y;
562 SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
563 controller->mouse_press(window, coords.x, coords.y, ev->multi.device);
564 mouse_pressed = TRUE;
572 /*CSCLContext *context = CSCLContext::get_instance();
573 controller->mouse_press((sclwindow)data, ev->output.x, ev->output.y);
574 mouse_pressed = TRUE;*/
576 //LOGD("=-=-=-=- mouse_press : %p %d %d\n", data, ev->output.x, ev->output.y);
579 //void mouse_release (void *data, Evas *e, Evas_Object *object, void *event_info)
580 static Eina_Bool mouse_release(void *data, int type, void *event_info)
584 CSCLController *controller = CSCLController::get_instance();
585 CSCLWindows *windows = CSCLWindows::get_instance();
586 CSCLContext *context = CSCLContext::get_instance();
588 //Evas_Event_Mouse_Up *ev = (Evas_Event_Mouse_Up*)event_info;
589 Ecore_Event_Mouse_Button *ev = (Ecore_Event_Mouse_Button*)event_info;
591 //if (!mouse_pressed) return FALSE;
592 if (ev && check_timestamp_outdated(ev->timestamp)) {
596 if (controller && windows && context && ev) {
597 LOGD("mouse_release : %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y);
600 sclboolean processed = FALSE;
601 sclwindow window = SCLWINDOW_INVALID;
603 sclboolean dimwinevent = FALSE;
604 SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
605 if (dim_window_context) {
606 if (!(dim_window_context->is_virtual)) {
607 if (elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_dim_window())) == ev->window) {
613 controller->mouse_press(windows->get_dim_window(), ev->root.x, ev->root.y, ev->multi.device);
616 window = windows->get_nth_window_in_Z_order_list(index);
618 SclWindowContext *window_context = windows->get_window_context(window);
619 if (window_context) {
620 windows->get_window_rect(window, &(window_context->geometry));
621 if (get_window_rect(window, &rect)) {
625 Ecore_Wl_Window *wl_magnifier_window =
626 (elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_magnifier_window())));
627 if (wl_magnifier_window &&
628 (unsigned int)ecore_wl_window_id_get(wl_magnifier_window) == ev->window) {
629 SclRectangle magnifier_rect = { 0, 0, 0, 0 };
630 if (get_window_rect(windows->get_magnifier_window(), &magnifier_rect)) {
631 root_x = ev->x + magnifier_rect.x;
632 root_y = ev->y + magnifier_rect.y;
635 root_x = ev->x + rect.x;
636 root_y = ev->y + rect.y;
638 if (window_context->is_virtual) {
639 apply_virtual_offset(rect, &root_x, &root_y);
642 int root_x = ev->root.x;
643 int root_y = ev->root.y;
645 int adjust_x = root_x;
646 int adjust_y = root_y;
648 SclResParserManager *sclres_manager = SclResParserManager::get_instance();
649 PSclDefaultConfigure default_configure = NULL;
650 if (sclres_manager) {
651 default_configure = sclres_manager->get_default_configure();
654 if (default_configure) {
655 SCLDisplayMode display_mode = context->get_display_mode();
656 CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
657 if (adjustment && scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
658 adjustment->apply_touch_offset(
659 default_configure->touch_offset_level[display_mode],
660 &adjust_x, &adjust_y);
664 sclint win_width = rect.width;
665 sclint win_height = rect.height;
666 if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
667 rect.height = win_width;
668 rect.width = win_height;
671 /* Check whether will-be-adjusted coordinate is within the window area */
672 sclboolean process_event = FALSE;
673 if ((adjust_x >= rect.x && adjust_x <= (rect.x + win_width)) &&
674 (adjust_y >= rect.y && adjust_y <= (rect.y + win_height))) {
675 process_event = TRUE;
678 /* Now convert the global coordinate to appropriate local coordinate */
679 SclPoint coords = get_rotated_local_coords(
680 root_x, root_y, context->get_rotation(), &rect);
681 controller->mouse_release(window, coords.x, coords.y, ev->multi.device);
688 } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed);
692 window = pressed_window;
693 SclWindowContext *window_context = windows->get_window_context(window);
694 if (window_context && get_window_rect(window, &rect)) {
695 if (context->get_rotation() == ROTATION_90_CW || context->get_rotation() == ROTATION_90_CCW) {
696 sclint temp = rect.width;
697 rect.width = rect.height;
701 /* Now convert the global coordinate to appropriate local coordinate */
703 int root_x = ev->x + rect.x;
704 int root_y = ev->y + rect.y;
705 if (window_context->is_virtual) {
706 apply_virtual_offset(rect, &root_x, &root_y);
709 int root_x = ev->root.x;
710 int root_y = ev->root.y;
713 SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
714 controller->mouse_release(window, coords.x, coords.y, ev->multi.device);
719 mouse_pressed = FALSE;
723 //CSCLController *controller = CSCLController::get_instance();
724 //CSCLWindows *windows = CSCLWindows::get_instance();
725 //controller->mouse_release((sclwindow)data, (int)ev->output.x, (int)ev->output.y);
726 //controller->mouse_release((sclwindow)data, (int)ev->x, (int)ev->y);
729 #ifdef HANDLE_KEY_EVENTS
730 static Eina_Bool key_pressed(void *data, int type, void *event_info)
732 LOGD("=-=-=-=- key_pressed \n");
733 CSCLController *controller = CSCLController::get_instance();
734 Ecore_Event_Key *ev = (Ecore_Event_Key *)event_info;
735 const char *ckey_val = ev->key;
736 LOGD("=-=-=-=- ev->key(char) = %c \n", ev->key);
737 LOGD("=-=-=-=- ev->key(string) = %s \n", ev->key);
738 LOGD("=-=-=-=- ev->keyname(char) = %c \n", ev->keyname);
739 LOGD("=-=-=-=- ev->keyname(string) = %s \n", ev->keyname);
740 LOGD("=-=-=-=- ev->string(char) = %c \n", ev->string);
741 LOGD("=-=-=-=- ev->string(string) = %s \n", ev->string);
743 CSCLResourceCache *cache = CSCLResourceCache::get_instance();
744 SclButtonContext *prev_button_context = NULL;
745 const SclLayoutKeyCoordinate *prevcoordinate = NULL;
746 SclButtonContext *button_context = NULL;
747 const SclLayoutKeyCoordinate *coordinate = NULL;
749 CSCLWindows *windows = CSCLWindows::get_instance();
750 sclwindow window = windows->get_base_window();
751 CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
753 sclbyte current_key_index = focus_handler->get_current_key_index();
754 sclbyte key_index = current_key_index;
756 if (strcmp(ev->keyname, "Right") == 0) {
757 key_index = focus_handler->get_next_key_index(NAVIGATE_RIGHT);
758 } else if (strcmp(ev->keyname, "Left") == 0) {
759 key_index = focus_handler->get_next_key_index(NAVIGATE_LEFT);
760 } else if (strcmp(ev->keyname, "Up") == 0) {
761 key_index = focus_handler->get_next_key_index(NAVIGATE_UP);
762 } else if (strcmp(ev->keyname, "Down") == 0) {
763 key_index = focus_handler->get_next_key_index(NAVIGATE_DOWN);
764 } else if ((strcmp(ev->keyname, "Return") == 0) || (strcmp(ev->keyname, "Enter") == 0)) {
765 button_context = cache->get_cur_button_context(window, current_key_index);
766 coordinate = cache->get_cur_layout_key_coordinate(window, current_key_index);
767 button_context->state = BUTTON_STATE_NORMAL;
768 controller->mouse_press(window, coordinate->x, coordinate->y, TRUE);
769 controller->mouse_release(window, coordinate->x, coordinate->y, TRUE);
770 if (KEY_TYPE_MODECHANGE != coordinate->key_type) {
771 button_context->state = BUTTON_STATE_PRESSED;
772 windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
774 focus_handler->init_key_index();
779 if (current_key_index != key_index) {
780 button_context = cache->get_cur_button_context(window, key_index);
781 prev_button_context = cache->get_cur_button_context(window, current_key_index);
782 prevcoordinate = cache->get_cur_layout_key_coordinate(window, current_key_index);
783 coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
784 prev_button_context->state = BUTTON_STATE_NORMAL;
785 button_context->state = BUTTON_STATE_PRESSED;
786 sclshort x, y, width, height;
787 if (prevcoordinate->x < coordinate->x) {
788 x = prevcoordinate->x;
793 if (prevcoordinate->y < coordinate->y) {
794 y = prevcoordinate->y;
799 if (prevcoordinate->x + prevcoordinate->width > coordinate->x + coordinate->width) {
800 width = prevcoordinate->x + prevcoordinate->width - x;
802 width = coordinate->x + coordinate->width - x;
805 if (prevcoordinate->y + prevcoordinate->height > coordinate->y + coordinate->height) {
806 height = prevcoordinate->y + prevcoordinate->height - y;
808 height = coordinate->y + coordinate->height - y;
810 windows->update_window(window, x, y, width, height);
817 #endif /*HANDLE_KEY_EVENTS*/
819 //int mouse_move (void *data, Evas *e, Evas_Object *object, void *event_info)
820 static Eina_Bool mouse_move(void *data, int type, void *event_info)
824 CSCLController *controller = CSCLController::get_instance();
825 CSCLWindows *windows = CSCLWindows::get_instance();
826 CSCLContext *context = CSCLContext::get_instance();
827 CSCLResourceCache *cache = CSCLResourceCache::get_instance();
829 //Evas_Event_Mouse_Move *ev = (Evas_Event_Mouse_Move*)event_info;
830 Ecore_Event_Mouse_Move *ev = (Ecore_Event_Mouse_Move*)event_info;
832 //if (!mouse_pressed) return FALSE;
833 if (ev && check_timestamp_outdated(ev->timestamp)) {
837 if (controller && windows && context && cache && ev) {
839 sclboolean processed = FALSE;
840 sclwindow window = SCLWINDOW_INVALID;
843 LOGD("mouse_move : %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y);
845 if (context->get_cur_pressed_window(ev->multi.device) != SCLWINDOW_INVALID &&
846 get_window_rect(context->get_cur_pressed_window(ev->multi.device), &rect)) {
847 sclint winwidth = rect.width;
848 sclint winheight = rect.height;
849 if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
850 rect.height = winwidth;
851 rect.width = winheight;
857 Ecore_Wl_Window *wl_base_window =
858 elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
859 Ecore_Wl_Window *wl_magnifier_window =
860 (elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_magnifier_window())));
861 if (wl_base_window && (unsigned int)ecore_wl_window_id_get(wl_base_window) == ev->window) {
862 SclRectangle base_rect;
863 get_window_rect(windows->get_base_window(), &base_rect);
864 root_x = ev->x + base_rect.x;
865 root_y = ev->y + base_rect.y;
866 } else if (wl_magnifier_window && (unsigned int)ecore_wl_window_id_get(wl_magnifier_window) == ev->window) {
867 SclRectangle magnifier_rect = { 0, 0, 0, 0 };
868 if (get_window_rect(windows->get_magnifier_window(), &magnifier_rect)) {
869 root_x = ev->x + magnifier_rect.x;
870 root_y = ev->y + magnifier_rect.y;
873 root_x = ev->x + rect.x;
874 root_y = ev->y + rect.y;
877 int root_x = ev->root.x;
878 int root_y = ev->root.y;
881 SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
883 controller->mouse_move(context->get_cur_pressed_window(ev->multi.device), coords.x, coords.y, ev->multi.device);
887 window = windows->get_nth_window_in_Z_order_list(index);
889 SclWindowContext *window_context = windows->get_window_context(window);
890 if (window_context) {
891 windows->get_window_rect(window, &(window_context->geometry));
892 if (get_window_rect(window, &rect)) {
894 int root_x = ev->x + rect.x;
895 int root_y = ev->y + rect.y;
896 if (window_context->is_virtual) {
897 apply_virtual_offset(rect, &root_x, &root_y);
900 int root_x = ev->root.x;
901 int root_y = ev->root.y;
903 int adjust_x = root_x;
904 int adjust_y = root_y;
906 SclResParserManager *sclres_manager = SclResParserManager::get_instance();
907 PSclDefaultConfigure default_configure = NULL;
908 if (sclres_manager) {
909 default_configure = sclres_manager->get_default_configure();
911 if (default_configure) {
912 SCLDisplayMode display_mode = context->get_display_mode();
913 CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
914 if (adjustment && scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
915 adjustment->apply_touch_offset(
916 default_configure->touch_offset_level[display_mode],
917 &adjust_x, &adjust_y);
921 sclint win_width = rect.width;
922 sclint win_height = rect.height;
923 if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
924 rect.height = win_width;
925 rect.width = win_height;
928 sclboolean process_event = FALSE;
929 if ((adjust_x >= rect.x && adjust_x <= (rect.x + win_width)) &&
930 (adjust_y >= rect.y && adjust_y <= (rect.y + win_height))) {
931 process_event = TRUE;
933 /* Process this event regardless of the coordinate if the top window has the POPUP_GRAB layout style */
934 if (index == SCL_WINDOW_Z_TOP) {
935 const SclLayout *layout = cache->get_cur_layout(window);
937 if (layout->style == LAYOUT_STYLE_POPUP_GRAB) {
938 process_event = TRUE;
943 /* Now convert the global coordinate to appropriate local coordinate */
944 SclPoint coords = get_rotated_local_coords(
945 root_x, root_y, context->get_rotation(), &rect);
946 controller->mouse_move(window, coords.x, coords.y, ev->multi.device);
953 } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed);
957 window = pressed_window;
958 SclWindowContext *window_context = windows->get_window_context(window);
959 if (window_context && get_window_rect(window, &rect)) {
960 /* Now convert the global coordinate to appropriate local coordinate */
962 int root_x = ev->x + rect.x;
963 int root_y = ev->y + rect.y;
964 if (window_context->is_virtual) {
965 apply_virtual_offset(rect, &root_x, &root_y);
968 int root_x = ev->root.x;
969 int root_y = ev->root.y;
972 SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
973 controller->mouse_move(window, coords.x, coords.y, ev->multi.device);
978 //CSCLController *controller = CSCLController::get_instance();
979 //CSCLWindows *windows = CSCLWindows::get_instance();
980 //controller->mouse_move((sclwindow)data, (int)ev->cur.output.x, (int)ev->cur.output.y);
981 //controller->mouse_move((sclwindow)data, (int)ev->x, (int)ev->y);
987 * Regists a event callback func to given window.
988 * In this function, it should call several event functions of CSCLController class whenever an event has occurred
989 * The below list shows what event function should be called.
990 * - mouse_press (when the user presses mouse button)
991 * - mouse_release (when the user releases mouse button)
992 * - mouse_move (when the user drags mouse button)
993 * - show_base_layout (when the expost event has occurred)
996 CSCLEventsImplEfl::connect_window_events(const sclwindow wnd, const sclint evt)
1000 //evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_DOWN, mouse_press, NULL);
1001 /*evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_UP, mouse_release, NULL);
1002 evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_MOVE, mouse_move, NULL);*/
1007 client_message_cb(void *data, int type, void *event)
1009 Ecore_X_Event_Client_Message *ev = (Ecore_X_Event_Client_Message *)event;
1010 if (ev->message_type == ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL) {
1011 CSCLWindows *windows = CSCLWindows::get_instance();
1012 CSCLController *controller = CSCLController::get_instance();
1014 static int last_pos_x = -10000;
1015 static int last_pos_y = -10000;
1017 if (windows && controller) {
1018 Evas_Object *base_win = (Evas_Object *)windows->get_base_window();
1019 if (base_win == NULL) return FALSE;
1021 if ((unsigned int)ev->data.l[0] == elm_win_xwindow_get(base_win)) {
1022 if ((unsigned int)ev->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE) {
1023 // 1 finger double tap
1024 controller->mouse_press(base_win, last_pos_x, last_pos_y);
1025 controller->mouse_release(base_win, last_pos_x, last_pos_y);
1026 } else if ((unsigned int)ev->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ) {
1028 // 1 finger touch & move
1029 last_pos_x = ev->data.l[2];
1030 last_pos_y = ev->data.l[3];
1031 controller->mouse_over(base_win, last_pos_x, last_pos_y);
1036 return ECORE_CALLBACK_PASS_ON;
1040 Eina_Bool timer_event(void *data)
1043 CSCLUtils *utils = CSCLUtils::get_instance();
1044 CSCLController *controller = CSCLController::get_instance();
1046 scl32 sendData = static_cast<scl32>(reinterpret_cast<uintptr_t>(data) & 0xffffffff);
1048 if (controller && utils) {
1049 scl16 id = SCL_LOWORD(sendData); /* Timer ID */
1050 Eina_Bool ret = controller->timer_event(sendData);
1052 utils->log("Returning Timer : %d %d\n", id, ret);
1061 * In this function, it should call timer_event of CSCLController class
1064 CSCLEventsImplEfl::create_timer(const scl16 id, const scl32 interval, scl16 value, sclboolean addToMap)
1067 sclint data = SCL_MAKELONG(id, value);
1068 Ecore_Timer *pTimer = ecore_timer_add((double)interval / 1000.0, timer_event, (void*)data);
1070 CSCLUtils *utils = CSCLUtils::get_instance();
1072 utils->log("Created Timer : %d %p\n", id, pTimer);
1081 * Destroys the given ID's timer
1084 CSCLEventsImplEfl::destroy_timer(const scl32 id)
1087 //for ( std::map<int, Ecore_Timer*>::iterator idx = idMap.begin(); idx != idMap.end(); ++idx) {
1088 std::map<int, Ecore_Timer*>::iterator idx = idMap.find(id);
1089 //if ((*idx).first == id) {
1090 if (idx != idMap.end()) {
1091 CSCLUtils *utils = CSCLUtils::get_instance();
1093 utils->log("Destroyed Timer : %d %p\n", (*idx).first, (*idx).second);
1095 ecore_timer_del((*idx).second);
1096 idMap.erase((*idx).first);
1103 * Destroys all of created timer
1106 CSCLEventsImplEfl::destroy_all_timer()
1109 for ( std::map<int, Ecore_Timer*>::iterator idx = idMap.begin(); idx != idMap.end(); ++idx ) {
1110 ecore_timer_del((*idx).second);
1112 CSCLUtils *utils = CSCLUtils::get_instance();
1114 utils->log("Destroyed Timer : %d %p\n", (*idx).first, (*idx).second);
1121 CSCLEventsImplEfl::generate_mouse_event(SCLMouseEvent type, scl16 x, scl16 y)
1123 CSCLWindows *windows = CSCLWindows::get_instance();
1124 SclWindowContext *window_context = NULL;
1126 static const sclint MAX_DEVICES = 100;
1127 static sclboolean pressed[MAX_DEVICES] = { FALSE };
1130 case SCL_MOUSE_EVENT_PRESS:
1132 sclboolean generated = FALSE;
1133 for (sclint loop = 0; !generated && loop < MAX_DEVICES; loop++) {
1134 if (pressed[loop] != TRUE) {
1135 pressed[loop] = TRUE;
1136 Ecore_Event_Mouse_Button evt;
1138 Ecore_Wl_Window *wl_base_window;
1139 wl_base_window = elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
1141 evt.window = (unsigned int)ecore_wl_window_id_get(wl_base_window);
1143 evt.window = elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window()));
1145 //window_context = windows->get_window_context(windows->get_base_window(), FALSE);
1146 window_context = windows->get_window_context(windows->get_base_window());
1147 if (window_context) {
1148 evt.root.x = x + window_context->geometry.x;
1149 evt.root.y = y + window_context->geometry.y;
1150 evt.multi.device = loop;
1151 mouse_press(NULL, 0, &evt);
1158 case SCL_MOUSE_EVENT_RELEASE:
1160 sclboolean generated = FALSE;
1161 for (sclint loop = 0; !generated && loop < MAX_DEVICES; loop++) {
1162 if (pressed[loop] == TRUE) {
1163 pressed[loop] = FALSE;
1164 Ecore_Event_Mouse_Button evt;
1166 Ecore_Wl_Window *wl_base_window;
1167 wl_base_window = elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
1169 evt.window = (unsigned int)ecore_wl_window_id_get(wl_base_window);
1171 evt.window = elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window()));
1173 //window_context = windows->get_window_context(windows->get_base_window(), FALSE);
1174 window_context = windows->get_window_context(windows->get_base_window());
1175 if (window_context) {
1176 evt.root.x = x + window_context->geometry.x;
1177 evt.root.y = y + window_context->geometry.y;
1178 evt.multi.device = loop;
1179 mouse_release(NULL, 0, &evt);
1186 case SCL_MOUSE_EVENT_MOVE:
1188 sclboolean generated = FALSE;
1189 for (sclint loop = 0; !generated && loop < MAX_DEVICES; loop++) {
1190 if (pressed[loop] == TRUE) {
1191 Ecore_Event_Mouse_Move evt;
1193 Ecore_Wl_Window *wl_base_window;
1194 wl_base_window = elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
1196 evt.window = (unsigned int)ecore_wl_window_id_get(wl_base_window);
1198 evt.window = elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window()));
1200 //window_context = windows->get_window_context(windows->get_base_window(), FALSE);
1201 window_context = windows->get_window_context(windows->get_base_window());
1202 if (window_context) {
1203 evt.root.x = x + window_context->geometry.x;
1204 evt.root.y = y + window_context->geometry.y;
1205 evt.multi.device = loop;
1206 mouse_move(NULL, 0, &evt);