Update minictrl and assistive_light
[apps/core/preloaded/quickpanel.git] / daemon / service / keyboard_x.c
1 /*
2  * Copyright (c) 2009-2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 #include <Elementary.h>
19 #include <Ecore_X.h>
20 #include <Ecore_Input.h>
21 #include <X11/Xlib.h>
22 #include <X11/extensions/XInput.h>
23 #include <X11/extensions/XInput2.h>
24
25 #include <vconf.h>
26 #include <utilX.h>
27 #include <feedback.h>
28 #include <tzsh.h>
29 #include <tzsh_quickpanel_service.h>
30 #include <notification.h>
31 #include <E_DBus.h>
32
33 #include "quickpanel-ui.h"
34 #include "common.h"
35 #include "noti_util.h"
36 #include "keyboard_x.h"
37
38 #define TAB             23
39 #define SHIFT           50
40 #define RETURN          36
41 #define ARROW_KP_UP     80
42 #define ARROW_KP_DOWN   88
43 #define ARROW_KP_LEFT   83
44 #define ARROW_KP_RIGHT  85
45 #define ARROW_UP        111
46 #define ARROW_DOWN      116
47 #define ARROW_LEFT      113
48 #define ARROW_RIGHT     114
49
50 typedef struct _key_info {
51         int keycode;
52         const char *keyname;
53         const char *key;
54         const char *string;
55         const char *compose;
56 } key_info;
57
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 },
70 };
71
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);
77
78 static struct _s_info {
79         int xi2_opcode;
80         int is_shift_pressed;
81         Ecore_Event_Handler *hdl_key_event;
82 } s_info = {
83         .xi2_opcode = -1,
84         .is_shift_pressed = 0,
85         .hdl_key_event = NULL,
86 };
87
88 static int _key_event_validation_check(int keycode)
89 {
90         int i = 0, len = 0;
91
92         len = sizeof(key_infos) / sizeof(key_infos[0]);
93
94         for (i = 0; i < len; i++ ) {
95                 if (key_infos[i].keycode == keycode) {
96                         return 1;
97                 }
98         }
99
100         return 0;
101 }
102
103 static void _key_event_select(void)
104 {
105         int rc;
106         XIEventMask mask;
107         Ecore_X_Display *d;
108
109         d = ecore_x_display_get();
110         if (d == NULL) {
111                 ERR("failed to get ecore-display");
112                 return;
113         }
114
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");
120                 return;
121         }
122         memset(mask.mask, 0, mask.mask_len);
123
124         XISetMask(mask.mask, XI_RawKeyPress);
125         XISetMask(mask.mask, XI_RawKeyRelease);
126
127         rc = XISelectEvents(d, ecore_x_window_root_first_get(), &mask, 1);
128         if (Success != rc) {
129                 ERR("Failed to select XInput extension events");
130         }
131         if (mask.mask) {
132                 free( mask.mask);
133         }
134         ecore_x_sync();
135 }
136
137 static Eina_Bool _xinput_init(void)
138 {
139         int event, error;
140
141         if (!XQueryExtension(ecore_x_display_get(), "XInputExtension", &s_info.xi2_opcode, &event, &error)) {
142                 s_info.xi2_opcode = -1;
143
144                 SERR("failed to initialize key event receiver");
145                 return EINA_FALSE;
146         }
147
148         _key_event_select();
149
150         return EINA_TRUE;
151 }
152
153 static int _cb_event_generic(void *data, int ev_type, void *event)
154 {
155         Ecore_X_Event_Generic *e;
156         XIDeviceEvent *evData;
157
158         e = (Ecore_X_Event_Generic *)event;
159         evData = (XIDeviceEvent *)(e->data);
160
161         if (e->extension != s_info.xi2_opcode) {
162                 return ECORE_CALLBACK_PASS_ON;
163         }
164
165         if (!evData || evData->send_event) {
166                 return ECORE_CALLBACK_PASS_ON;
167         }
168
169         switch (e->evtype) {
170         case XI_RawKeyPress:
171                 if (evData->deviceid == 3) {
172                         break;
173                 }
174                 _focus_ui_process_press((XIRawEvent *)evData);
175                 break;
176         case XI_RawKeyRelease:
177                 if (evData->deviceid == 3) {
178                         break;
179                 }
180                 _focus_ui_process_release((XIRawEvent *)evData);
181                 break;
182         default:
183                 break;
184         }
185
186         return ECORE_CALLBACK_PASS_ON;
187 }
188
189 static void _focus_ui_process_press(XIRawEvent *raw_event)
190 {
191         XEvent xev;
192         Ecore_X_Display *d;
193         struct appdata *ad;
194
195         ad = quickpanel_get_app_data();
196         retif(ad == NULL, , "invalid data.");
197         retif(raw_event == NULL, , "invalid data.");
198
199         if (raw_event->detail == SHIFT) {
200                 s_info.is_shift_pressed = 1;
201                 return;
202         }
203         if (_key_event_validation_check(raw_event->detail) == 0) {
204                 return;
205         }
206
207         d = ecore_x_display_get();
208         if (d == NULL) {
209                 ERR("failed to get ecore-display");
210                 return;
211         }
212
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;
219         } else {
220                 xev.xkey.state = 0;
221         }
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);
229 }
230
231 static void _focus_ui_process_release(XIRawEvent *raw_event)
232 {
233         XEvent xev;
234         Ecore_X_Display *d;
235         struct appdata *ad;
236
237         ad = quickpanel_get_app_data();
238         retif(ad == NULL, , "invalid data.");
239         retif(raw_event == NULL, , "invalid data.");
240
241         if (raw_event->detail == SHIFT) {
242                 s_info.is_shift_pressed = 0;
243                 return;
244         }
245
246         if (_key_event_validation_check(raw_event->detail) == 0) {
247                 return;
248         }
249
250         d = ecore_x_display_get();
251         if (d == NULL) {
252                 ERR("failed to get ecore-display");
253                 return;
254         }
255
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;
262         } else {
263                 xev.xkey.state = 0;
264         }
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);
272 }
273
274 static void _focus_cleanup(void *data)
275 {
276         struct appdata *ad = data;
277         Evas_Object *focused_obj = NULL;
278         retif(ad == NULL, , "invalid data.");
279         retif(ad->win == NULL, , "invalid data.");
280
281         focused_obj = elm_object_focused_object_get(ad->win);
282         if (focused_obj != NULL) {
283                 elm_object_focus_set(focused_obj, EINA_FALSE);
284         }
285         elm_win_focus_highlight_enabled_set(ad->win, EINA_FALSE);
286 }
287
288 HAPI void quickpanel_keyboard_x_init(void *data)
289 {
290         struct appdata *ad = data;
291         retif(ad == NULL, , "Invalid parameter!");
292
293         _xinput_init();
294 }
295
296 HAPI void quickpanel_keyboard_x_fini(void *data)
297 {
298         struct appdata *ad;
299
300         ad = data;
301         retif(ad == NULL, , "Invalid parameter!");
302
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;
306         }
307
308         _focus_cleanup(ad);
309 }
310
311 HAPI void quickpanel_keyboard_x_openning_init(void *data)
312 {
313         struct appdata *ad;
314
315         ad = data;
316         retif(ad == NULL, , "Invalid parameter!");
317
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;
321         }
322         s_info.hdl_key_event =  ecore_event_handler_add(ECORE_X_EVENT_GENERIC, (Ecore_Event_Handler_Cb)_cb_event_generic, NULL);
323 }
324
325 HAPI void quickpanel_keyboard_x_closing_fini(void *data)
326 {
327         struct appdata *ad;
328
329         ad = data;
330         retif(ad == NULL, , "Invalid parameter!");
331
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;
335         }
336
337         if (ad->win != NULL) {
338                 elm_win_focus_highlight_enabled_set(ad->win, EINA_FALSE);
339         }
340 }