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)
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", &s_info.xi2_opcode, &event, &error)) {
142 s_info.xi2_opcode = -1;
144 SERR("failed to initialize key event receiver");
153 static int _cb_event_generic(void *data, int ev_type, void *event)
155 Ecore_X_Event_Generic *e;
156 XIDeviceEvent *evData;
158 e = (Ecore_X_Event_Generic *)event;
159 evData = (XIDeviceEvent *)(e->data);
161 if (e->extension != s_info.xi2_opcode) {
162 return ECORE_CALLBACK_PASS_ON;
165 if (!evData || evData->send_event) {
166 return ECORE_CALLBACK_PASS_ON;
171 if (evData->deviceid == 3) {
174 _focus_ui_process_press((XIRawEvent *)evData);
176 case XI_RawKeyRelease:
177 if (evData->deviceid == 3) {
180 _focus_ui_process_release((XIRawEvent *)evData);
186 return ECORE_CALLBACK_PASS_ON;
189 static void _focus_ui_process_press(XIRawEvent *raw_event)
195 ad = quickpanel_get_app_data();
196 retif(ad == NULL, , "invalid data.");
197 retif(raw_event == NULL, , "invalid data.");
199 if (raw_event->detail == SHIFT) {
200 s_info.is_shift_pressed = 1;
203 if (_key_event_validation_check(raw_event->detail) == 0) {
207 d = ecore_x_display_get();
209 ERR("failed to get ecore-display");
213 memset(&xev, 0, sizeof(XEvent));
214 xev.xany.display = ecore_x_display_get();
215 xev.xkey.keycode = raw_event->detail;
216 xev.xkey.time = raw_event->time;
217 if (s_info.is_shift_pressed == 1) {
218 xev.xkey.state = 0x1;
222 xev.xkey.root = ecore_x_window_root_first_get();
223 xev.xkey.send_event = 1;
224 xev.xkey.subwindow = None;
225 xev.xkey.type = KeyPress;
226 xev.xkey.window = elm_win_xwindow_get(ad->win);
227 XSendEvent(d, elm_win_xwindow_get(ad->win) , False, NoEventMask, &xev);
228 DBG("keypressed:%d", raw_event->detail);
231 static void _focus_ui_process_release(XIRawEvent *raw_event)
237 ad = quickpanel_get_app_data();
238 retif(ad == NULL, , "invalid data.");
239 retif(raw_event == NULL, , "invalid data.");
241 if (raw_event->detail == SHIFT) {
242 s_info.is_shift_pressed = 0;
246 if (_key_event_validation_check(raw_event->detail) == 0) {
250 d = ecore_x_display_get();
252 ERR("failed to get ecore-display");
256 memset(&xev, 0, sizeof(XEvent));
257 xev.xany.display = d;
258 xev.xkey.keycode = raw_event->detail;
259 xev.xkey.time = raw_event->time;
260 if (s_info.is_shift_pressed == 1) {
261 xev.xkey.state = 0x1;
265 xev.xkey.root = ecore_x_window_root_first_get();
266 xev.xkey.send_event = 1;
267 xev.xkey.subwindow = None;
268 xev.xkey.type = KeyRelease;
269 xev.xkey.window = elm_win_xwindow_get(ad->win);
270 XSendEvent(d, elm_win_xwindow_get(ad->win) , False, NoEventMask, &xev);
271 DBG("keyrelease:%d", raw_event->detail);
274 static void _focus_cleanup(void *data)
276 struct appdata *ad = data;
277 Evas_Object *focused_obj = NULL;
278 retif(ad == NULL, , "invalid data.");
279 retif(ad->win == NULL, , "invalid data.");
281 focused_obj = elm_object_focused_object_get(ad->win);
282 if (focused_obj != NULL) {
283 elm_object_focus_set(focused_obj, EINA_FALSE);
285 elm_win_focus_highlight_enabled_set(ad->win, EINA_FALSE);
288 HAPI void quickpanel_keyboard_x_init(void *data)
290 struct appdata *ad = data;
291 retif(ad == NULL, , "Invalid parameter!");
296 HAPI void quickpanel_keyboard_x_fini(void *data)
301 retif(ad == NULL, , "Invalid parameter!");
303 if (s_info.hdl_key_event != NULL) {
304 ecore_event_handler_del(s_info.hdl_key_event);
305 s_info.hdl_key_event = NULL;
311 HAPI void quickpanel_keyboard_x_openning_init(void *data)
316 retif(ad == NULL, , "Invalid parameter!");
318 if (s_info.hdl_key_event != NULL) {
319 ecore_event_handler_del(s_info.hdl_key_event);
320 s_info.hdl_key_event = NULL;
322 s_info.hdl_key_event = ecore_event_handler_add(ECORE_X_EVENT_GENERIC, (Ecore_Event_Handler_Cb)_cb_event_generic, NULL);
325 HAPI void quickpanel_keyboard_x_closing_fini(void *data)
330 retif(ad == NULL, , "Invalid parameter!");
332 if (s_info.hdl_key_event != NULL) {
333 ecore_event_handler_del(s_info.hdl_key_event);
334 s_info.hdl_key_event = NULL;
337 if (ad->win != NULL) {
338 elm_win_focus_highlight_enabled_set(ad->win, EINA_FALSE);