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 static Eldbus_Object *eldbus_bus_obj = NULL;
53 typedef enum _Gesture {
55 ONE_FINGER_SINGLE_TAP = 15,
56 ONE_FINGER_DOUBLE_TAP = 16
61 Gesture type; // Type of recognized gesture
67 static sclboolean mouse_pressed = FALSE; /* Checks whether mouse is pressed or not */
68 static sclwindow pressed_window = SCLWINDOW_INVALID;
70 /* If the gap between two timestamps are bigger than 1 sec, do not compare */
71 const unsigned int _touch_event_timestamp_compare_range = 1000;
72 /* If the gap between two timestamps are smaller than 50 msec, do not process */
73 const unsigned int _touch_event_timestamp_valid_threshold = 50;
74 extern unsigned int g_timestamp_last_base_window_resized;
76 #define MIN_XY_DIFF 14
78 static Eina_Bool mouse_press(void *data, int type, void *event_info);
79 static Eina_Bool mouse_move(void *data, int type, void *event_info);
80 static Eina_Bool mouse_release(void *data, int type, void *event_info);
83 static Eina_Bool client_message_cb(void *data, int type, void *event);
86 #ifdef HANDLE_KEY_EVENTS
87 static Eina_Bool key_pressed(void *data, int type, void *event_info);
90 static sclboolean get_window_rect(const sclwindow window, SclRectangle *rect)
93 sclboolean ret = FALSE;
94 CSCLUtils *utils = CSCLUtils::get_instance();
95 CSCLWindows *windows = CSCLWindows::get_instance();
96 CSCLContext *context = CSCLContext::get_instance();
97 if (windows && context && utils && rect) {
98 SclWindowContext *window_context = windows->get_window_context(window);
100 /* get window size */
101 if (window_context && utils->get_screen_resolution(&scr_w, &scr_h)) {
102 switch (context->get_rotation()) {
105 rect->height = window_context->geometry.width;
106 rect->width = window_context->geometry.height;
107 rect->y = scr_w - rect->height - window_context->geometry.x;
108 rect->x = window_context->geometry.y;
113 rect->width = window_context->geometry.width;
114 rect->height = window_context->geometry.height;
115 rect->x = scr_w - window_context->geometry.x - rect->width;
116 rect->y = scr_h - window_context->geometry.y - rect->height;
119 case ROTATION_90_CCW:
121 rect->height = window_context->geometry.width;
122 rect->width = window_context->geometry.height;
123 rect->y = window_context->geometry.x;
124 rect->x = scr_h - window_context->geometry.y - rect->width;
129 rect->x = window_context->geometry.x;
130 rect->y = window_context->geometry.y;
131 rect->width = window_context->geometry.width;
132 rect->height = window_context->geometry.height;
138 rect->x = rect->y = rect->width = rect->height = 0;
145 /* In wayland, root.x / root.y is not available, so need to apply virtual offset
146 when event occurred on a virtual window */
147 static void apply_virtual_offset(SclRectangle rect, int *adjustx, int *adjusty)
149 int virtual_offset_x = 0;
150 int virtual_offset_y = 0;
151 SclRectangle base_rect = {0, 0, 0, 0};
153 CSCLWindows *windows = CSCLWindows::get_instance();
155 if (get_window_rect(windows->get_base_window(), &base_rect)) {
156 virtual_offset_x = rect.x - base_rect.x;
157 virtual_offset_y = rect.y - base_rect.y;
159 if (adjustx && adjusty) {
160 *adjustx -= virtual_offset_x;
161 *adjusty -= virtual_offset_y;
170 CSCLEventsImplEfl::CSCLEventsImplEfl()
174 m_mouse_down_handler = NULL;
175 m_mouse_move_handler = NULL;
176 m_mouse_up_handler = NULL;
179 m_xclient_msg_handler = NULL;
181 m_key_pressed_handler = NULL;
185 static void gesture_cb(void *data, const Eldbus_Message *msg)
187 LOGD("GestureDetected callback");
189 static int last_pos_x = -1;
190 static int last_pos_y = -1;
193 LOGD("Incoming message is empty");
196 CSCLController *controller = CSCLController::get_instance();
197 CSCLWindows *windows = CSCLWindows::get_instance();
199 if (!windows || !controller) return;
201 sclwindow base_window = windows->get_base_window();
202 SclWindowContext *window_context = windows->get_window_context(base_window);
204 if (!window_context) return;
205 if (window_context->hidden) return;
207 LOGD("window_context->geometry.x=%d y=%d w=%d h=%d",
208 window_context->geometry.x, window_context->geometry.y,
209 window_context->geometry.width, window_context->geometry.height);
211 Gesture_Info *info = (Gesture_Info *)calloc(sizeof(Gesture_Info), 1);
213 LOGD("Memory alloc failed for Gesture_Info");
216 if (!eldbus_message_arguments_get(msg, "iii", &g_type, &info->x,
218 LOGD("Getting message arguments failed");
223 info->type = (Gesture)g_type;
224 LOGD("Incoming gesture name is %d : %d %d", info->type, info->x, info->y);
226 if (info->type == ONE_FINGER_HOVER || info->type == ONE_FINGER_SINGLE_TAP) {
227 if (info->y >= window_context->geometry.y) {
228 last_pos_x = info->x;
229 last_pos_y = info->y - window_context->geometry.y;
230 LOGD("hover last_pos_x=%d last_pos_y=%d", last_pos_x, last_pos_y);
231 controller->mouse_over(base_window, last_pos_x, last_pos_y);
233 } else if (info->type == ONE_FINGER_DOUBLE_TAP) {
234 if (info->y >= window_context->geometry.y) {
235 last_pos_x = info->x;
236 last_pos_y = info->y - window_context->geometry.y;
237 LOGD("double last_pos_x=%d last_pos_y=%d", last_pos_x, last_pos_y);
238 controller->mouse_press(base_window, last_pos_x, last_pos_y);
239 controller->mouse_release(base_window, last_pos_x, last_pos_y);
245 static void gestures_tracker_register()
247 Eldbus_Proxy *proxy = NULL;
253 LOGD("Registering callback for GestureDetected signal");
254 if (!(eldbus_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION))) {
255 LOGW("Error: Unable to get session bus");
259 eldbus_bus_obj = eldbus_object_get(eldbus_conn, E_KEYBOARD_SERVICE_BUS_NAME, E_KEYBOARD_SERVICE_NAVI_OBJ_PATH);
260 if (!eldbus_bus_obj) {
261 LOGW("Error: Getting object failed");
265 proxy = eldbus_proxy_get(eldbus_bus_obj, E_KEYBOARD_SERVICE_NAVI_IFC_NAME);
267 LOGW("Error: Getting proxy failed");
271 if (!eldbus_proxy_signal_handler_add(proxy, "KBGestureDetected", gesture_cb, NULL))
272 LOGW("No signal handler returned");
274 LOGD("Callback registration successful");
278 eldbus_object_unref(eldbus_bus_obj);
279 eldbus_bus_obj = NULL;
281 eldbus_connection_unref(eldbus_conn);
285 static void gestures_tracker_unregister()
287 if (eldbus_bus_obj) {
288 eldbus_object_unref(eldbus_bus_obj);
289 eldbus_bus_obj = NULL;
293 eldbus_connection_unref(eldbus_conn);
303 CSCLEventsImplEfl::~CSCLEventsImplEfl()
310 void CSCLEventsImplEfl::init()
312 /* Initializes all window resources */
313 m_mouse_down_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, mouse_press, NULL);
314 m_mouse_move_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, mouse_move, NULL);
315 m_mouse_up_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, mouse_release, NULL);
318 m_xclient_msg_handler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, client_message_cb, NULL);
320 gestures_tracker_register();
323 #ifdef HANDLE_KEY_EVENTS
324 m_key_pressed_handler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, key_pressed, NULL);
328 void CSCLEventsImplEfl::fini()
330 if (m_mouse_down_handler) ecore_event_handler_del(m_mouse_down_handler);
331 m_mouse_down_handler = NULL;
332 if (m_mouse_move_handler) ecore_event_handler_del(m_mouse_move_handler);
333 m_mouse_move_handler = NULL;
334 if (m_mouse_up_handler) ecore_event_handler_del(m_mouse_up_handler);
335 m_mouse_up_handler = NULL;
336 #ifdef HANDLE_KEY_EVENTS
337 if (m_key_pressed_handler) ecore_event_handler_del(m_key_pressed_handler);
339 m_key_pressed_handler = NULL;
341 if (m_xclient_msg_handler) ecore_event_handler_del(m_xclient_msg_handler);
343 gestures_tracker_unregister();
347 /** Here x and y contains "actual" x and y position relative to portrait root window,
348 and window_context->width,height contains the window's orientation dependant width and height */
349 SclPoint get_rotated_local_coords(sclint x, sclint y, SCLRotation rotation, SclRectangle *rect) {
350 SclPoint ret = {0, 0};
356 ret.x = (rect->y + rect->width) - y;
362 ret.x = (rect->x + rect->width) - x;
363 ret.y = (rect->y + rect->height) - y;
366 case ROTATION_90_CCW:
369 ret.y = (rect->x + rect->height) - x;
383 static Eina_Bool check_timestamp_outdated(unsigned int timestamp)
385 /* Skip events that were generated nearly at the same time when our base window resized */
386 timestamp -= _touch_event_timestamp_valid_threshold;
387 unsigned int gap = (g_timestamp_last_base_window_resized > timestamp) ?
388 (g_timestamp_last_base_window_resized - timestamp) :
389 (timestamp - g_timestamp_last_base_window_resized);
390 if (gap < _touch_event_timestamp_compare_range) {
391 if (g_timestamp_last_base_window_resized > timestamp) {
392 /* This event was generated before the base window resize event, ignore */
393 LOGD("Skipping event since turned out to be outdated : %u, %u",
394 g_timestamp_last_base_window_resized, timestamp);
401 //void mouse_press (void *data, Evas *e, Evas_Object *object, void *event_info)
402 static Eina_Bool mouse_press(void *data, int type, void *event_info)
406 Ecore_Wl_Window *wl_base_window;
407 Ecore_Wl_Window *wl_magnifier_window;
408 Ecore_Wl_Window *wl_window;
411 CSCLController *controller = CSCLController::get_instance();
412 CSCLWindows *windows = CSCLWindows::get_instance();
413 CSCLContext *context = CSCLContext::get_instance();
414 CSCLUtils *utils = CSCLUtils::get_instance();
415 CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
417 Ecore_Event_Mouse_Button *ev = (Ecore_Event_Mouse_Button*)event_info;
419 if (ev && check_timestamp_outdated(ev->timestamp)) {
423 if (controller && windows && context && utils && adjustment && ev) {
424 LOGD("mouse_press : %d %d, %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y,
425 g_timestamp_last_base_window_resized, ev->timestamp);
428 sclboolean processed = FALSE;
429 sclwindow window = SCLWINDOW_INVALID;
432 Ecore_X_Window inputWindow = 0;
433 Ecore_X_Atom inputAtom = ecore_x_atom_get("DeviceMgr Input Window");
434 ecore_x_window_prop_xid_get(ecore_x_window_root_first_get(),
435 inputAtom, ECORE_X_ATOM_WINDOW, &inputWindow, 1);
436 if (inputWindow == 0) {
437 utils->log("Error : input window NULL!");
440 unsigned int touch_input = 0;
441 int res = ecore_x_window_prop_card32_get(inputWindow,
442 ecore_x_atom_get(E_PROP_TOUCH_INPUT), &touch_input, 1);
444 utils->log("E_PROP_TOUCH_INPUT : %d %d\n", res, touch_input);
447 if (1 == touch_input) {
448 adjustment->enable_touch_offset(TRUE);
449 } else if (0 == touch_input) {
450 adjustment->enable_touch_offset(FALSE);
454 sclboolean is_scl_window = FALSE;
456 sclboolean is_magnifier_window = FALSE;
457 wl_base_window = elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
458 wl_magnifier_window = (elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_magnifier_window())));
459 if (wl_base_window && (unsigned int)ecore_wl_window_id_get(wl_base_window) == ev->window) {
460 is_scl_window = TRUE;
461 } else if (wl_magnifier_window && (unsigned int)ecore_wl_window_id_get(wl_magnifier_window) == ev->window) {
462 is_scl_window = TRUE;
463 is_magnifier_window = TRUE;
465 if (elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window())) == ev->window) {
466 is_scl_window = TRUE;
467 } else if (elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_magnifier_window())) == ev->window) {
468 is_scl_window = TRUE;
472 window = windows->get_nth_window_in_Z_order_list(index);
473 SclWindowContext *window_context = windows->get_window_context(window);
474 if (window_context) {
475 if (window_context->is_virtual) {
476 is_scl_window = TRUE;
478 } else if ((wl_window = elm_win_wl_window_get(static_cast<Evas_Object*>(window)))) {
479 if ((unsigned int)ecore_wl_window_id_get(wl_window) == ev->window)
480 is_scl_window = TRUE;
482 } else if (elm_win_xwindow_get(static_cast<Evas_Object*>(window)) == ev->window) {
483 is_scl_window = TRUE;
488 } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID);
491 if (!is_scl_window) return TRUE;
493 SclRectangle rect = {0, 0, 0, 0};
495 window = windows->get_nth_window_in_Z_order_list(index);
497 // Update the position of the target window
498 //windows->get_window_context(window, TRUE);
499 SclWindowContext *window_context = windows->get_window_context(window);
500 if (window_context) {
501 windows->get_window_rect(window, &(window_context->geometry));
502 if (get_window_rect(window, &rect)) {
506 if (is_magnifier_window) {
507 SclRectangle magnifier_rect = { 0, 0, 0, 0 };
508 if (get_window_rect(windows->get_magnifier_window(), &magnifier_rect)) {
509 root_x = ev->x + magnifier_rect.x;
510 root_y = ev->y + magnifier_rect.y;
513 root_x = ev->x + rect.x;
514 root_y = ev->y + rect.y;
516 if (window_context->is_virtual) {
517 apply_virtual_offset(rect, &root_x, &root_y);
520 int root_x = ev->root.x;
521 int root_y = ev->root.y;
523 int adjust_x = root_x;
524 int adjust_y = root_y;
526 SclResParserManager *sclres_manager = SclResParserManager::get_instance();
527 PSclDefaultConfigure default_configure = NULL;
528 if (sclres_manager) {
529 default_configure = sclres_manager->get_default_configure();
532 if (default_configure) {
533 SCLDisplayMode display_mode = context->get_display_mode();
534 if (scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
535 adjustment->apply_touch_offset(
536 default_configure->touch_offset_level[display_mode],
537 &adjust_x, &adjust_y);
541 sclint win_width = rect.width;
542 sclint win_height = rect.height;
543 if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
544 rect.height = win_width;
545 rect.width = win_height;
548 /* Check whether will-be-adjusted coordinate is within the window area */
549 sclboolean process_event = FALSE;
550 if ((adjust_x >= rect.x && adjust_x <= (rect.x + win_width)) &&
551 (adjust_y >= rect.y && adjust_y <= (rect.y + win_height))) {
552 process_event = TRUE;
555 /* Now convert the global coordinate to appropriate local coordinate */
556 SclPoint coords = get_rotated_local_coords(
557 root_x, root_y, context->get_rotation(), &rect);
558 controller->mouse_press(window, coords.x, coords.y, ev->multi.device);
559 mouse_pressed = TRUE;
561 pressed_window = window;
567 } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed);
570 window = pressed_window;
571 SclWindowContext *window_context = windows->get_window_context(window);
572 if (window_context && get_window_rect(window, &rect)) {
573 if (context->get_rotation() == ROTATION_90_CW || context->get_rotation() == ROTATION_90_CCW) {
574 sclint temp = rect.width;
575 rect.width = rect.height;
579 // Now convert the global coordinate to appropriate local coordinate
581 int root_x = ev->x + rect.x;
582 int root_y = ev->y + rect.y;
583 if (window_context->is_virtual) {
584 apply_virtual_offset(rect, &root_x, &root_y);
587 int root_x = ev->root.x;
588 int root_y = ev->root.y;
591 SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
592 controller->mouse_press(window, coords.x, coords.y, ev->multi.device);
593 mouse_pressed = TRUE;
601 /*CSCLContext *context = CSCLContext::get_instance();
602 controller->mouse_press((sclwindow)data, ev->output.x, ev->output.y);
603 mouse_pressed = TRUE;*/
605 //LOGD("=-=-=-=- mouse_press : %p %d %d\n", data, ev->output.x, ev->output.y);
608 //void mouse_release (void *data, Evas *e, Evas_Object *object, void *event_info)
609 static Eina_Bool mouse_release(void *data, int type, void *event_info)
613 CSCLController *controller = CSCLController::get_instance();
614 CSCLWindows *windows = CSCLWindows::get_instance();
615 CSCLContext *context = CSCLContext::get_instance();
617 //Evas_Event_Mouse_Up *ev = (Evas_Event_Mouse_Up*)event_info;
618 Ecore_Event_Mouse_Button *ev = (Ecore_Event_Mouse_Button*)event_info;
620 //if (!mouse_pressed) return FALSE;
621 if (ev && check_timestamp_outdated(ev->timestamp)) {
625 if (controller && windows && context && ev) {
626 LOGD("mouse_release : %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y);
629 sclboolean processed = FALSE;
630 sclwindow window = SCLWINDOW_INVALID;
632 sclboolean dimwinevent = FALSE;
633 SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
634 if (dim_window_context) {
635 if (!(dim_window_context->is_virtual)) {
636 if (elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_dim_window())) == ev->window) {
642 controller->mouse_press(windows->get_dim_window(), ev->root.x, ev->root.y, ev->multi.device);
645 window = windows->get_nth_window_in_Z_order_list(index);
647 SclWindowContext *window_context = windows->get_window_context(window);
648 if (window_context) {
649 windows->get_window_rect(window, &(window_context->geometry));
650 if (get_window_rect(window, &rect)) {
654 Ecore_Wl_Window *wl_magnifier_window =
655 (elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_magnifier_window())));
656 if (wl_magnifier_window &&
657 (unsigned int)ecore_wl_window_id_get(wl_magnifier_window) == ev->window) {
658 SclRectangle magnifier_rect = { 0, 0, 0, 0 };
659 if (get_window_rect(windows->get_magnifier_window(), &magnifier_rect)) {
660 root_x = ev->x + magnifier_rect.x;
661 root_y = ev->y + magnifier_rect.y;
664 root_x = ev->x + rect.x;
665 root_y = ev->y + rect.y;
667 if (window_context->is_virtual) {
668 apply_virtual_offset(rect, &root_x, &root_y);
671 int root_x = ev->root.x;
672 int root_y = ev->root.y;
674 int adjust_x = root_x;
675 int adjust_y = root_y;
677 SclResParserManager *sclres_manager = SclResParserManager::get_instance();
678 PSclDefaultConfigure default_configure = NULL;
679 if (sclres_manager) {
680 default_configure = sclres_manager->get_default_configure();
683 if (default_configure) {
684 SCLDisplayMode display_mode = context->get_display_mode();
685 CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
686 if (adjustment && scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
687 adjustment->apply_touch_offset(
688 default_configure->touch_offset_level[display_mode],
689 &adjust_x, &adjust_y);
693 sclint win_width = rect.width;
694 sclint win_height = rect.height;
695 if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
696 rect.height = win_width;
697 rect.width = win_height;
700 /* Check whether will-be-adjusted coordinate is within the window area */
701 sclboolean process_event = FALSE;
702 if ((adjust_x >= rect.x && adjust_x <= (rect.x + win_width)) &&
703 (adjust_y >= rect.y && adjust_y <= (rect.y + win_height))) {
704 process_event = TRUE;
707 /* Now convert the global coordinate to appropriate local coordinate */
708 SclPoint coords = get_rotated_local_coords(
709 root_x, root_y, context->get_rotation(), &rect);
710 controller->mouse_release(window, coords.x, coords.y, ev->multi.device);
717 } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed);
721 window = pressed_window;
722 SclWindowContext *window_context = windows->get_window_context(window);
723 if (window_context && get_window_rect(window, &rect)) {
724 if (context->get_rotation() == ROTATION_90_CW || context->get_rotation() == ROTATION_90_CCW) {
725 sclint temp = rect.width;
726 rect.width = rect.height;
730 /* Now convert the global coordinate to appropriate local coordinate */
732 int root_x = ev->x + rect.x;
733 int root_y = ev->y + rect.y;
734 if (window_context->is_virtual) {
735 apply_virtual_offset(rect, &root_x, &root_y);
738 int root_x = ev->root.x;
739 int root_y = ev->root.y;
742 SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
743 controller->mouse_release(window, coords.x, coords.y, ev->multi.device);
748 mouse_pressed = FALSE;
752 //CSCLController *controller = CSCLController::get_instance();
753 //CSCLWindows *windows = CSCLWindows::get_instance();
754 //controller->mouse_release((sclwindow)data, (int)ev->output.x, (int)ev->output.y);
755 //controller->mouse_release((sclwindow)data, (int)ev->x, (int)ev->y);
758 #ifdef HANDLE_KEY_EVENTS
759 static Eina_Bool key_pressed(void *data, int type, void *event_info)
761 LOGD("=-=-=-=- key_pressed \n");
762 CSCLController *controller = CSCLController::get_instance();
763 Ecore_Event_Key *ev = (Ecore_Event_Key *)event_info;
764 const char *ckey_val = ev->key;
765 LOGD("=-=-=-=- ev->key(char) = %c \n", ev->key);
766 LOGD("=-=-=-=- ev->key(string) = %s \n", ev->key);
767 LOGD("=-=-=-=- ev->keyname(char) = %c \n", ev->keyname);
768 LOGD("=-=-=-=- ev->keyname(string) = %s \n", ev->keyname);
769 LOGD("=-=-=-=- ev->string(char) = %c \n", ev->string);
770 LOGD("=-=-=-=- ev->string(string) = %s \n", ev->string);
772 CSCLResourceCache *cache = CSCLResourceCache::get_instance();
773 SclButtonContext *prev_button_context = NULL;
774 const SclLayoutKeyCoordinate *prevcoordinate = NULL;
775 SclButtonContext *button_context = NULL;
776 const SclLayoutKeyCoordinate *coordinate = NULL;
778 CSCLWindows *windows = CSCLWindows::get_instance();
779 sclwindow window = windows->get_base_window();
780 CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
782 sclbyte current_key_index = focus_handler->get_current_key_index();
783 sclbyte key_index = current_key_index;
785 if (strcmp(ev->keyname, "Right") == 0) {
786 key_index = focus_handler->get_next_key_index(NAVIGATE_RIGHT);
787 } else if (strcmp(ev->keyname, "Left") == 0) {
788 key_index = focus_handler->get_next_key_index(NAVIGATE_LEFT);
789 } else if (strcmp(ev->keyname, "Up") == 0) {
790 key_index = focus_handler->get_next_key_index(NAVIGATE_UP);
791 } else if (strcmp(ev->keyname, "Down") == 0) {
792 key_index = focus_handler->get_next_key_index(NAVIGATE_DOWN);
793 } else if ((strcmp(ev->keyname, "Return") == 0) || (strcmp(ev->keyname, "Enter") == 0)) {
794 button_context = cache->get_cur_button_context(window, current_key_index);
795 coordinate = cache->get_cur_layout_key_coordinate(window, current_key_index);
796 button_context->state = BUTTON_STATE_NORMAL;
797 controller->mouse_press(window, coordinate->x, coordinate->y, TRUE);
798 controller->mouse_release(window, coordinate->x, coordinate->y, TRUE);
799 if (KEY_TYPE_MODECHANGE != coordinate->key_type) {
800 button_context->state = BUTTON_STATE_PRESSED;
801 windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
803 focus_handler->init_key_index();
808 if (current_key_index != key_index) {
809 button_context = cache->get_cur_button_context(window, key_index);
810 prev_button_context = cache->get_cur_button_context(window, current_key_index);
811 prevcoordinate = cache->get_cur_layout_key_coordinate(window, current_key_index);
812 coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
813 prev_button_context->state = BUTTON_STATE_NORMAL;
814 button_context->state = BUTTON_STATE_PRESSED;
815 sclshort x, y, width, height;
816 if (prevcoordinate->x < coordinate->x) {
817 x = prevcoordinate->x;
822 if (prevcoordinate->y < coordinate->y) {
823 y = prevcoordinate->y;
828 if (prevcoordinate->x + prevcoordinate->width > coordinate->x + coordinate->width) {
829 width = prevcoordinate->x + prevcoordinate->width - x;
831 width = coordinate->x + coordinate->width - x;
834 if (prevcoordinate->y + prevcoordinate->height > coordinate->y + coordinate->height) {
835 height = prevcoordinate->y + prevcoordinate->height - y;
837 height = coordinate->y + coordinate->height - y;
839 windows->update_window(window, x, y, width, height);
846 #endif /*HANDLE_KEY_EVENTS*/
848 //int mouse_move (void *data, Evas *e, Evas_Object *object, void *event_info)
849 static Eina_Bool mouse_move(void *data, int type, void *event_info)
853 CSCLController *controller = CSCLController::get_instance();
854 CSCLWindows *windows = CSCLWindows::get_instance();
855 CSCLContext *context = CSCLContext::get_instance();
856 CSCLResourceCache *cache = CSCLResourceCache::get_instance();
858 //Evas_Event_Mouse_Move *ev = (Evas_Event_Mouse_Move*)event_info;
859 Ecore_Event_Mouse_Move *ev = (Ecore_Event_Mouse_Move*)event_info;
861 //if (!mouse_pressed) return FALSE;
862 if (ev && check_timestamp_outdated(ev->timestamp)) {
866 if (controller && windows && context && cache && ev) {
868 sclboolean processed = FALSE;
869 sclwindow window = SCLWINDOW_INVALID;
872 LOGD("mouse_move : %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y);
874 if (context->get_cur_pressed_window(ev->multi.device) != SCLWINDOW_INVALID &&
875 get_window_rect(context->get_cur_pressed_window(ev->multi.device), &rect)) {
876 sclint winwidth = rect.width;
877 sclint winheight = rect.height;
878 if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
879 rect.height = winwidth;
880 rect.width = winheight;
886 Ecore_Wl_Window *wl_base_window =
887 elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
888 Ecore_Wl_Window *wl_magnifier_window =
889 (elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_magnifier_window())));
890 if (wl_base_window && (unsigned int)ecore_wl_window_id_get(wl_base_window) == ev->window) {
891 SclRectangle base_rect;
892 get_window_rect(windows->get_base_window(), &base_rect);
893 root_x = ev->x + base_rect.x;
894 root_y = ev->y + base_rect.y;
895 } else if (wl_magnifier_window && (unsigned int)ecore_wl_window_id_get(wl_magnifier_window) == ev->window) {
896 SclRectangle magnifier_rect = { 0, 0, 0, 0 };
897 if (get_window_rect(windows->get_magnifier_window(), &magnifier_rect)) {
898 root_x = ev->x + magnifier_rect.x;
899 root_y = ev->y + magnifier_rect.y;
902 root_x = ev->x + rect.x;
903 root_y = ev->y + rect.y;
906 int root_x = ev->root.x;
907 int root_y = ev->root.y;
910 SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
912 controller->mouse_move(context->get_cur_pressed_window(ev->multi.device), coords.x, coords.y, ev->multi.device);
916 window = windows->get_nth_window_in_Z_order_list(index);
918 SclWindowContext *window_context = windows->get_window_context(window);
919 if (window_context) {
920 windows->get_window_rect(window, &(window_context->geometry));
921 if (get_window_rect(window, &rect)) {
923 int root_x = ev->x + rect.x;
924 int root_y = ev->y + rect.y;
925 if (window_context->is_virtual) {
926 apply_virtual_offset(rect, &root_x, &root_y);
929 int root_x = ev->root.x;
930 int root_y = ev->root.y;
932 int adjust_x = root_x;
933 int adjust_y = root_y;
935 SclResParserManager *sclres_manager = SclResParserManager::get_instance();
936 PSclDefaultConfigure default_configure = NULL;
937 if (sclres_manager) {
938 default_configure = sclres_manager->get_default_configure();
940 if (default_configure) {
941 SCLDisplayMode display_mode = context->get_display_mode();
942 CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
943 if (adjustment && scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
944 adjustment->apply_touch_offset(
945 default_configure->touch_offset_level[display_mode],
946 &adjust_x, &adjust_y);
950 sclint win_width = rect.width;
951 sclint win_height = rect.height;
952 if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
953 rect.height = win_width;
954 rect.width = win_height;
957 sclboolean process_event = FALSE;
958 if ((adjust_x >= rect.x && adjust_x <= (rect.x + win_width)) &&
959 (adjust_y >= rect.y && adjust_y <= (rect.y + win_height))) {
960 process_event = TRUE;
962 /* Process this event regardless of the coordinate if the top window has the POPUP_GRAB layout style */
963 if (index == SCL_WINDOW_Z_TOP) {
964 const SclLayout *layout = cache->get_cur_layout(window);
966 if (layout->style == LAYOUT_STYLE_POPUP_GRAB) {
967 process_event = TRUE;
972 /* Now convert the global coordinate to appropriate local coordinate */
973 SclPoint coords = get_rotated_local_coords(
974 root_x, root_y, context->get_rotation(), &rect);
975 controller->mouse_move(window, coords.x, coords.y, ev->multi.device);
982 } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed);
986 window = pressed_window;
987 SclWindowContext *window_context = windows->get_window_context(window);
988 if (window_context && get_window_rect(window, &rect)) {
989 /* Now convert the global coordinate to appropriate local coordinate */
991 int root_x = ev->x + rect.x;
992 int root_y = ev->y + rect.y;
993 if (window_context->is_virtual) {
994 apply_virtual_offset(rect, &root_x, &root_y);
997 int root_x = ev->root.x;
998 int root_y = ev->root.y;
1001 SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
1002 controller->mouse_move(window, coords.x, coords.y, ev->multi.device);
1007 //CSCLController *controller = CSCLController::get_instance();
1008 //CSCLWindows *windows = CSCLWindows::get_instance();
1009 //controller->mouse_move((sclwindow)data, (int)ev->cur.output.x, (int)ev->cur.output.y);
1010 //controller->mouse_move((sclwindow)data, (int)ev->x, (int)ev->y);
1016 * Regists a event callback func to given window.
1017 * In this function, it should call several event functions of CSCLController class whenever an event has occurred
1018 * The below list shows what event function should be called.
1019 * - mouse_press (when the user presses mouse button)
1020 * - mouse_release (when the user releases mouse button)
1021 * - mouse_move (when the user drags mouse button)
1022 * - show_base_layout (when the expost event has occurred)
1025 CSCLEventsImplEfl::connect_window_events(const sclwindow wnd, const sclint evt)
1029 //evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_DOWN, mouse_press, NULL);
1030 /*evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_UP, mouse_release, NULL);
1031 evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_MOVE, mouse_move, NULL);*/
1036 client_message_cb(void *data, int type, void *event)
1038 Ecore_X_Event_Client_Message *ev = (Ecore_X_Event_Client_Message *)event;
1039 if (ev->message_type == ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL) {
1040 CSCLWindows *windows = CSCLWindows::get_instance();
1041 CSCLController *controller = CSCLController::get_instance();
1043 static int last_pos_x = -10000;
1044 static int last_pos_y = -10000;
1046 if (windows && controller) {
1047 Evas_Object *base_win = (Evas_Object *)windows->get_base_window();
1048 if (base_win == NULL) return FALSE;
1050 if ((unsigned int)ev->data.l[0] == elm_win_xwindow_get(base_win)) {
1051 if ((unsigned int)ev->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE) {
1052 // 1 finger double tap
1053 controller->mouse_press(base_win, last_pos_x, last_pos_y);
1054 controller->mouse_release(base_win, last_pos_x, last_pos_y);
1055 } else if ((unsigned int)ev->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ) {
1057 // 1 finger touch & move
1058 last_pos_x = ev->data.l[2];
1059 last_pos_y = ev->data.l[3];
1060 controller->mouse_over(base_win, last_pos_x, last_pos_y);
1065 return ECORE_CALLBACK_PASS_ON;
1069 Eina_Bool timer_event(void *data)
1072 CSCLUtils *utils = CSCLUtils::get_instance();
1073 CSCLController *controller = CSCLController::get_instance();
1075 scl32 sendData = static_cast<scl32>(reinterpret_cast<uintptr_t>(data) & 0xffffffff);
1077 if (controller && utils) {
1078 scl16 id = SCL_LOWORD(sendData); /* Timer ID */
1079 Eina_Bool ret = controller->timer_event(sendData);
1081 utils->log("Returning Timer : %d %d\n", id, ret);
1090 * In this function, it should call timer_event of CSCLController class
1093 CSCLEventsImplEfl::create_timer(const scl16 id, const scl32 interval, scl16 value, sclboolean addToMap)
1096 sclint data = SCL_MAKELONG(id, value);
1097 Ecore_Timer *pTimer = ecore_timer_add((double)interval / 1000.0, timer_event, (void*)(uintptr_t)data);
1099 CSCLUtils *utils = CSCLUtils::get_instance();
1101 utils->log("Created Timer : %d %p\n", id, pTimer);
1110 * Destroys the given ID's timer
1113 CSCLEventsImplEfl::destroy_timer(const scl32 id)
1116 //for ( std::map<int, Ecore_Timer*>::iterator idx = idMap.begin(); idx != idMap.end(); ++idx) {
1117 std::map<int, Ecore_Timer*>::iterator idx = idMap.find(id);
1118 //if ((*idx).first == id) {
1119 if (idx != idMap.end()) {
1120 CSCLUtils *utils = CSCLUtils::get_instance();
1122 utils->log("Destroyed Timer : %d %p\n", (*idx).first, (*idx).second);
1124 ecore_timer_del((*idx).second);
1125 idMap.erase((*idx).first);
1132 * Destroys all of created timer
1135 CSCLEventsImplEfl::destroy_all_timer()
1138 for ( std::map<int, Ecore_Timer*>::iterator idx = idMap.begin(); idx != idMap.end(); ++idx ) {
1139 ecore_timer_del((*idx).second);
1141 CSCLUtils *utils = CSCLUtils::get_instance();
1143 utils->log("Destroyed Timer : %d %p\n", (*idx).first, (*idx).second);
1150 CSCLEventsImplEfl::generate_mouse_event(SCLMouseEvent type, scl16 x, scl16 y)
1152 CSCLWindows *windows = CSCLWindows::get_instance();
1153 SclWindowContext *window_context = NULL;
1155 static const sclint MAX_DEVICES = 100;
1156 static sclboolean pressed[MAX_DEVICES] = { FALSE };
1159 case SCL_MOUSE_EVENT_PRESS:
1161 sclboolean generated = FALSE;
1162 for (sclint loop = 0; !generated && loop < MAX_DEVICES; loop++) {
1163 if (pressed[loop] != TRUE) {
1164 pressed[loop] = TRUE;
1165 Ecore_Event_Mouse_Button evt;
1167 Ecore_Wl_Window *wl_base_window;
1168 wl_base_window = elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
1170 evt.window = (unsigned int)ecore_wl_window_id_get(wl_base_window);
1172 evt.window = elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window()));
1174 //window_context = windows->get_window_context(windows->get_base_window(), FALSE);
1175 window_context = windows->get_window_context(windows->get_base_window());
1176 if (window_context) {
1177 evt.x = evt.root.x = x + window_context->geometry.x;
1178 evt.y = evt.root.y = y + window_context->geometry.y;
1179 evt.multi.device = loop;
1180 mouse_press(NULL, 0, &evt);
1187 case SCL_MOUSE_EVENT_RELEASE:
1189 sclboolean generated = FALSE;
1190 for (sclint loop = 0; !generated && loop < MAX_DEVICES; loop++) {
1191 if (pressed[loop] == TRUE) {
1192 pressed[loop] = FALSE;
1193 Ecore_Event_Mouse_Button evt;
1195 Ecore_Wl_Window *wl_base_window;
1196 wl_base_window = elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
1198 evt.window = (unsigned int)ecore_wl_window_id_get(wl_base_window);
1200 evt.window = elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window()));
1202 //window_context = windows->get_window_context(windows->get_base_window(), FALSE);
1203 window_context = windows->get_window_context(windows->get_base_window());
1204 if (window_context) {
1205 evt.x = evt.root.x = x + window_context->geometry.x;
1206 evt.y = evt.root.y = y + window_context->geometry.y;
1207 evt.multi.device = loop;
1208 mouse_release(NULL, 0, &evt);
1215 case SCL_MOUSE_EVENT_MOVE:
1217 sclboolean generated = FALSE;
1218 for (sclint loop = 0; !generated && loop < MAX_DEVICES; loop++) {
1219 if (pressed[loop] == TRUE) {
1220 Ecore_Event_Mouse_Move evt;
1222 Ecore_Wl_Window *wl_base_window;
1223 wl_base_window = elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
1225 evt.window = (unsigned int)ecore_wl_window_id_get(wl_base_window);
1227 evt.window = elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window()));
1229 //window_context = windows->get_window_context(windows->get_base_window(), FALSE);
1230 window_context = windows->get_window_context(windows->get_base_window());
1231 if (window_context) {
1232 evt.x = evt.root.x = x + window_context->geometry.x;
1233 evt.y = evt.root.y = y + window_context->geometry.y;
1234 evt.multi.device = loop;
1235 mouse_move(NULL, 0, &evt);