2 * Copyright 2012-2013 Samsung Electronics Co., Ltd.
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
8 * http://floralicense.org/license/
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>
33 #define E_PROP_TOUCH_INPUT "X_TouchInput"
35 sclboolean mouse_pressed = FALSE; /* Checks whether mouse is pressed or not */
36 sclwindow pressed_window = SCLWINDOW_INVALID;
38 #define MIN_XY_DIFF 14
40 Eina_Bool mouse_press(void *data, int type, void *event_info);
41 Eina_Bool mouse_move (void *data, int type, void *event_info);
42 Eina_Bool mouse_release (void *data, int type, void *event_info);
47 CSCLEventsImplEfl::CSCLEventsImplEfl()
50 /* Initializes all window resources */
51 m_mouse_down_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, mouse_press, NULL);
52 m_mouse_move_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, mouse_move, NULL);
53 m_mouse_up_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, mouse_release, NULL);
59 CSCLEventsImplEfl::~CSCLEventsImplEfl()
63 if (m_mouse_down_handler) ecore_event_handler_del(m_mouse_down_handler);
64 if (m_mouse_move_handler) ecore_event_handler_del(m_mouse_move_handler);
65 if (m_mouse_up_handler) ecore_event_handler_del(m_mouse_up_handler);
68 sclboolean get_window_rect(const sclwindow window, SclRectangle *rect)
71 sclboolean ret = FALSE;
72 CSCLUtils *utils = CSCLUtils::get_instance();
73 CSCLWindows *windows = CSCLWindows::get_instance();
74 CSCLContext *context = CSCLContext::get_instance();
75 if (windows && context && utils && rect) {
76 SclWindowContext *winctx = windows->get_window_context(window);
79 utils->get_screen_resolution(&scr_w, &scr_h);
81 switch (context->get_rotation()) {
84 rect->height = winctx->geometry.width;
85 rect->width = winctx->geometry.height;
86 rect->y = scr_w - rect->height - winctx->geometry.x;
87 rect->x = winctx->geometry.y;
92 rect->width = winctx->geometry.width;
93 rect->height = winctx->geometry.height;
94 rect->x = scr_w - winctx->geometry.x - rect->width;
95 rect->y = scr_h - winctx->geometry.y - rect->height;
100 rect->height = winctx->geometry.width;
101 rect->width = winctx->geometry.height;
102 rect->y = winctx->geometry.x;
103 rect->x= scr_h - winctx->geometry.y - rect->width;
108 rect->x = winctx->geometry.x;
109 rect->y = winctx->geometry.y;
110 rect->width = winctx->geometry.width;
111 rect->height = winctx->geometry.height;
117 rect->x = rect->y = rect->width = rect->height = 0;
123 /** Here x and y contains "actual" x and y position relative to portrait root window,
124 and winctx->width,height contains the window's orientation dependant width and height */
125 SclPoint get_rotated_local_coords(sclint x, sclint y, SCLRotation rotation, SclRectangle *rect) {
126 SclPoint ret = {0, 0};
132 ret.x = (rect->y + rect->width) - y;
138 ret.x = (rect->x + rect->width) - x;
139 ret.y = (rect->y + rect->height) - y;
142 case ROTATION_90_CCW:
145 ret.y = (rect->x + rect->height) - x;
159 //void mouse_press (void *data, Evas *e, Evas_Object *object, void *event_info)
160 Eina_Bool mouse_press(void *data, int type, void *event_info)
164 //Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down*)event_info;
165 //LOGD("mouse_press : %d %d\n", ev->output.x, ev->output.y);
167 CSCLController *controller = CSCLController::get_instance();
168 CSCLWindows *windows = CSCLWindows::get_instance();
169 CSCLContext *context = CSCLContext::get_instance();
170 CSCLUtils *utils = CSCLUtils::get_instance();
171 CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
173 Ecore_Event_Mouse_Button *ev = (Ecore_Event_Mouse_Button*)event_info;
175 if (controller && windows && context && utils && adjustment && ev) {
177 sclboolean processed = FALSE;
178 sclwindow window = SCLWINDOW_INVALID;
180 unsigned int touch_input = 0;
181 int res = ecore_x_window_prop_card32_get(ecore_x_window_root_first_get(),
182 ecore_x_atom_get(E_PROP_TOUCH_INPUT), &touch_input, 1);
184 utils->log("E_PROP_TOUCH_INPUT : %d %d\n", res, touch_input);
187 if (1 == touch_input) {
188 adjustment->enable_touch_offset(TRUE);
189 } else if (0 == touch_input) {
190 adjustment->enable_touch_offset(FALSE);
194 sclwindow evwin = (sclwindow)(ev->window);
195 sclboolean is_scl_window = FALSE;
196 if (elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window())) == ev->window) {
197 is_scl_window = TRUE;
198 } else if (elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_magnifier_window())) == ev->window) {
199 is_scl_window = TRUE;
202 window = windows->get_nth_window_in_Z_order_list(index);
203 SclWindowContext *winctx = windows->get_window_context(window);
205 if (winctx->is_virtual) {
206 is_scl_window = TRUE;
207 } else if (elm_win_xwindow_get(static_cast<Evas_Object*>(window)) == ev->window) {
208 is_scl_window = TRUE;
212 } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID);
215 if (!is_scl_window) return TRUE;
217 SclRectangle rect = {0};
219 window = windows->get_nth_window_in_Z_order_list(index);
221 // Update the position of the target window
222 //windows->get_window_context(window, TRUE);
223 windows->get_window_context(window);
224 if (get_window_rect(window, &rect)) {
225 int adjustx = ev->root.x;
226 int adjusty = ev->root.y;
228 SclResParserManager *sclres_manager = SclResParserManager::get_instance();
229 PSclDefaultConfigure default_configure = NULL;
230 if (sclres_manager) {
231 default_configure = sclres_manager->get_default_configure();
233 if (default_configure) {
234 SCLDisplayMode display_mode = context->get_display_mode();
235 CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
236 if (adjustment && scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
237 adjustment->apply_touch_offset(default_configure->touch_offset_level[display_mode], &adjustx, &adjusty);
241 sclint winwidth = rect.width;
242 sclint winheight = rect.height;
243 if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
244 rect.height = winwidth;
245 rect.width = winheight;
248 sclboolean process_event = FALSE;
249 if ((adjustx >= rect.x && adjustx <= (rect.x + winwidth)) &&
250 (adjusty >= rect.y && adjusty <= (rect.y + winheight))) {
251 process_event = TRUE;
255 // Now convert the global coordination to appropriate local coordination
256 SclPoint coords = get_rotated_local_coords(ev->root.x, ev->root.y, context->get_rotation(), &rect);
257 controller->mouse_press(window, coords.x, coords.y, ev->multi.device);
258 mouse_pressed = TRUE;
260 pressed_window = window;
266 } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed);
269 window = pressed_window;
270 if (get_window_rect(window, &rect)) {
271 if (context->get_rotation() == ROTATION_90_CW || context->get_rotation() == ROTATION_90_CCW) {
272 sclint temp = rect.width;
273 rect.width = rect.height;
277 // Now convert the global coordination to appropriate local coordination
278 SclPoint coords = get_rotated_local_coords(ev->root.x, ev->root.y, context->get_rotation(), &rect);
279 controller->mouse_press(window, coords.x, coords.y, ev->multi.device);
280 mouse_pressed = TRUE;
288 /*CSCLContext *context = CSCLContext::get_instance();
289 controller->mouse_press((sclwindow)data, ev->output.x, ev->output.y);
290 mouse_pressed = TRUE;*/
292 //LOGD("=-=-=-=- mouse_press : %p %d %d\n", data, ev->output.x, ev->output.y);
295 //void mouse_release (void *data, Evas *e, Evas_Object *object, void *event_info)
296 Eina_Bool mouse_release (void *data, int type, void *event_info)
300 CSCLController *controller = CSCLController::get_instance();
301 CSCLWindows *windows = CSCLWindows::get_instance();
302 CSCLContext *context = CSCLContext::get_instance();
304 //Evas_Event_Mouse_Up *ev = (Evas_Event_Mouse_Up*)event_info;
305 Ecore_Event_Mouse_Button *ev = (Ecore_Event_Mouse_Button*)event_info;
306 //LOGD("mouse_release : %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y);
308 //if (!mouse_pressed) return FALSE;
310 if (controller && windows && context && ev) {
312 sclboolean processed = FALSE;
313 sclwindow window = SCLWINDOW_INVALID;
315 sclboolean dimwinevent = FALSE;
316 SclWindowContext *dimctx = windows->get_window_context(windows->get_dim_window());
318 if (!(dimctx->is_virtual)) {
319 if (elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_dim_window())) == ev->window) {
325 controller->mouse_press(windows->get_dim_window(), ev->root.x, ev->root.y, ev->multi.device);
328 window = windows->get_nth_window_in_Z_order_list(index);
330 if (get_window_rect(window, &rect)) {
331 int adjustx = ev->root.x;
332 int adjusty = ev->root.y;
334 SclResParserManager *sclres_manager = SclResParserManager::get_instance();
335 PSclDefaultConfigure default_configure = NULL;
336 if (sclres_manager) {
337 default_configure = sclres_manager->get_default_configure();
339 if (default_configure) {
340 SCLDisplayMode display_mode = context->get_display_mode();
341 CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
342 if (adjustment && scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
343 adjustment->apply_touch_offset(default_configure->touch_offset_level[display_mode], &adjustx, &adjusty);
347 sclint winwidth = rect.width;
348 sclint winheight = rect.height;
349 if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
350 rect.height = winwidth;
351 rect.width = winheight;
354 sclboolean process_event = FALSE;
355 if ((adjustx >= rect.x && adjustx <= (rect.x + winwidth)) &&
356 (adjusty >= rect.y && adjusty <= (rect.y + winheight))) {
357 process_event = TRUE;
361 /* Now convert the global coordination to appropriate local coordination */
362 SclPoint coords = get_rotated_local_coords(ev->root.x, ev->root.y, context->get_rotation(), &rect);
363 controller->mouse_release(window, coords.x, coords.y, ev->multi.device);
370 } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed);
374 window = pressed_window;
375 if (get_window_rect(window, &rect)) {
376 if (context->get_rotation() == ROTATION_90_CW || context->get_rotation() == ROTATION_90_CCW) {
377 sclint temp = rect.width;
378 rect.width = rect.height;
382 /* Now convert the global coordination to appropriate local coordination */
383 SclPoint coords = get_rotated_local_coords(ev->root.x, ev->root.y, context->get_rotation(), &rect);
384 controller->mouse_release(window, coords.x, coords.y, ev->multi.device);
389 mouse_pressed = FALSE;
393 //CSCLController *controller = CSCLController::get_instance();
394 //CSCLWindows *windows = CSCLWindows::get_instance();
395 //controller->mouse_release((sclwindow)data, (int)ev->output.x, (int)ev->output.y);
396 //controller->mouse_release((sclwindow)data, (int)ev->x, (int)ev->y);
399 //int mouse_move (void *data, Evas *e, Evas_Object *object, void *event_info)
400 Eina_Bool mouse_move (void *data, int type, void *event_info)
404 CSCLController *controller = CSCLController::get_instance();
405 CSCLWindows *windows = CSCLWindows::get_instance();
406 CSCLContext *context = CSCLContext::get_instance();
407 CSCLResourceCache *cache = CSCLResourceCache::get_instance();
409 //Evas_Event_Mouse_Move *ev = (Evas_Event_Mouse_Move*)event_info;
410 Ecore_Event_Mouse_Move *ev = (Ecore_Event_Mouse_Move*)event_info;
411 //LOGD("mouse_move : %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y);
413 //if (!mouse_pressed) return FALSE;
415 if (controller && windows && context && cache && ev) {
417 sclboolean processed = FALSE;
418 sclwindow window = SCLWINDOW_INVALID;
421 if (context->get_cur_pressed_window(ev->multi.device) != SCLWINDOW_INVALID &&
422 get_window_rect(context->get_cur_pressed_window(ev->multi.device), &rect)) {
423 sclint winwidth = rect.width;
424 sclint winheight = rect.height;
425 if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
426 rect.height = winwidth;
427 rect.width = winheight;
429 SclPoint coords = get_rotated_local_coords(ev->root.x, ev->root.y, context->get_rotation(), &rect);
431 controller->mouse_move(context->get_cur_pressed_window(ev->multi.device), coords.x, coords.y, ev->multi.device);
435 window = windows->get_nth_window_in_Z_order_list(index);
437 if (get_window_rect(window, &rect)) {
438 int adjustx = ev->root.x;
439 int adjusty = ev->root.y;
441 SclResParserManager *sclres_manager = SclResParserManager::get_instance();
442 PSclDefaultConfigure default_configure = NULL;
443 if (sclres_manager) {
444 default_configure = sclres_manager->get_default_configure();
446 if (default_configure) {
447 SCLDisplayMode display_mode = context->get_display_mode();
448 CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
449 if (adjustment && scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
450 adjustment->apply_touch_offset(default_configure->touch_offset_level[display_mode], &adjustx, &adjusty);
454 sclint winwidth = rect.width;
455 sclint winheight = rect.height;
456 if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
457 rect.height = winwidth;
458 rect.width = winheight;
461 sclboolean process_event = FALSE;
462 if ((adjustx >= rect.x && adjustx <= (rect.x + winwidth)) &&
463 (adjusty >= rect.y && adjusty <= (rect.y + winheight))) {
464 process_event = TRUE;
466 /* Process this event regardless of the coordination if the top window has the POPUP_GRAB layout style */
467 if (index == SCL_WINDOW_Z_TOP) {
468 const SclLayout *layout = cache->get_cur_layout(window);
470 if (layout->style == LAYOUT_STYLE_POPUP_GRAB) {
471 process_event = TRUE;
477 /* Now convert the global coordination to appropriate local coordination */
478 SclPoint coords = get_rotated_local_coords(ev->root.x, ev->root.y, context->get_rotation(), &rect);
480 controller->mouse_move(window, coords.x, coords.y, ev->multi.device);
487 } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed);
491 window = pressed_window;
492 if (get_window_rect(window, &rect)) {
493 /* Now convert the global coordination to appropriate local coordination */
494 SclPoint coords = get_rotated_local_coords(ev->root.x, ev->root.y, context->get_rotation(), &rect);
495 controller->mouse_move(window, coords.x, coords.y, ev->multi.device);
500 //CSCLController *controller = CSCLController::get_instance();
501 //CSCLWindows *windows = CSCLWindows::get_instance();
502 //controller->mouse_move((sclwindow)data, (int)ev->cur.output.x, (int)ev->cur.output.y);
503 //controller->mouse_move((sclwindow)data, (int)ev->x, (int)ev->y);
509 * Regists a event callback func to given window.
510 * In this function, it should call serveral event functions of CSCLController class whenever an event has occured
511 * The below list shows what event function should be called.
512 * - mouse_press (when the user presses mouse button)
513 * - mouse_release (when the user releases mouse button)
514 * - mouse_move (when the user drags mouse button)
515 * - show_base_layout (when the expost event has occured)
518 CSCLEventsImplEfl::connect_window_events(const sclwindow wnd, const sclint evt)
522 //evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_DOWN, mouse_press, NULL);
523 /*evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_UP, mouse_release, NULL);
524 evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_MOVE, mouse_move, NULL);*/
527 Eina_Bool timer_event(void *data)
530 scl32 sendData = (scl32)data;
531 CSCLController *controller;
532 controller = CSCLController::get_instance();
534 return controller->timer_event(sendData);
541 * In this function, it should call timer_event of CSCLController class
544 CSCLEventsImplEfl::create_timer(const scl16 id, const scl32 interval, scl16 value, sclboolean addToMap)
547 sclint data = SCL_MAKELONG(id, value);
548 Ecore_Timer *pTimer = ecore_timer_add((double)interval / 1000.0, timer_event, (void*)data);
557 * Destroys the given ID's timer
560 CSCLEventsImplEfl::destroy_timer(const scl32 id)
563 //for ( std::map<int, Ecore_Timer*>::iterator idx = idMap.begin(); idx != idMap.end(); ++idx) {
564 std::map<int, Ecore_Timer*>::iterator idx = idMap.find(id);
565 //if ((*idx).first == id) {
566 if (idx != idMap.end()) {
567 ecore_timer_del((*idx).second);
568 idMap.erase((*idx).first);
575 * Destroys all of created timer
578 CSCLEventsImplEfl::destroy_all_timer()
581 for ( std::map<int, Ecore_Timer*>::iterator idx = idMap.begin(); idx != idMap.end(); ++idx) {
582 ecore_timer_del((*idx).second);
588 CSCLEventsImplEfl::generate_mouse_event(SCLMouseEvent type, scl16 x, scl16 y)
590 CSCLWindows *windows = CSCLWindows::get_instance();
591 SclWindowContext *winctx = NULL;
594 case SCL_MOUSE_EVENT_PRESS:
596 Ecore_Event_Mouse_Button evt;
597 evt.window = elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window()));
598 //winctx = windows->get_window_context(windows->get_base_window(), FALSE);
599 winctx = windows->get_window_context(windows->get_base_window());
601 evt.root.x = x + winctx->geometry.x;
602 evt.root.y = y + winctx->geometry.y;
603 mouse_press(NULL, 0, &evt);
607 case SCL_MOUSE_EVENT_RELEASE:
609 Ecore_Event_Mouse_Button evt;
610 evt.window = elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window()));
611 //winctx = windows->get_window_context(windows->get_base_window(), FALSE);
612 winctx = windows->get_window_context(windows->get_base_window());
614 evt.root.x = x + winctx->geometry.x;
615 evt.root.y = y + winctx->geometry.y;
616 mouse_release(NULL, 0, &evt);
620 case SCL_MOUSE_EVENT_MOVE:
622 Ecore_Event_Mouse_Move evt;
623 evt.window = elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window()));
624 //winctx = windows->get_window_context(windows->get_base_window(), FALSE);
625 winctx = windows->get_window_context(windows->get_base_window());
627 evt.root.x = x + winctx->geometry.x;
628 evt.root.y = y + winctx->geometry.y;
629 mouse_move(NULL, 0, &evt);