2 * Copyright (c) 2000 - 2015 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.
20 #include <Elementary.h>
22 #include <Ecore_Input.h>
25 #include <dd-display.h>
32 #include "dbus_util.h"
34 #include "process_mgr.h"
36 #define GRAB_TWO_FINGERS 2
37 #define POWERKEY_TIMER_SEC 0.25
38 #define POWERKEY_LCDOFF_TIMER_SEC 0.4
39 #define LONG_PRESS_TIMER_SEC 0.7
41 #define APP_CONTROL_OPERATION_MAIN_KEY "__APP_SVC_OP_TYPE__"
42 #define APP_CONTROL_OPERATION_MAIN_VALUE "http://tizen.org/appcontrol/operation/main"
44 #define USE_DBUS_POWEROFF 1
45 #define W_TASKMGR_PKGNAME "org.tizen.w-taskmanager"
51 Ecore_Event_Handler *key_up;
52 Ecore_Event_Handler *key_down;
53 Ecore_Event_Handler *two_fingers_hold_hd;
54 Ecore_Timer *power_long_press_timer;
55 Ecore_Timer *power_release_timer;
57 Eina_Bool is_long_press;
64 .two_fingers_hold_hd = NULL,
65 .power_long_press_timer = NULL,
66 .power_release_timer = NULL,
67 .is_lcd_on = EINA_FALSE,
68 .is_long_press = EINA_FALSE,
70 .is_cancel = EINA_FALSE,
75 static Eina_Bool _powerkey_timer_cb(void *data)
77 _W("%s, powerkey count[%d]", __func__, key_info.powerkey_count);
79 key_info.power_release_timer = NULL;
81 if (VCONFKEY_PM_KEY_LOCK == status_passive_get()->pm_key_ignore) {
82 _E("Critical Low Batt Clock Mode");
83 key_info.powerkey_count = 0;
84 if(key_info.is_lcd_on) {
85 _W("just turn off LCD");
86 display_change_state(LCD_OFF);
88 _W("just turn on LCD by powerkey.. starter ignore powerkey operation");
90 return ECORE_CALLBACK_CANCEL;
93 if (key_info.powerkey_count % 2 == 0) {
95 _W("powerkey double press");
96 key_info.powerkey_count = 0;
97 return ECORE_CALLBACK_CANCEL;
99 key_info.powerkey_count = 0;
101 if (key_info.is_lcd_on) {
102 if(VCONFKEY_PM_STATE_LCDOFF <= status_active_get()->pm_state) {
103 _E("Already lcd state was changed while powerkey op. starter ignore powerkey operation");
104 return ECORE_CALLBACK_CANCEL;
107 _W("just turn on LCD by powerkey.. starter ignore powerkey operation");
108 return ECORE_CALLBACK_CANCEL;
111 if (VCONFKEY_CALL_VOICE_ACTIVE == status_passive_get()->call_state) {
112 _W("call state is [%d] -> just turn off LCD");
113 display_change_state(LCD_OFF);
114 return ECORE_CALLBACK_CANCEL;
117 if (VCONFKEY_IDLE_LOCK == status_passive_get()->idle_lock_state) {
118 _W("lock state is [%d] -> just turn off LCD");
119 display_change_state(LCD_OFF);
120 return ECORE_CALLBACK_CANCEL;
123 if (0 < status_passive_get()->remote_lock_islocked) {
124 _W("remote lock is on top (%d), -> just turn off LCD", status_passive_get()->remote_lock_islocked);
125 display_change_state(LCD_OFF);
126 return ECORE_CALLBACK_CANCEL;
129 home_mgr_launch_home_by_power();
131 return ECORE_CALLBACK_CANCEL;
135 static Eina_Bool _long_press_timer_cb(void* data)
137 key_info.power_long_press_timer = NULL;
138 key_info.is_long_press = EINA_TRUE;
139 key_info.powerkey_count = 0;
141 if (0 < status_passive_get()->remote_lock_islocked){
142 _W("remote lock is on top (%d), -> just turn off LCD", status_passive_get()->remote_lock_islocked);
143 return ECORE_CALLBACK_CANCEL;
146 if (key_info.power_release_timer) {
147 ecore_timer_del(key_info.power_release_timer);
148 key_info.power_release_timer = NULL;
149 _D("delete power_release_timer");
152 #if USE_DBUS_POWEROFF
153 dbus_util_send_poweroff_signal();
155 _D("launch power off syspopup");
156 process_mgr_syspopup_launch("poweroff-syspopup", NULL, NULL, NULL, NULL);
159 feedback_initialize();
160 feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_HOLD);
161 feedback_deinitialize();
163 return ECORE_CALLBACK_CANCEL;
167 static Eina_Bool _key_release_cb(void *data, int type, void *event)
169 Evas_Event_Key_Up *ev = event;
171 retv_if(!ev, ECORE_CALLBACK_RENEW);
172 retv_if(!ev->keyname, ECORE_CALLBACK_RENEW);
174 _D("_key_release_cb : %s Released", ev->keyname);
176 if (!strcmp(ev->keyname, KEY_POWER)) {
177 _W("POWER Key is released");
179 if(key_info.power_long_press_timer) {
180 ecore_timer_del(key_info.power_long_press_timer);
181 key_info.power_long_press_timer = NULL;
182 _D("delete long press timer");
185 // Check powerkey timer
186 if(key_info.power_release_timer) {
187 ecore_timer_del(key_info.power_release_timer);
188 key_info.power_release_timer = NULL;
189 _D("delete powerkey timer");
192 // Cancel key operation
193 if (EINA_TRUE == key_info.is_cancel) {
194 _D("Cancel key is activated");
195 key_info.is_cancel = EINA_FALSE;
196 key_info.powerkey_count = 0; //initialize powerkey count
197 return ECORE_CALLBACK_RENEW;
200 // Check long press operation
201 if(key_info.is_long_press) {
202 _D("ignore power key release by long poress");
203 key_info.is_long_press = EINA_FALSE;
204 return ECORE_CALLBACK_RENEW;
207 if(key_info.is_lcd_on) {
208 key_info.power_release_timer = ecore_timer_add(POWERKEY_TIMER_SEC, _powerkey_timer_cb, NULL);
210 _D("lcd off --> [%f]sec timer", POWERKEY_LCDOFF_TIMER_SEC);
211 key_info.power_release_timer = ecore_timer_add(POWERKEY_LCDOFF_TIMER_SEC, _powerkey_timer_cb, NULL);
213 if (!key_info.power_release_timer) {
214 _E("Critical, cannot add a timer for powerkey");
216 } else if (!strcmp(ev->keyname, KEY_CANCEL)) {
217 _D("CANCEL Key is released");
218 key_info.is_cancel = EINA_FALSE;
221 return ECORE_CALLBACK_RENEW;
226 static Eina_Bool _key_press_cb(void *data, int type, void *event)
228 Evas_Event_Key_Down *ev = event;
230 retv_if(!ev, ECORE_CALLBACK_RENEW);
231 retv_if(!ev->keyname, ECORE_CALLBACK_RENEW);
233 _D("_key_press_cb : %s Pressed", ev->keyname);
235 if (!strcmp(ev->keyname, KEY_POWER)) {
236 _W("POWER Key is pressed");
245 if (VCONFKEY_PM_STATE_LCDDIM >= status_active_get()->pm_state) {
246 key_info.is_lcd_on = EINA_TRUE;
247 } else if (VCONFKEY_PM_STATE_LCDOFF <= status_active_get()->pm_state) {
248 key_info.is_lcd_on = EINA_FALSE;
251 key_info.powerkey_count++;
252 _W("powerkey count : %d", key_info.powerkey_count);
254 if(key_info.power_release_timer) {
255 ecore_timer_del(key_info.power_release_timer);
256 key_info.power_release_timer = NULL;
259 if (key_info.power_long_press_timer) {
260 ecore_timer_del(key_info.power_long_press_timer);
261 key_info.power_long_press_timer = NULL;
264 key_info.is_long_press = EINA_FALSE;
265 key_info.power_long_press_timer = ecore_timer_add(LONG_PRESS_TIMER_SEC, _long_press_timer_cb, NULL);
266 if(!key_info.power_long_press_timer) {
267 _E("Failed to add power_long_press_timer");
269 } else if (!strcmp(ev->keyname, KEY_CANCEL)) {
270 _D("CANCEL key is pressed");
271 key_info.is_cancel = EINA_TRUE;
274 return ECORE_CALLBACK_RENEW;
279 static Eina_Bool _w_gesture_hold_cb(void *data, int ev_type, void *ev)
281 Ecore_X_Event_Gesture_Notify_Hold *e = ev;
283 if (VCONFKEY_PM_KEY_LOCK == status_passive_get()->pm_key_ignore) {
284 _E("Critical Low Batt Clock Mode, ignore gesture");
285 return ECORE_CALLBACK_RENEW;
288 if (SETTING_PSMODE_WEARABLE_ENHANCED == status_passive_get()->setappl_psmode) {
289 _E("UPS Mode, ignore gesture");
290 return ECORE_CALLBACK_RENEW;
293 if(e->num_fingers == GRAB_TWO_FINGERS) {
294 _D("subtype[%d]: hold[%d]\n", e->subtype, e->hold_time);
295 if (e->subtype == ECORE_X_GESTURE_BEGIN) {
296 _D("Begin : launch task mgr..!!");
297 dbus_util_send_cpu_booster_signal();
298 process_mgr_must_launch(W_TASKMGR_PKGNAME, APP_CONTROL_OPERATION_MAIN_KEY, APP_CONTROL_OPERATION_MAIN_VALUE, NULL, NULL);
302 return ECORE_CALLBACK_RENEW;
307 void hw_key_create_window(void)
312 _W("hw_key_create_window");
314 key_info.win = ecore_x_window_input_new(0, 0, 0, 1, 1);
316 _E("Failed to create hidden window");
319 ecore_x_event_mask_unset(key_info.win, ECORE_X_EVENT_MASK_NONE);
320 ecore_x_icccm_title_set(key_info.win, "w_starter,key,receiver");
321 ecore_x_netwm_name_set(key_info.win, "w_starter,key,receiver");
322 ecore_x_netwm_pid_set(key_info.win, getpid());
324 ret = utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_POWER, SHARED_GRAB);
326 _E("utilx_grab_key KEY_POWER GrabSHARED_GRAB failed, ret[%d]", ret);
329 key_info.key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_release_cb, NULL);
330 if (!key_info.key_up) {
331 _E("Failed to register a key up event handler");
334 key_info.key_down = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_press_cb, NULL);
335 if (!key_info.key_down) {
336 _E("Failed to register a key down event handler");
339 status = ecore_x_gesture_event_grab(key_info.win, ECORE_X_GESTURE_EVENT_HOLD, GRAB_TWO_FINGERS);
340 _E("ECORE_X_GESTURE_EVENT_HOLD Grab(%d fingers) status[%d]\n", GRAB_TWO_FINGERS, status);
342 key_info.two_fingers_hold_hd = ecore_event_handler_add(ECORE_X_EVENT_GESTURE_NOTIFY_HOLD, _w_gesture_hold_cb, NULL);
343 if (!key_info.two_fingers_hold_hd) {
344 _E("Failed to register handler : ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD\n");
350 void hw_key_destroy_window(void)
354 if (key_info.two_fingers_hold_hd) {
355 ecore_event_handler_del(key_info.two_fingers_hold_hd);
356 key_info.two_fingers_hold_hd = NULL;
359 status = ecore_x_gesture_event_ungrab(key_info.win, ECORE_X_GESTURE_EVENT_HOLD, GRAB_TWO_FINGERS);
361 _E("ECORE_X_GESTURE_EVENT_HOLD UnGrab(%d fingers) failed, status[%d]\n", GRAB_TWO_FINGERS, status);
364 if (key_info.key_up) {
365 ecore_event_handler_del(key_info.key_up);
366 key_info.key_up = NULL;
369 if (key_info.key_down) {
370 ecore_event_handler_del(key_info.key_down);
371 key_info.key_down = NULL;
374 utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_POWER);
376 ecore_x_window_delete_request_send(key_info.win);
383 #include <Elementary.h>
384 #include <Ecore_Input.h>
385 #include <Ecore_Wayland.h>
387 #include <dd-display.h>
388 #include <feedback.h>
394 #include "dbus_util.h"
395 #include "home_mgr.h"
396 #include "process_mgr.h"
398 #define LONG_PRESS_TIMER_SEC 0.7
399 #define POWERKEY_LCDOFF_TIMER_SEC 0.4
400 #define POWERKEY_TIMER_SEC 0.25
402 #define USE_DBUS_POWEROFF 1
404 const char *key_name[KEY_NAME_MAX] = {
405 "XF86AudioRaiseVolume",
406 "XF86AudioLowerVolume",
422 "XF86AudioPlayPause",
433 "XF86MonBrightnessDown",
434 "XF86MonBrightnessUp",
440 "XF86VoiceWakeUp_LPSD",
446 Ecore_Event_Handler *key_up;
447 Ecore_Event_Handler *key_down;
448 Ecore_Timer *home_long_press_timer;
449 Ecore_Timer *home_multi_press_timer;
450 Ecore_Timer *keygrab_timer;
454 Ecore_Timer *power_long_press_timer;
455 Ecore_Timer *power_release_timer;
457 Eina_Bool is_long_press;
463 .home_long_press_timer = NULL,
464 .home_multi_press_timer = NULL,
465 .keygrab_timer = NULL,
466 .cancel = EINA_FALSE,
469 .power_long_press_timer = NULL,
470 .power_release_timer = NULL,
471 .is_lcd_on = EINA_FALSE,
472 .is_long_press = EINA_FALSE,
474 .is_cancel = EINA_FALSE,
479 static Eina_Bool _long_press_timer_cb(void* data)
481 key_info.power_long_press_timer = NULL;
482 key_info.is_long_press = EINA_TRUE;
483 key_info.powerkey_count = 0;
485 if (0 < status_passive_get()->remote_lock_islocked){
486 _W("remote lock is on top (%d), -> just turn off LCD", status_passive_get()->remote_lock_islocked);
487 return ECORE_CALLBACK_CANCEL;
490 if (key_info.power_release_timer) {
491 ecore_timer_del(key_info.power_release_timer);
492 key_info.power_release_timer = NULL;
493 _D("delete power_release_timer");
496 #if USE_DBUS_POWEROFF
497 dbus_util_send_poweroff_signal();
499 _D("launch power off syspopup");
500 process_mgr_syspopup_launch("poweroff-syspopup", NULL, NULL, NULL, NULL);
503 feedback_initialize();
504 feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_HOLD);
505 feedback_deinitialize();
507 return ECORE_CALLBACK_CANCEL;
512 static Eina_Bool _powerkey_timer_cb(void *data)
514 _W("%s, powerkey count[%d]", __func__, key_info.powerkey_count);
516 key_info.power_release_timer = NULL;
518 if (VCONFKEY_PM_KEY_LOCK == status_passive_get()->pm_key_ignore) {
519 _E("Critical Low Batt Clock Mode");
520 key_info.powerkey_count = 0;
521 if(key_info.is_lcd_on) {
522 _W("just turn off LCD");
523 display_change_state(LCD_OFF);
525 _W("just turn on LCD by powerkey.. starter ignore powerkey operation");
527 return ECORE_CALLBACK_CANCEL;
530 if (key_info.powerkey_count % 2 == 0) {
532 _W("powerkey double press");
533 key_info.powerkey_count = 0;
534 return ECORE_CALLBACK_CANCEL;
536 key_info.powerkey_count = 0;
538 if (key_info.is_lcd_on) {
539 if(VCONFKEY_PM_STATE_LCDOFF <= status_active_get()->pm_state) {
540 _E("Already lcd state was changed while powerkey op. starter ignore powerkey operation");
541 return ECORE_CALLBACK_CANCEL;
544 _W("just turn on LCD by powerkey.. starter ignore powerkey operation");
545 return ECORE_CALLBACK_CANCEL;
548 if (VCONFKEY_CALL_VOICE_ACTIVE == status_passive_get()->call_state) {
549 _W("call state is [%d] -> just turn off LCD");
550 display_change_state(LCD_OFF);
551 return ECORE_CALLBACK_CANCEL;
554 if (VCONFKEY_IDLE_LOCK == status_passive_get()->idle_lock_state) {
555 _W("lock state is [%d] -> just turn off LCD");
556 display_change_state(LCD_OFF);
557 return ECORE_CALLBACK_CANCEL;
560 if (0 < status_passive_get()->remote_lock_islocked) {
561 _W("remote lock is on top (%d), -> just turn off LCD", status_passive_get()->remote_lock_islocked);
562 display_change_state(LCD_OFF);
563 return ECORE_CALLBACK_CANCEL;
566 home_mgr_launch_home_by_power();
568 return ECORE_CALLBACK_CANCEL;
573 static Eina_Bool _key_release_cb(void *data, int type, void *event)
575 Evas_Event_Key_Up *ev = event;
577 retv_if(!ev, ECORE_CALLBACK_RENEW);
578 retv_if(!ev->keyname, ECORE_CALLBACK_RENEW);
580 _D("_key_release_cb : %s Released", ev->keyname);
582 if (!strcmp(ev->keyname, key_name[KEY_POWER])) {
583 _W("POWER Key is released");
585 if(key_info.power_long_press_timer) {
586 ecore_timer_del(key_info.power_long_press_timer);
587 key_info.power_long_press_timer = NULL;
588 _D("delete long press timer");
591 // Check powerkey timer
592 if(key_info.power_release_timer) {
593 ecore_timer_del(key_info.power_release_timer);
594 key_info.power_release_timer = NULL;
595 _D("delete powerkey timer");
598 // Cancel key operation
599 if (EINA_TRUE == key_info.is_cancel) {
600 _D("Cancel key is activated");
601 key_info.is_cancel = EINA_FALSE;
602 key_info.powerkey_count = 0; //initialize powerkey count
603 return ECORE_CALLBACK_RENEW;
606 // Check long press operation
607 if(key_info.is_long_press) {
608 _D("ignore power key release by long poress");
609 key_info.is_long_press = EINA_FALSE;
610 return ECORE_CALLBACK_RENEW;
613 if(key_info.is_lcd_on) {
614 key_info.power_release_timer = ecore_timer_add(POWERKEY_TIMER_SEC, _powerkey_timer_cb, NULL);
616 _D("lcd off --> [%f]sec timer", POWERKEY_LCDOFF_TIMER_SEC);
617 key_info.power_release_timer = ecore_timer_add(POWERKEY_LCDOFF_TIMER_SEC, _powerkey_timer_cb, NULL);
619 if (!key_info.power_release_timer) {
620 _E("Critical, cannot add a timer for powerkey");
622 } else if (!strcmp(ev->keyname, key_name[KEY_CANCEL])) {
623 _D("CANCEL Key is released");
624 key_info.is_cancel = EINA_FALSE;
627 return ECORE_CALLBACK_RENEW;
632 static Eina_Bool _key_press_cb(void *data, int type, void *event)
634 Evas_Event_Key_Down *ev = event;
636 retv_if(!ev, ECORE_CALLBACK_RENEW);
637 retv_if(!ev->keyname, ECORE_CALLBACK_RENEW);
639 _D("_key_press_cb : %s Pressed", ev->keyname);
641 if (!strcmp(ev->keyname, key_name[KEY_POWER])) {
642 _W("POWER Key is pressed");
651 if (VCONFKEY_PM_STATE_LCDDIM >= status_active_get()->pm_state) {
652 key_info.is_lcd_on = EINA_TRUE;
653 } else if (VCONFKEY_PM_STATE_LCDOFF <= status_active_get()->pm_state) {
654 key_info.is_lcd_on = EINA_FALSE;
657 key_info.powerkey_count++;
658 _W("powerkey count : %d", key_info.powerkey_count);
660 if(key_info.power_release_timer) {
661 ecore_timer_del(key_info.power_release_timer);
662 key_info.power_release_timer = NULL;
665 if (key_info.power_long_press_timer) {
666 ecore_timer_del(key_info.power_long_press_timer);
667 key_info.power_long_press_timer = NULL;
670 key_info.is_long_press = EINA_FALSE;
671 key_info.power_long_press_timer = ecore_timer_add(LONG_PRESS_TIMER_SEC, _long_press_timer_cb, NULL);
672 if(!key_info.power_long_press_timer) {
673 _E("Failed to add power_long_press_timer");
675 } else if (!strcmp(ev->keyname, key_name[KEY_CANCEL])) {
676 _D("CANCEL key is pressed");
677 key_info.is_cancel = EINA_TRUE;
680 return ECORE_CALLBACK_RENEW;
685 static Eina_Bool __keygrab_timer_cb(void *data)
690 for (i = 0; i < KEY_NAME_MAX; i++) {
691 ret = ecore_wl_window_keygrab_set(NULL, key_name[i], 0, 0, 0, ECORE_WL_WINDOW_KEYGRAB_SHARED);
692 _D("key grab : %s / ret : %d", key_name[i], ret);
695 key_info.key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_release_cb, NULL);
696 if (!key_info.key_up) {
697 _E("Failed to register a key up event handler");
700 key_info.key_down = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_press_cb, NULL);
701 if (!key_info.key_down) {
702 _E("Failed to register a key down event handler");
705 return ECORE_CALLBACK_CANCEL;
710 void hw_key_create_window(void)
712 if (key_info.keygrab_timer) {
713 ecore_timer_del(key_info.keygrab_timer);
714 key_info.keygrab_timer = NULL;
717 key_info.keygrab_timer = ecore_timer_add(1.0f, __keygrab_timer_cb, NULL);
718 if (!key_info.keygrab_timer) {
719 _E("Failed to add timer for keygrab");
725 void hw_key_destroy_window(void)
729 for (i = 0; i < KEY_NAME_MAX; i++) {
730 ecore_wl_window_keygrab_unset(NULL, key_name[i], 0, 0);
733 if (key_info.keygrab_timer) {
734 ecore_timer_del(key_info.keygrab_timer);
735 key_info.keygrab_timer = NULL;
738 if (key_info.key_up) {
739 ecore_event_handler_del(key_info.key_up);
740 key_info.key_up = NULL;
743 if (key_info.key_down) {
744 ecore_event_handler_del(key_info.key_down);
745 key_info.key_down = NULL;