Update minictrl and assistive_light
[apps/core/preloaded/quickpanel.git] / daemon / service / keyboard_x_x11.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 = NULL;
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",
142                                &s_info.xi2_opcode, &event, &error)) {
143       s_info.xi2_opcode = -1;
144
145       SERR("failed to initialize key event receiver");
146       return EINA_FALSE;
147    }
148
149    _key_event_select();
150
151    return EINA_TRUE;
152 }
153
154 static int _cb_event_generic(void *data, int ev_type, void *event)
155 {
156         Ecore_X_Event_Generic *e = (Ecore_X_Event_Generic *)event;
157         XIDeviceEvent *evData = (XIDeviceEvent *)(e->data);
158
159         if ( e->extension != s_info.xi2_opcode ) {
160                 return ECORE_CALLBACK_PASS_ON;
161         }
162         if ( !evData || evData->send_event ) {
163                 return ECORE_CALLBACK_PASS_ON;
164         }
165
166         switch( e->evtype ) {
167         case XI_RawKeyPress:
168                 if (evData->deviceid == 3) {
169                         break;
170                 }
171                 _focus_ui_process_press((XIRawEvent *)evData);
172                 break;
173         case XI_RawKeyRelease:
174                 if (evData->deviceid == 3) {
175                         break;
176                 }
177                 _focus_ui_process_release((XIRawEvent *)evData);
178                 break;
179         default:
180                 break;
181         }
182
183         return ECORE_CALLBACK_PASS_ON;
184 }
185
186 static void _focus_ui_process_press(XIRawEvent *raw_event)
187 {
188         XEvent xev;
189
190         struct appdata *ad = quickpanel_get_app_data();
191         retif(ad == NULL, , "invalid data.");
192         retif(raw_event == NULL, , "invalid data.");
193
194         if (raw_event->detail == SHIFT) {
195                 s_info.is_shift_pressed = 1;
196                 return;
197         }
198         if (_key_event_validation_check(raw_event->detail) == 0) {
199                 return;
200         }
201
202         Ecore_X_Display *d = ecore_x_display_get();
203     if (d == NULL) {
204         ERR("failed to get ecore-display");
205         return;
206     }
207
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;
214         } else {
215                 xev.xkey.state = 0;
216         }
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);
225 }
226
227 static void _focus_ui_process_release(XIRawEvent *raw_event)
228 {
229         XEvent xev;
230
231         struct appdata *ad = quickpanel_get_app_data();
232         retif(ad == NULL, , "invalid data.");
233         retif(raw_event == NULL, , "invalid data.");
234
235         if (raw_event->detail == SHIFT) {
236                 s_info.is_shift_pressed = 0;
237                 return;
238         }
239         if (_key_event_validation_check(raw_event->detail) == 0) {
240                 return;
241         }
242
243         Ecore_X_Display *d = ecore_x_display_get();
244     if (d == NULL) {
245         ERR("failed to get ecore-display");
246         return;
247     }
248
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;
255         } else {
256                 xev.xkey.state = 0;
257         }
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);
266 }
267
268 static void _focus_cleanup(void *data)
269 {
270         struct appdata *ad = data;
271         Evas_Object *focused_obj = NULL;
272         retif(ad == NULL, , "invalid data.");
273         retif(ad->win == NULL, , "invalid data.");
274
275         focused_obj = elm_object_focused_object_get(ad->win);
276         if (focused_obj != NULL) {
277                 elm_object_focus_set(focused_obj, EINA_FALSE);
278         }
279         elm_win_focus_highlight_enabled_set(ad->win, EINA_FALSE);
280 }
281
282 HAPI void quickpanel_keyboard_x_init(void *data)
283 {
284         struct appdata *ad = data;
285         retif(ad == NULL, , "Invalid parameter!");
286
287         _xinput_init();
288 }
289
290 HAPI void quickpanel_keyboard_x_fini(void *data)
291 {
292         struct appdata *ad = data;
293         retif(ad == NULL, , "Invalid parameter!");
294
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;
298         }
299
300         _focus_cleanup(ad);
301 }
302
303 HAPI void quickpanel_keyboard_x_openning_init(void *data)
304 {
305         struct appdata *ad = data;
306         retif(ad == NULL, , "Invalid parameter!");
307
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;
311         }
312         s_info.hdl_key_event =
313                         ecore_event_handler_add(ECORE_X_EVENT_GENERIC, (Ecore_Event_Handler_Cb)_cb_event_generic, NULL);
314 }
315
316 HAPI void quickpanel_keyboard_x_closing_fini(void *data)
317 {
318         struct appdata *ad = data;
319         retif(ad == NULL, , "Invalid parameter!");
320
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;
324         }
325
326         if (ad->win != NULL) {
327                 elm_win_focus_highlight_enabled_set(ad->win, EINA_FALSE);
328         }
329 }