2 * Copyright (c) 2009-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.
18 #include <Elementary.h>
20 #include <Ecore_Input.h>
22 #include <X11/extensions/XInput.h>
23 #include <X11/extensions/XInput2.h>
29 #include <tzsh_quickpanel_service.h>
30 #include <notification.h>
33 #include "quickpanel-ui.h"
35 #include "noti_util.h"
36 #include "keyboard_x.h"
41 #define ARROW_KP_UP 80
42 #define ARROW_KP_DOWN 88
43 #define ARROW_KP_LEFT 83
44 #define ARROW_KP_RIGHT 85
46 #define ARROW_DOWN 116
47 #define ARROW_LEFT 113
48 #define ARROW_RIGHT 114
50 typedef struct _key_info {
58 key_info key_infos[] = {
59 {TAB, "Tab", "Tab", "\t", "\t"},
60 {RETURN, "Return", "Return", "\n", "\n"},
61 {ARROW_UP, "Up", "Up", NULL, NULL},
62 {ARROW_KP_UP, "Up", "Up", NULL, NULL},
63 {ARROW_DOWN, "Down", "Down", NULL, NULL},
64 {ARROW_KP_DOWN, "Down", "Down", NULL, NULL},
65 {ARROW_LEFT, "Left", "Left", NULL, NULL},
66 {ARROW_KP_LEFT, "Left", "Left", NULL, NULL},
67 {ARROW_RIGHT, "Right", "Right", NULL, NULL},
68 {ARROW_KP_RIGHT, "Right", "Right", NULL, NULL},
69 {SHIFT, "Shift", "Shift", NULL, NULL},
72 static int _cb_event_generic(void *data, int ev_type, void *event);
73 static Eina_Bool _xinput_init(void);
74 static void _key_event_select(void);
75 static void _focus_ui_process_press(XIRawEvent *raw_event);
76 static void _focus_ui_process_release(XIRawEvent *raw_event);
78 static struct _s_info {
81 Ecore_Event_Handler *hdl_key_event;
84 .is_shift_pressed = 0,
85 .hdl_key_event = NULL,
88 static int _key_event_validation_check(int keycode)
92 len = sizeof(key_infos) / sizeof(key_infos[0]);
94 for (i = 0; i < len; i++ ) {
95 if (key_infos[i].keycode == keycode) {
103 static void _key_event_select(void)
107 Ecore_X_Display *d = NULL;
109 d = ecore_x_display_get();
111 ERR("failed to get ecore-display");
115 mask.mask_len = XIMaskLen(XI_LASTEVENT);
116 mask.deviceid = XIAllDevices;
117 mask.mask = calloc(mask.mask_len, sizeof(char));
118 if (mask.mask == NULL) {
119 ERR("failed to get ecore-display");
122 memset(mask.mask, 0, mask.mask_len);
124 XISetMask(mask.mask, XI_RawKeyPress);
125 XISetMask(mask.mask, XI_RawKeyRelease);
127 rc = XISelectEvents(d, ecore_x_window_root_first_get(), &mask, 1);
129 ERR("Failed to select XInput extension events");
137 static Eina_Bool _xinput_init(void)
141 if (!XQueryExtension(ecore_x_display_get(), "XInputExtension",
142 &s_info.xi2_opcode, &event, &error)) {
143 s_info.xi2_opcode = -1;
145 SERR("failed to initialize key event receiver");
154 static int _cb_event_generic(void *data, int ev_type, void *event)
156 Ecore_X_Event_Generic *e = (Ecore_X_Event_Generic *)event;
157 XIDeviceEvent *evData = (XIDeviceEvent *)(e->data);
159 if ( e->extension != s_info.xi2_opcode ) {
160 return ECORE_CALLBACK_PASS_ON;
162 if ( !evData || evData->send_event ) {
163 return ECORE_CALLBACK_PASS_ON;
166 switch( e->evtype ) {
168 if (evData->deviceid == 3) {
171 _focus_ui_process_press((XIRawEvent *)evData);
173 case XI_RawKeyRelease:
174 if (evData->deviceid == 3) {
177 _focus_ui_process_release((XIRawEvent *)evData);
183 return ECORE_CALLBACK_PASS_ON;
186 static void _focus_ui_process_press(XIRawEvent *raw_event)
190 struct appdata *ad = quickpanel_get_app_data();
191 retif(ad == NULL, , "invalid data.");
192 retif(raw_event == NULL, , "invalid data.");
194 if (raw_event->detail == SHIFT) {
195 s_info.is_shift_pressed = 1;
198 if (_key_event_validation_check(raw_event->detail) == 0) {
202 Ecore_X_Display *d = ecore_x_display_get();
204 ERR("failed to get ecore-display");
208 memset(&xev, 0, sizeof(XEvent));
209 xev.xany.display = ecore_x_display_get();
210 xev.xkey.keycode = raw_event->detail;
211 xev.xkey.time = raw_event->time;
212 if (s_info.is_shift_pressed == 1) {
213 xev.xkey.state = 0x1;
217 xev.xkey.root = ecore_x_window_root_first_get();
218 xev.xkey.send_event = 1;
219 xev.xkey.subwindow = None;
220 xev.xkey.type = KeyPress;
221 xev.xkey.window = elm_win_xwindow_get(ad->win);
222 XSendEvent(d, elm_win_xwindow_get(ad->win)
223 , False, NoEventMask, &xev);
224 DBG("keypressed:%d", raw_event->detail);
227 static void _focus_ui_process_release(XIRawEvent *raw_event)
231 struct appdata *ad = quickpanel_get_app_data();
232 retif(ad == NULL, , "invalid data.");
233 retif(raw_event == NULL, , "invalid data.");
235 if (raw_event->detail == SHIFT) {
236 s_info.is_shift_pressed = 0;
239 if (_key_event_validation_check(raw_event->detail) == 0) {
243 Ecore_X_Display *d = ecore_x_display_get();
245 ERR("failed to get ecore-display");
249 memset(&xev, 0, sizeof(XEvent));
250 xev.xany.display = d;
251 xev.xkey.keycode = raw_event->detail;
252 xev.xkey.time = raw_event->time;
253 if (s_info.is_shift_pressed == 1) {
254 xev.xkey.state = 0x1;
258 xev.xkey.root = ecore_x_window_root_first_get();
259 xev.xkey.send_event = 1;
260 xev.xkey.subwindow = None;
261 xev.xkey.type = KeyRelease;
262 xev.xkey.window = elm_win_xwindow_get(ad->win);
263 XSendEvent(d, elm_win_xwindow_get(ad->win)
264 , False, NoEventMask, &xev);
265 DBG("keyrelease:%d", raw_event->detail);
268 static void _focus_cleanup(void *data)
270 struct appdata *ad = data;
271 Evas_Object *focused_obj = NULL;
272 retif(ad == NULL, , "invalid data.");
273 retif(ad->win == NULL, , "invalid data.");
275 focused_obj = elm_object_focused_object_get(ad->win);
276 if (focused_obj != NULL) {
277 elm_object_focus_set(focused_obj, EINA_FALSE);
279 elm_win_focus_highlight_enabled_set(ad->win, EINA_FALSE);
282 HAPI void quickpanel_keyboard_x_init(void *data)
284 struct appdata *ad = data;
285 retif(ad == NULL, , "Invalid parameter!");
290 HAPI void quickpanel_keyboard_x_fini(void *data)
292 struct appdata *ad = data;
293 retif(ad == NULL, , "Invalid parameter!");
295 if (s_info.hdl_key_event != NULL) {
296 ecore_event_handler_del(s_info.hdl_key_event);
297 s_info.hdl_key_event = NULL;
303 HAPI void quickpanel_keyboard_x_openning_init(void *data)
305 struct appdata *ad = data;
306 retif(ad == NULL, , "Invalid parameter!");
308 if (s_info.hdl_key_event != NULL) {
309 ecore_event_handler_del(s_info.hdl_key_event);
310 s_info.hdl_key_event = NULL;
312 s_info.hdl_key_event =
313 ecore_event_handler_add(ECORE_X_EVENT_GENERIC, (Ecore_Event_Handler_Cb)_cb_event_generic, NULL);
316 HAPI void quickpanel_keyboard_x_closing_fini(void *data)
318 struct appdata *ad = data;
319 retif(ad == NULL, , "Invalid parameter!");
321 if (s_info.hdl_key_event != NULL) {
322 ecore_event_handler_del(s_info.hdl_key_event);
323 s_info.hdl_key_event = NULL;
326 if (ad->win != NULL) {
327 elm_win_focus_highlight_enabled_set(ad->win, EINA_FALSE);