tizen 2.4 release
[framework/uifw/e17-mod-tizen-devicemgr.git] / src / e_mod_main.c
1
2 #include "e.h"
3 #include "e_devicemgr_privates.h"
4 #include "e_mod_main.h"
5 #include "e_mod_config.h"
6 #include <string.h>
7 #include <X11/XKBlib.h>
8
9 #define XSELECTION_HDMI_NAME     "HDMI"
10 #define XSELECTION_TIMEOUT       10.0
11
12 #define E_MOD_SCRNCONF_CHK(cond) {if (!(cond)) { SLOG(LOG_DEBUG, "DEVICEMGR", "[%s] : '%s' failed.\n", __func__, #cond); }}
13 #define E_MOD_SCRNCONF_CHK_RET(cond, val) {if (!(cond)) { SLOG(LOG_DEBUG, "DEVICEMGR", "[%s] : '%s' failed.\n", __func__, #cond); return val; }}
14 #define E_MOD_SCRNCONF_CHK_GOTO(cond, dst) {if (!(cond)) { SLOG(LOG_DEBUG, "DEVICEMGR", "[%s] : '%s' failed.\n", __func__, #cond); goto dst; }}
15
16 extern char *strcasestr(const char *s, const char *find);
17 DeviceMgr e_devicemgr;
18 static Eina_Bool e_mod_set_disp_clone = EINA_FALSE;
19
20 static int _e_devicemgr_init (void);
21 static void _e_devicemgr_fini (void);
22 static int _e_devicemgr_get_configuration (void);
23 static int _e_devicemgr_update_configuration (void);
24
25 static int _e_devicemgr_cb_crtc_change     (void *data, int type, void *ev);
26 static int _e_devicemgr_cb_output_change   (void *data, int type, void *ev);
27 static int _e_devicemgr_cb_output_property (void *data, int type, void *ev);
28 static int _e_devicemgr_cb_client_message  (void* data, int type, void* event);
29
30 static Eina_Bool _e_devicemgr_dialog_and_connect (Ecore_X_Randr_Output output_xid);
31 static Eina_Bool _e_devicemgr_disconnect (Ecore_X_Randr_Output output_xid);
32 static Eina_Bool _e_devicemgr_selection_clear_cb (void* data, int type, void *event);
33 static Eina_Bool _e_devicemgr_selection_request_cb (void* data, int type, void *event);
34 static Eina_Bool _e_devicemgr_selection_notify_cb (void* data, int type, void *event);
35
36 /* this is needed to advertise a label for the module IN the code (not just
37  * the .desktop file) but more specifically the api version it was compiled
38  * for so E can skip modules that are compiled for an incorrect API version
39  * safely) */
40 EAPI E_Module_Api e_modapi =
41 {
42    E_MODULE_API_VERSION,
43    "DeviceMgr Module of Window Manager"
44 };
45
46 EAPI void*
47 e_modapi_init(E_Module* m)
48 {
49    if (!_e_devicemgr_init())
50      {
51         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed @ _e_devicemgr_init()..!\n", __FUNCTION__);
52         return NULL;
53      }
54
55    /* add handlers */
56    e_devicemgr.client_message_handler = ecore_event_handler_add (ECORE_X_EVENT_CLIENT_MESSAGE, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_client_message, NULL);
57    e_devicemgr.window_property_handler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_window_property, NULL);
58    e_devicemgr.event_generic_handler = ecore_event_handler_add(ECORE_X_EVENT_GENERIC, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_event_generic, NULL);
59    e_devicemgr.zone_add_handler = ecore_event_handler_add(E_EVENT_ZONE_ADD, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_zone_add, NULL);
60    e_devicemgr.zone_del_handler = ecore_event_handler_add(E_EVENT_ZONE_DEL, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_zone_del, NULL);
61    e_devicemgr.window_destroy_handler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_window_destroy, NULL);
62
63    e_devicemgr.e_msg_handler = e_msg_handler_add(_e_mod_move_e_msg_handler, NULL);
64
65    if (!e_devicemgr.window_property_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add ECORE_X_EVENT_WINDOW_PROPERTY handler\n", __FUNCTION__);
66    if (!e_devicemgr.event_generic_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add ECORE_X_EVENT_GENERIC handler\n", __FUNCTION__);
67    if (!e_devicemgr.zone_add_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add E_EVENT_ZONE_ADD handler\n", __FUNCTION__);
68    if (!e_devicemgr.zone_del_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add E_EVENT_ZONE_DEL handler\n", __FUNCTION__);
69    if (!e_devicemgr.e_msg_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add E_MSG handler\n", __FUNCTION__);
70    if (!e_devicemgr.window_destroy_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add ECORE_X_EVENT_WINDOW_DESTROY handler\n", __FUNCTION__);
71 #if 0
72    if (e_devicemgr.scrnconf_enable)
73      {
74         e_devicemgr.randr_crtc_handler = ecore_event_handler_add (ECORE_X_EVENT_RANDR_CRTC_CHANGE, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_crtc_change, NULL);
75         e_devicemgr.randr_output_handler = ecore_event_handler_add (ECORE_X_EVENT_RANDR_OUTPUT_CHANGE, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_output_change, NULL);
76         e_devicemgr.randr_output_property_handler = ecore_event_handler_add (ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_output_property, NULL);
77
78         if (!e_devicemgr.randr_crtc_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add ECORE_X_EVENT_RANDR_CRTC_CHANGE handler\n", __FUNCTION__);
79         if (!e_devicemgr.randr_output_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add ECORE_X_EVENT_RANDR_OUTPUT_CHANGE handler\n", __FUNCTION__);
80         if (!e_devicemgr.randr_output_property_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY handler\n", __FUNCTION__);
81      }
82 #endif
83    return m;
84 }
85
86 EAPI int
87 e_modapi_shutdown(E_Module* m)
88 {
89    ecore_event_handler_del (e_devicemgr.randr_crtc_handler);
90    ecore_event_handler_del (e_devicemgr.randr_output_handler);
91    ecore_event_handler_del (e_devicemgr.randr_output_property_handler);
92    ecore_event_handler_del(e_devicemgr.window_property_handler);
93    ecore_event_handler_del(e_devicemgr.event_generic_handler);
94    ecore_event_handler_del(e_devicemgr.zone_add_handler);
95    ecore_event_handler_del(e_devicemgr.zone_del_handler);
96    if (e_devicemgr.e_msg_handler) e_msg_handler_del(e_devicemgr.e_msg_handler);
97    e_devicemgr.window_property_handler = NULL;
98    e_devicemgr.event_generic_handler = NULL;
99    e_devicemgr.zone_add_handler = NULL;
100    e_devicemgr.zone_del_handler = NULL;
101
102    e_devicemgr.randr_crtc_handler = NULL;
103    e_devicemgr.randr_output_handler = NULL;
104    e_devicemgr.randr_output_property_handler = NULL;
105    _e_devicemgr_fini();
106
107    return 1;
108 }
109
110 EAPI int
111 e_modapi_save(E_Module* m)
112 {
113    /* Do Something */
114    return 1;
115 }
116
117 static int
118 _e_devicemgr_init(void)
119 {
120    unsigned int val = 1;
121    int res, ret = 1;
122    int enable = 1;
123    int disable = 0;
124    int no_window = -1;
125
126    memset(&e_devicemgr, 0, sizeof(DeviceMgr));
127
128    e_devicemgr.disp = ecore_x_display_get();
129
130    if (!e_devicemgr.disp)
131      {
132         SLOG(LOG_DEBUG, "DEVICEMGR", "\e[32m[e_devicemgr] Failed to open display..!\e[0m\n");
133         ret = 0;
134         goto out;
135      }
136
137    e_devicemgr.rootWin = ecore_x_window_root_first_get();
138
139    /* init data structure */
140    e_devicemgr.cursor_show = 0;
141    e_devicemgr.cursor_show_ack = 0;
142    e_devicemgr.rel_move_deviceid = 0;
143    e_devicemgr.vcp_id = -1;
144    e_devicemgr.vcp_xtest_pointer_id = -1;
145    e_devicemgr.vck_xtest_keyboard_id = -1;
146    e_devicemgr.new_master_pointer_id = -1;
147    e_devicemgr.virtual_touchpad_id = -1;
148    e_devicemgr.gamepad_id = -1;
149    e_devicemgr.gesture_id = -1;
150    e_devicemgr.virtual_multitouch_done = 1;
151    e_devicemgr.device_list = NULL;
152    e_devicemgr.palm_disabled = EINA_FALSE;
153    e_devicemgr.atomDeviceEnabled = ecore_x_atom_get(XI_PROP_DEVICE_ENABLE);
154    e_devicemgr.atomRROutput = ecore_x_atom_get(E_PROP_XRROUTPUT);
155    e_devicemgr.atomDeviceName = ecore_x_atom_get(E_PROP_DEVICE_NAME);
156    e_devicemgr.atomDeviceList = ecore_x_atom_get(E_PROP_DEVICE_LIST);
157    e_devicemgr.atomXMouseExist = ecore_x_atom_get(E_PROP_X_MOUSE_EXIST);
158    e_devicemgr.atomXMouseCursorEnable = ecore_x_atom_get(E_PROP_X_MOUSE_CURSOR_ENABLE);
159    e_devicemgr.atomXExtKeyboardExist = ecore_x_atom_get(E_PROP_X_EXT_KEYBOARD_EXIST);
160    e_devicemgr.atomHWKbdInputStarted = ecore_x_atom_get(E_PROP_HW_KEY_INPUT_STARTED);
161    e_devicemgr.atomAxisLabels = ecore_x_atom_get(E_PROP_X_EVDEV_AXIS_LABELS);
162    e_devicemgr.atomButtonLabels = ecore_x_atom_get(E_PROP_X_EVDEV_BUTTON_LABELS);
163    e_devicemgr.atomVirtualTouchpadConfineRegion = ecore_x_atom_get(E_PROP_VIRTUAL_TOUCHPAD_CONFINE_REGION);
164    e_devicemgr.atomVirtualTouchpad = ecore_x_atom_get(E_PROP_VIRTUAL_TOUCHPAD);
165    e_devicemgr.atomVirtualTouchpadInt = ecore_x_atom_get(E_PROP_VIRTUAL_TOUCHPAD_INT);
166    e_devicemgr.atomDeviceMgrInputWindow = ecore_x_atom_get(E_PROP_DEVICEMGR_INPUTWIN);
167    e_devicemgr.atomTouchInput = ecore_x_atom_get(E_PROP_TOUCH_INPUT);
168    e_devicemgr.atomScrnConfDispModeSet = ecore_x_atom_get(STR_ATOM_SCRNCONF_DISPMODE_SET);
169    e_devicemgr.atomVirtMonReq = ecore_x_atom_get(STR_ATOM_VIRT_MONITOR_REQUEST);
170    e_devicemgr.atomHibReq = ecore_x_atom_get(STR_ATOM_HIB_REQUEST);
171    e_devicemgr.atomDevMgrCfg = ecore_x_atom_get(STR_ATOM_DEVICEMGR_CFG);
172    e_devicemgr.atomFloat = ecore_x_atom_get(XATOM_FLOAT);
173    e_devicemgr.atomInputTransform = ecore_x_atom_get(EVDEVMULTITOUCH_PROP_TRANSFORM);
174    e_devicemgr.atomExKeyboardEnabled = ecore_x_atom_get(E_PROP_EXTERNAL_KEYBOARD_ENABLED);
175    e_devicemgr.atomRelativeMoveStatus = ecore_x_atom_get(XI_PROP_REL_MOVE_STATUS);
176    e_devicemgr.atomRelativeMoveAck = ecore_x_atom_get(XI_PROP_REL_MOVE_ACK);
177    e_devicemgr.atomGameModeEnabled = ecore_x_atom_get(E_PROP_GAMEMODE_ENABLED);
178    e_devicemgr.atomMultitouchDeviceId = ecore_x_atom_get(E_PROP_MULTITOUCH_DEVICEID);
179
180    e_devicemgr.atomPalmDisablingWinRunning = ecore_x_atom_get(E_PROP_PALM_DISABLING_WIN_RUNNING);
181    e_devicemgr.palmDisablingWin = -1;
182
183    e_devicemgr.atomPalmRejectionMode = ecore_x_atom_get(GESTURE_PALM_REJECTION_MODE);
184
185    e_devicemgr.atomWindowStackisChanged = ecore_x_atom_get(GESTURE_WINDOW_STACK_CHANGED);
186
187    SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] e_devicemgr.atomRelativeMoveStatus = %d\n", e_devicemgr.atomRelativeMoveStatus);
188    SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] e_devicemgr.atomRelativeMoveAck = %d\n", e_devicemgr.atomRelativeMoveAck);
189
190    memset(&e_devicemgr.virtual_touchpad_area_info, -1, sizeof(e_devicemgr.virtual_touchpad_area_info));
191    memset(&e_devicemgr.virtual_multitouch_id, -1, sizeof(e_devicemgr.virtual_multitouch_id));
192    e_devicemgr.virtual_touchpad_pointed_window = 0;
193    e_devicemgr.zones = NULL;
194
195    e_devicemgr.input_window = ecore_x_window_input_new(e_devicemgr.rootWin, -1, -1, 1, 1);
196
197    if (!e_devicemgr.input_window)
198      {
199         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to create input_window !\n");
200         ret = 0;
201         goto out;
202      }
203    else
204      {
205         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Succeed to create input_window (0x%x)!\n", e_devicemgr.input_window);
206         ecore_x_window_prop_property_set(e_devicemgr.rootWin, e_devicemgr.atomDeviceMgrInputWindow, ECORE_X_ATOM_WINDOW, 32, &e_devicemgr.input_window, 1);
207      }
208
209    ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomTouchInput, &val, 1);
210    ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomExKeyboardEnabled, &enable, 1);
211    ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomGameModeEnabled, &disable, 1);
212    ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomPalmDisablingWinRunning, &no_window, 1);
213
214    res = _e_devicemgr_xinput_init();
215    if (!res)
216      {
217         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to initialize XInput Extension !\n");
218         ret =0;
219         goto out;
220      }
221
222    res = _e_devicemgr_xkb_init();
223    if (!res)
224      {
225         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to initialize XKB Extension !\n");
226         ret = 0;
227         goto out;
228      }
229
230    e_mod_scrnconf_external_init();
231
232    _e_devicemgr_init_transform_matrix();
233    _e_devicemgr_init_input();
234    _e_devicemgr_init_output();
235
236    res = _e_devicemgr_get_configuration();
237    if (!res)
238      {
239         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to get configuration from %s.cfg file !\n", E_DEVICEMGR_CFG);
240         ret =0;
241         goto out;
242      }
243
244    e_mod_scrnconf_container_bg_canvas_visible_set(EINA_FALSE);
245    if(EINA_FALSE == e_mod_sf_rotation_init())
246      {
247         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to init rotation!\n");
248      }
249
250 out:
251    return ret;
252 }
253
254 static void
255 _e_devicemgr_fini(void)
256 {
257    if(EINA_FALSE == e_mod_sf_rotation_deinit())
258      {
259         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to deinit rotation!\n");
260      }
261
262    e_mod_devicemgr_config_shutdown();
263 }
264
265
266 static void
267 _get_preferred_size (int sc_output, int *preferred_w, int *preferred_h)
268 {
269    if (sc_output == SC_EXT_OUTPUT_HDMI)
270      {
271         *preferred_w = e_devicemgr.hdmi_preferred_w;
272         *preferred_h = e_devicemgr.hdmi_preferred_h;
273      }
274    else if (sc_output == SC_EXT_OUTPUT_VIRTUAL)
275      {
276         *preferred_w = e_devicemgr.virtual_preferred_w;
277         *preferred_h = e_devicemgr.virtual_preferred_h;
278      }
279    else
280      {
281         *preferred_w = 0;
282         *preferred_h = 0;
283      }
284 }
285
286 static void
287 _e_devicemgr_selection_atom_init (void)
288 {
289    static Eina_Bool init = EINA_FALSE;
290
291    if (init) return;
292    init = EINA_TRUE;
293
294    if (!e_devicemgr.selection_atom)
295       e_devicemgr.selection_atom = ecore_x_atom_get ("SEL_EXT_DISPLAY");
296    if( !e_devicemgr.selection_type_atom)
297       e_devicemgr.selection_type_atom = ecore_x_atom_get ("SEL_EXT_DISPLAY_TYPE");
298 }
299
300 static void
301 _e_devicemgr_selection_dialog_new (char *owner)
302 {
303     Ecore_Exe *exe;
304     char cmd[4096];
305
306     E_MOD_SCRNCONF_CHK (owner != NULL);
307
308     /* external_dialog_name, icccm_name, icccm_class, popup_title, popup_contents */
309     snprintf (cmd, sizeof (cmd), "/usr/bin/extndialog HDMI-CONVERGENCE HDMI-CONVERGENCE %s", owner);
310     exe = ecore_exe_run (cmd, NULL);
311
312     SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] Do '%s'. exe(%p)\n", cmd, exe);
313
314     if (exe)
315         ecore_exe_free (exe);
316 }
317
318 static char*
319 _e_devicemgr_selection_get_owner (void)
320 {
321    Ecore_X_Window xwin;
322
323    _e_devicemgr_selection_atom_init ();
324
325    xwin = ecore_x_selection_owner_get (e_devicemgr.selection_atom);
326    if (!xwin)
327       return NULL;
328
329    return ecore_x_window_prop_string_get (xwin, e_devicemgr.selection_type_atom);
330 }
331
332 static void
333 _e_devicemgr_selection_ensure_xwindow (void)
334 {
335    if (e_devicemgr.selection_xwin > 0)
336       return;
337
338    e_devicemgr.selection_xwin = ecore_x_window_new ((Ecore_X_Window)NULL, -100, -100, 10, 10);
339    E_MOD_SCRNCONF_CHK (e_devicemgr.selection_xwin != 0);
340    XStoreName (ecore_x_display_get (), e_devicemgr.selection_xwin, "DEVMGR-HDMI-SELECTION");
341    ecore_x_window_override_set (e_devicemgr.selection_xwin, EINA_TRUE);
342    ecore_x_window_show (e_devicemgr.selection_xwin);
343 }
344
345 static Eina_Bool
346 _e_devicemgr_selection_request_timeout (void *data)
347 {
348    SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] xselection timeout(%d)\n",
349          (int)XSELECTION_TIMEOUT);
350
351    _e_devicemgr_selection_notify_cb (NULL, 0, NULL);
352
353    return ECORE_CALLBACK_CANCEL;
354 }
355
356 static void
357 _e_devicemgr_selection_request (void)
358 {
359    _e_devicemgr_selection_atom_init ();
360    _e_devicemgr_selection_ensure_xwindow ();
361
362    SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] request that '%s' releases xselection ownership.\n", e_devicemgr.selection_prev_owner);
363
364    /* handler for xselection */
365    e_devicemgr.selection_notify_handler = ecore_event_handler_add (ECORE_X_EVENT_SELECTION_NOTIFY,
366                                              _e_devicemgr_selection_notify_cb, NULL);
367    e_devicemgr.selection_request_timeout = ecore_timer_add (XSELECTION_TIMEOUT,
368                                              _e_devicemgr_selection_request_timeout, NULL);
369
370    XConvertSelection (ecore_x_display_get (),
371                       e_devicemgr.selection_atom,
372                       e_devicemgr.selection_type_atom,
373                       e_devicemgr.selection_type_atom,
374                       e_devicemgr.selection_xwin, 0);
375 }
376
377 static Eina_Bool
378 _e_devicemgr_selection_set (void)
379 {
380    if (e_devicemgr.selection_ownership)
381      {
382         SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] already has xselection ownership.\n");
383         return EINA_TRUE;
384      }
385
386    _e_devicemgr_selection_atom_init ();
387    _e_devicemgr_selection_ensure_xwindow ();
388
389    /* The previous owner receives a "SelectionClear" event. */
390    ecore_x_selection_owner_set (e_devicemgr.selection_xwin, e_devicemgr.selection_atom, 0);
391    if (e_devicemgr.selection_xwin != ecore_x_selection_owner_get (e_devicemgr.selection_atom))
392      {
393         SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] failed to take xselection ownership.\n");
394         return EINA_FALSE;
395      }
396
397    e_devicemgr.selection_clear_handler = ecore_event_handler_add (ECORE_X_EVENT_SELECTION_CLEAR,
398                                             _e_devicemgr_selection_clear_cb, NULL);
399    e_devicemgr.selection_request_handler = ecore_event_handler_add (ECORE_X_EVENT_SELECTION_REQUEST,
400                                               _e_devicemgr_selection_request_cb, NULL);
401
402    ecore_x_window_prop_string_set (e_devicemgr.selection_xwin, e_devicemgr.selection_type_atom, XSELECTION_HDMI_NAME);
403    SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] set xselection ownership. xwin(%x)\n", e_devicemgr.selection_xwin);
404
405    e_devicemgr.selection_ownership = EINA_TRUE;
406
407    return EINA_TRUE;
408 }
409
410 static Eina_Bool
411 _e_devicemgr_selection_clear (void)
412 {
413    _e_devicemgr_selection_atom_init ();
414
415    e_devicemgr.selection_ownership = EINA_FALSE;
416
417    if (e_devicemgr.selection_xwin)
418      {
419         ecore_x_window_free (e_devicemgr.selection_xwin);
420         e_devicemgr.selection_xwin = 0;
421      }
422
423    e_devicemgr.selection_output_xid = 0;
424    memset (e_devicemgr.selection_prev_owner, 0, sizeof (e_devicemgr.selection_prev_owner));
425
426    if (e_devicemgr.selection_clear_handler)
427      {
428         ecore_event_handler_del (e_devicemgr.selection_clear_handler);
429         e_devicemgr.selection_clear_handler = NULL;
430      }
431    if (e_devicemgr.selection_request_handler)
432      {
433         ecore_event_handler_del (e_devicemgr.selection_request_handler);
434         e_devicemgr.selection_request_handler = NULL;
435      }
436    if (e_devicemgr.selection_notify_handler)
437      {
438         ecore_event_handler_del (e_devicemgr.selection_notify_handler);
439         e_devicemgr.selection_notify_handler = NULL;
440      }
441    if (e_devicemgr.selection_request_timeout)
442      {
443         ecore_timer_del (e_devicemgr.selection_request_timeout);
444         e_devicemgr.selection_request_timeout = NULL;
445      }
446
447    SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] clear xselection\n");
448
449    return EINA_TRUE;
450 }
451
452 static Eina_Bool
453 _e_devicemgr_selection_clear_cb (void* data, int type, void *event)
454 {
455    SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] xselection ownership gone.\n");
456
457    if (e_devicemgr.selection_ownership)
458       _e_devicemgr_disconnect (e_devicemgr.selection_output_xid);
459
460    return EINA_FALSE;
461 }
462
463 static Eina_Bool
464 _e_devicemgr_selection_request_cb (void* data, int type, void *event)
465 {
466    Ecore_X_Event_Selection_Request *e = (Ecore_X_Event_Selection_Request*)event;
467
468    SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] someone wants to take ownership.\n");
469
470    _e_devicemgr_disconnect (e_devicemgr.selection_output_xid);
471
472    /* send notify for other application to allow to take ownership */
473    ecore_x_selection_notify_send (e->requestor, e->selection, e->target,
474                                   e->property, 0);
475
476    return EINA_FALSE;
477 }
478
479 static Eina_Bool
480 _e_devicemgr_selection_notify_cb (void* data, int type, void *event)
481 {
482    SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] ready to take ownership.\n");
483
484    if (e_devicemgr.selection_request_timeout)
485      {
486         ecore_timer_del (e_devicemgr.selection_request_timeout);
487         e_devicemgr.selection_request_timeout = NULL;
488      }
489    if (e_devicemgr.selection_notify_handler)
490      {
491         ecore_event_handler_del (e_devicemgr.selection_notify_handler);
492         e_devicemgr.selection_notify_handler = NULL;
493      }
494
495    if(!_e_devicemgr_selection_set ())
496       return EINA_FALSE;
497
498    _e_devicemgr_selection_dialog_new (e_devicemgr.selection_prev_owner);
499    _e_devicemgr_dialog_and_connect (e_devicemgr.selection_output_xid);
500
501    return EINA_FALSE;
502 }
503
504 static Eina_Bool
505 _e_devicemgr_dialog_and_connect (Ecore_X_Randr_Output output_xid)
506 {
507    int preferred_w =0, preferred_h = 0;
508    int sc_output = 0;
509    int sc_res = 0;
510
511    /* set the output of the external monitor */
512    sc_output = e_mod_scrnconf_external_get_output_from_xid (output_xid);
513    E_MOD_SCRNCONF_CHK_RET (sc_output != SC_EXT_OUTPUT_NULL, EINA_TRUE);
514
515    e_mod_scrnconf_external_set_output (sc_output);
516
517    /* set the resolution of the external monitor */
518    _get_preferred_size (sc_output, &preferred_w, &preferred_h);
519    sc_res = e_mod_scrnconf_external_get_default_res (sc_output, preferred_w, preferred_h);
520    E_MOD_SCRNCONF_CHK_GOTO (sc_res != SC_EXT_RES_NULL, fail);
521    e_mod_scrnconf_external_set_res (sc_res);
522
523    /* set the default display mode of the external monitor */
524    if (e_devicemgr.default_dispmode == UTILX_SCRNCONF_DISPMODE_CLONE ||
525        e_devicemgr.default_dispmode == UTILX_SCRNCONF_DISPMODE_EXTENDED)
526      {
527
528         if (!e_mod_scrnconf_external_set_dispmode (sc_output, e_devicemgr.default_dispmode, sc_res))
529           {
530               e_mod_scrnconf_external_set_status (UTILX_SCRNCONF_STATUS_CONNECT);
531               /* generate dialog */
532               if (e_devicemgr.isPopUpEnabled)
533                  e_mod_scrnconf_external_dialog_new (sc_output);
534               goto fail;
535           }
536
537         e_mod_scrnconf_external_set_status (UTILX_SCRNCONF_STATUS_ACTIVE);
538      }
539    else
540      {
541         e_mod_scrnconf_external_set_status (UTILX_SCRNCONF_STATUS_CONNECT);
542      }
543
544    /* generate dialog */
545    if (e_devicemgr.isPopUpEnabled)
546       e_mod_scrnconf_external_dialog_new (sc_output);
547
548    e_mod_scrnconf_external_send_current_status();
549
550    return EINA_TRUE;
551
552 fail:
553    e_mod_scrnconf_external_reset (sc_output);
554    return EINA_TRUE;
555 }
556
557 static Eina_Bool
558 _e_devicemgr_disconnect (Ecore_X_Randr_Output output_xid)
559 {
560    int sc_output = 0;
561
562    /* if display mode is set by the client message, ignore output disconnected */
563    if (e_mod_set_disp_clone)
564       return EINA_TRUE;
565
566    _e_devicemgr_selection_clear ();
567
568    /* set the output of the external monitor */
569    sc_output = e_mod_scrnconf_external_get_output_from_xid (output_xid);
570    E_MOD_SCRNCONF_CHK_RET (sc_output != SC_EXT_OUTPUT_NULL, 1);
571
572    e_mod_scrnconf_external_reset (sc_output);
573
574    e_mod_scrnconf_external_send_current_status();
575
576    /* if dialog is still showing, destroy dialog */
577    e_mod_scrnconf_external_dialog_free();
578
579    e_mod_scrnconf_container_bg_canvas_visible_set(EINA_FALSE);
580
581    return EINA_TRUE;
582 }
583
584 static int
585 _e_devicemgr_cb_crtc_change (void *data, int type, void *ev)
586 {
587    if (type == ECORE_X_EVENT_RANDR_CRTC_CHANGE)
588      {
589         //SLOG(LOG_DEBUG, "DEVICEMGR", "[scrn-conf]: Crtc Change!: \n");
590         //Ecore_X_Event_Randr_Crtc_Change *event = (Ecore_X_Event_Randr_Crtc_Change *)ev;
591         /* available information:
592            struct _Ecore_X_Event_Randr_Crtc_Change
593            {
594               Ecore_X_Window                win;
595               Ecore_X_Randr_Crtc            crtc;
596               Ecore_X_Randr_Mode            mode;
597               Ecore_X_Randr_Orientation     orientation;
598               int                           x;
599               int                           y;
600               int                           width;
601               int                           height;
602            };
603         */
604      }
605
606    return EINA_TRUE;
607 }
608
609 static int
610 _e_devicemgr_cb_output_change (void *data, int type, void *ev)
611 {
612    int sc_stat = 0;
613
614    if (type == ECORE_X_EVENT_RANDR_OUTPUT_CHANGE)
615      {
616        //SLOG(LOG_DEBUG, "DEVICEMGR", "[scrn-conf]: Output Change!: \n");
617        Ecore_X_Event_Randr_Output_Change *event = (Ecore_X_Event_Randr_Output_Change *)ev;
618        /* available information:
619           struct _Ecore_X_Event_Randr_Output_Change
620           {
621              Ecore_X_Window                  win;
622              Ecore_X_Randr_Output            output;
623              Ecore_X_Randr_Crtc              crtc;
624              Ecore_X_Randr_Mode              mode;
625              Ecore_X_Randr_Orientation       orientation;
626              Ecore_X_Randr_Connection_Status connection;
627              Ecore_X_Render_Subpixel_Order   subpixel_order;
628           };
629        */
630
631        SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: event (crtc:%d, output:%d, mode:%d)\n",
632                 event->crtc, event->output, event->mode);
633        SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: Output Connection!: %d (connected = %d, disconnected = %d, unknown %d)\n",
634                 event->connection, ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED, ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED, ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN);
635
636        /* check status of a output */
637        if (event->connection == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED &&
638            event->crtc == 0 &&
639            event->mode == 0)
640          {
641             /* if display mode is set by the client message, ignore output conncetion */
642             if (e_mod_set_disp_clone)
643               {
644                  /* reset flag to default */
645                  e_mod_set_disp_clone = EINA_FALSE;
646                  return EINA_TRUE;
647               }
648
649             sc_stat = e_mod_scrnconf_external_get_status();
650             if (sc_stat == UTILX_SCRNCONF_STATUS_CONNECT ||
651                 sc_stat == UTILX_SCRNCONF_STATUS_ACTIVE)
652              {
653                 SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : external monitor status is already connected \n");
654                 return 1;
655              }
656
657             /* if don't have xselection's ownership, ignore output disconnected */
658             if (e_devicemgr.selection_ownership)
659                SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] connected twice.\n");
660
661             char *prev_owner = _e_devicemgr_selection_get_owner ();
662
663             e_devicemgr.selection_output_xid = event->output;
664
665             SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] selection owner : '%s'.\n",
666                   (prev_owner)?prev_owner:"none");
667
668             if (!prev_owner)
669               _e_devicemgr_selection_set ();
670             else
671               {
672                  snprintf (e_devicemgr.selection_prev_owner, sizeof (e_devicemgr.selection_prev_owner),
673                            "%s", prev_owner);
674
675                  if (strcmp (prev_owner, XSELECTION_HDMI_NAME))
676                    {
677                       _e_devicemgr_selection_request ();
678                       free (prev_owner);
679                       return EINA_FALSE;
680                    }
681                  free (prev_owner);
682               }
683
684             _e_devicemgr_dialog_and_connect (event->output);
685          }
686        else if (event->connection == ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED)
687          {
688             _e_devicemgr_disconnect (event->output);
689          }
690        else if (event->connection == ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN)
691          {
692             /* if dialog is still showing, destroy dialog */
693             e_mod_scrnconf_external_dialog_free();
694
695             if (e_devicemgr.default_dispmode == UTILX_SCRNCONF_DISPMODE_EXTENDED)
696               {
697                  e_mod_scrnconf_container_bg_canvas_visible_set(EINA_TRUE);
698               }
699          }
700
701      }
702
703    return EINA_TRUE;
704 }
705
706 static int
707 _e_devicemgr_cb_output_property (void *data, int type, void *ev)
708 {
709    if (type == ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY)
710      {
711        //SLOG(LOG_DEBUG, "DEVICEMGR", "[scrn-conf]: Output Property Notify!: \n");
712        //Ecore_X_Event_Randr_Output_Property_Notify *event = (Ecore_X_Event_Randr_Output_Property_Notify *)ev;
713        /* available information:
714           struct _Ecore_X_Event_Randr_Output_Property_Notify
715           {
716           Ecore_X_Window                win;
717           Ecore_X_Randr_Output          output;
718           Ecore_X_Atom                  property;
719           Ecore_X_Time                  time;
720           Ecore_X_Randr_Property_Change state;
721           };
722        */
723      }
724
725    return EINA_TRUE;
726 }
727
728 static int
729 _e_devicemgr_cb_client_message (void* data, int type, void* event)
730 {
731    Ecore_X_Event_Client_Message* ev = event;
732    int req = 0;
733    int sc_dispmode = 0;
734    int sc_res = 0;
735    int sc_stat = 0;
736    int sc_output = 0;
737    int preferred_w = 0, preferred_h = 0;
738    int pos[2];
739    int cx, cy;
740    int x1, y1, x2, y2;
741    int w, h, px = 0, py = 0;
742    int vw, vh, pw = 0, ph = 0;
743    int region[5];
744    int pos_rootx, pos_rooty;
745
746    if (ev->message_type == e_devicemgr.atomVirtualTouchpadInt)
747      {
748         if (e_devicemgr.num_zones < 2)
749           {
750              ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt,
751                                                                      ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_SHUTDOWN, 0, 0, 0, 0);
752              return 1;
753           }
754
755         if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_NEED_TO_INIT)
756           {
757              ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt,
758                                                                      ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_DO_INIT, 0, 0, 0, 0);
759           }
760         else if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_AREA_INFO)
761           {
762              e_devicemgr.virtual_touchpad_area_info[0] = ev->data.l[1];
763              e_devicemgr.virtual_touchpad_area_info[1] = ev->data.l[2];
764              e_devicemgr.virtual_touchpad_area_info[2] = ev->data.l[3];
765              e_devicemgr.virtual_touchpad_area_info[3] = ev->data.l[4];
766              SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_client_message] virtual_touchpad_area_info=%d %d %d %d\n",
767                                 e_devicemgr.virtual_touchpad_area_info[0], e_devicemgr.virtual_touchpad_area_info[1],
768                                 e_devicemgr.virtual_touchpad_area_info[2], e_devicemgr.virtual_touchpad_area_info[3]);
769           }
770         else if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_WINDOW)
771           {
772              e_devicemgr.virtual_touchpad_window = (Ecore_X_Window)ev->data.l[1];
773              SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_client_message] virtual_touchpad_window=0x%x\n", e_devicemgr.virtual_touchpad_window);
774           }
775         else if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_CONFINE_SET)
776           {
777              _e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, _e_devicemgr_get_nth_zone(2), EINA_TRUE, NULL, EINA_FALSE, EINA_TRUE);
778              SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_client_message] E_VIRTUAL_TOUCHPAD_CONFINE_SET\n");
779           }
780         else if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_CONFINE_UNSET)
781           {
782              _e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, NULL, EINA_FALSE, NULL, EINA_FALSE, EINA_FALSE);
783              SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_client_message] E_VIRTUAL_TOUCHPAD_CONFINE_UNSET\n");
784           }
785         else if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_MT_BEGIN)
786           {
787              SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_client_message] E_VIRTUAL_TOUCHPAD_MT_BEGIN !virtual_multitouch_done=%d\n", e_devicemgr.virtual_multitouch_done);
788
789              if (0 != e_devicemgr.virtual_touchpad_pointed_window)
790                {
791                   XISetClientPointer(e_devicemgr.disp, e_devicemgr.virtual_touchpad_pointed_window, e_devicemgr.virtual_touchpad_id);
792                   XSync(e_devicemgr.disp, 0);
793                   ecore_x_pointer_xy_get(e_devicemgr.virtual_touchpad_pointed_window, &pos[0], &pos[1]);
794                   SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][_cb_client_message] cursor pos x=%d, y=%d\n", pos[0], pos[1]);
795
796                   if (pos[0] < 0 || pos[1] < 0 ) return 1;
797
798                   e_devicemgr.virtual_multitouch_done = 0;
799
800                   x1 = e_devicemgr.virtual_touchpad_pointed_window_info[0];
801                   y1 = e_devicemgr.virtual_touchpad_pointed_window_info[1];
802                   w = e_devicemgr.virtual_touchpad_pointed_window_info[2];
803                   h = e_devicemgr.virtual_touchpad_pointed_window_info[3];
804
805                   x2 = x1+w;
806                   y2 = y1+h;
807                   cx = x1 + pos[0];
808                   cy = y1 + pos[1];
809
810                   if (INSIDE(cx, cy, x1, y1, x1+(w/2), y1+(h/2)))
811                     {
812                        SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 1st box (x1=%d, y1=%d, x2=%d, y2=%d)!\n", x1, y1, x1+(w/2), y1+(h/2));
813                        pw = pos[0]*2;
814                        ph = pos[1]*2;
815                        px = x1;
816                        py = y1;
817                        SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 1st box (effective area = %d, %d, %d, %d)!\n", px, py, pw, ph);
818                     }
819                   else if (INSIDE(cx, cy, x1+(w/2), y1, x2, y1+(h/2)))
820                     {
821                        SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 2nd box (x1=%d, y1=%d, x2=%d, y2=%d)!\n", x1+(w/2), y1, x2, y1+(h/2));
822                        pw = (w-pos[0])*2;
823                        ph = pos[1]*2;
824                        px = x2-pw;
825                        py = y1;
826                        SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 2nd box (effective area = %d, %d, %d, %d)!\n", px, py, pw, ph);
827                     }
828                   else if (INSIDE(cx, cy, x1, y1+(h/2), x1+(w/2), y2))
829                     {
830                        SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 3rd box (x1=%d, y1=%d, x2=%d, y2=%d)!\n", x1, y1+(h/2), x1+(w/2), y2);
831                        pw = pos[0]*2;
832                        ph = (h-pos[1])*2;
833                        px = x1;
834                        py = y2-ph;
835                        SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 3rd box (effective area = %d, %d, %d, %d)!\n", px, py, pw, ph);
836                     }
837                   else if (INSIDE(cx, cy, x1+(w/2), y1+(h/2), x2, y2))
838                     {
839                        SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 4th box (x1=%d, y1=%d, x2=%d, y2=%d)!\n", x1+(w/2), y1+(h/2), x2, y2);
840                        pw = (w-pos[0])*2;
841                        ph = (h-pos[1])*2;
842                        px = x2-pw;
843                        py = y2-ph;
844                        SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 4th box (effective area = %d, %d, %d, %d)!\n", px, py, pw, ph);
845                     }
846                   else
847                     {
848                        SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] !!! pointer is not in 4 boxes !!!\n");
849                     }
850
851                   vw = e_devicemgr.virtual_touchpad_area_info[2] -e_devicemgr.virtual_touchpad_area_info[0];
852                   vh = e_devicemgr.virtual_touchpad_area_info[3] -e_devicemgr.virtual_touchpad_area_info[1];
853
854                   if ((pw) && (vw > pw)) e_devicemgr.tmatrix[0] = (float)vw/pw;
855                   else if (vw) e_devicemgr.tmatrix[0] = (float)pw/vw;
856                   if ((ph) && (vh > ph)) e_devicemgr.tmatrix[4] = (float)vh/ph;
857                   else if (vh) e_devicemgr.tmatrix[4] = (float)ph/vh;
858
859                   e_devicemgr.virtual_touchpad_cursor_pos[0] = pos[0];
860                   e_devicemgr.virtual_touchpad_cursor_pos[1] = pos[1];
861                   e_devicemgr.tmatrix[2] = (float)px*e_devicemgr.tmatrix[0]*(-1);
862                   e_devicemgr.tmatrix[5] = (float)py*e_devicemgr.tmatrix[4]*(-1);
863                   _e_devicemgr_update_input_transform_matrix(EINA_FALSE);
864
865                   region[0] = e_devicemgr.virtual_touchpad_pointed_window_info[0] + 10;
866                   region[1] = e_devicemgr.virtual_touchpad_pointed_window_info[1] + 10;
867                   region[2] = e_devicemgr.virtual_touchpad_pointed_window_info[2] - 20;
868                   region[3] = e_devicemgr.virtual_touchpad_pointed_window_info[3] - 20;
869                   region[4] = 0;
870                   _e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, NULL, EINA_TRUE, &region[0], EINA_FALSE, EINA_TRUE);
871                   ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt,
872                                                                           ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_MT_MATRIX_SET_DONE, 0, 0, 0, 0);
873                }
874           }
875         else if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_MT_END)
876           {
877              e_devicemgr.virtual_multitouch_done = 1;
878              SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_client_message] E_VIRTUAL_TOUCHPAD_MT_END !virtual_multitouch_done=%d\n", e_devicemgr.virtual_multitouch_done);
879              if (0 != e_devicemgr.virtual_touchpad_pointed_window)
880                {
881                   _e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, NULL, EINA_FALSE, NULL, EINA_FALSE, EINA_FALSE);
882                   //_e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, _e_devicemgr_get_nth_zone(2), EINA_TRUE, NULL, EINA_FALSE);
883                   if (e_devicemgr.virtual_touchpad_cursor_pos[0] >= 0 && e_devicemgr.virtual_touchpad_cursor_pos[1] >= 0)
884                     {
885                        pos_rootx = e_devicemgr.virtual_touchpad_cursor_pos[0] + e_devicemgr.virtual_touchpad_pointed_window_info[0];
886                        pos_rooty = e_devicemgr.virtual_touchpad_cursor_pos[1] + e_devicemgr.virtual_touchpad_pointed_window_info[1];
887                        ecore_x_pointer_warp(e_devicemgr.virtual_touchpad_pointed_window, e_devicemgr.virtual_touchpad_cursor_pos[0], e_devicemgr.virtual_touchpad_cursor_pos[1]);
888                        e_devicemgr.virtual_touchpad_cursor_pos[0] = -1;
889                        e_devicemgr.virtual_touchpad_cursor_pos[1] = -1;
890                   }
891                }
892           }
893
894         return 1;
895      }
896
897    if (ev->message_type == e_devicemgr.atomScrnConfDispModeSet)
898      {
899         sc_dispmode = (int)ev->data.s[0];
900
901         sc_stat = e_mod_scrnconf_external_get_status();
902         if (sc_stat == UTILX_SCRNCONF_STATUS_NULL)
903           {
904              SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : external monitor is not connected \n");
905              return 1;
906           }
907
908         if (sc_dispmode == e_mod_scrnconf_external_get_dispmode())
909           {
910              SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : the same dispmode is already set \n");
911              return 1;
912           }
913
914         sc_output = e_mod_scrnconf_external_get_output();
915         E_MOD_SCRNCONF_CHK_RET(sc_output != SC_EXT_OUTPUT_NULL, 1);
916
917         _get_preferred_size (sc_output, &preferred_w, &preferred_h);
918         sc_res = e_mod_scrnconf_external_get_default_res (sc_output, preferred_w, preferred_h);
919         E_MOD_SCRNCONF_CHK_RET(sc_res != SC_EXT_RES_NULL, 1);
920
921         if (!e_mod_scrnconf_external_set_dispmode (sc_output, sc_dispmode, sc_res))
922           {
923              SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to get external output \n");
924              return 1;
925           }
926
927         e_mod_scrnconf_external_set_status (UTILX_SCRNCONF_STATUS_ACTIVE);
928         e_mod_scrnconf_external_send_current_status();
929
930         /* if disp_mode is set by the client message, set clone flag for preventing
931            the output disconnect/connect */
932         if (sc_dispmode == UTILX_SCRNCONF_DISPMODE_CLONE)
933            e_mod_set_disp_clone = EINA_TRUE;
934      }
935    else if (ev->message_type == e_devicemgr.atomVirtMonReq)
936      {
937         req = (int)ev->data.s[0];
938         e_devicemgr.virtual_preferred_w = (int)ev->data.s[1];
939         e_devicemgr.virtual_preferred_h = (int)ev->data.s[2];
940
941         /* deal with edid data */
942         e_mod_drv_virt_mon_set (req);
943      }
944    else if (ev->message_type == e_devicemgr.atomHibReq)
945      {
946         req = (int)ev->data.s[0];
947      }
948    else if (ev->message_type == e_devicemgr.atomDevMgrCfg)
949      {
950         Eina_Bool set_popup = EINA_FALSE;
951         req = (int)ev->data.s[0];
952         if (req == DEVICEMGR_CFG_POPUP)
953           {
954              set_popup = (Eina_Bool)ev->data.s[1];
955              e_devicemgr.isPopUpEnabled = set_popup;
956              _e_devicemgr_cfg->ScrnConf.isPopUpEnabled = set_popup;
957           }
958         else if (req == DEVICEMGR_CFG_DEFAULT_DISPMODE)
959           {
960              sc_dispmode = (int)ev->data.s[1];
961              e_devicemgr.default_dispmode = sc_dispmode;
962              _e_devicemgr_cfg->ScrnConf.default_dispmode = sc_dispmode;
963           }
964         else
965           {
966              return 1;
967           }
968
969         /* update deivcemgr configuration */
970         _e_devicemgr_update_configuration();
971      }
972    else
973      {
974          ;
975      }
976
977    return 1;
978 }
979
980 static void
981 _e_mod_move_e_msg_handler(void *data, const char *name, const char *info, int val, E_Object   *obj, void *msgdata)
982 {
983    Eina_List* l;
984    DeviceMgr_Device_Info *ldata;
985    unsigned int ret_val = 1;
986
987    if (!strncmp(name, "e.move.quickpanel", sizeof("e.move.quickpanel")))
988      {
989         SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] e.move.quickpanel is comming (%s): val: %d\n", info, val);
990         if ((!strncmp(info, "start", sizeof("start"))))
991           {
992              // quickpanel state on
993              ret_val = 0;
994              ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomExKeyboardEnabled, &ret_val, 1);
995              EINA_LIST_FOREACH(e_devicemgr.device_list, l ,ldata)
996                {
997                   if(ldata->type == E_DEVICEMGR_KEYBOARD || ldata->type == E_DEVICEMGR_GAMEPAD)
998                     {
999                        if(_e_devicemgr_detach_slave(ldata->id) == EINA_FALSE)
1000                          {
1001                             SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to detach slave device(%d) \n", ldata->id);
1002                          }
1003                     }
1004                }
1005           }
1006         else if ((!strncmp(info, "end", sizeof("end"))) && (val == 0))
1007           {
1008              // quickpanel state off
1009              ret_val = 1;
1010              ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomExKeyboardEnabled, &ret_val, 1);
1011              EINA_LIST_FOREACH(e_devicemgr.device_list, l ,ldata)
1012                {
1013                   if(ldata->type == E_DEVICEMGR_KEYBOARD || ldata->type == E_DEVICEMGR_GAMEPAD)
1014                     {
1015                        if(_e_devicemgr_reattach_slave(ldata->id, ldata->master_id) == EINA_FALSE)
1016                          {
1017                             SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to reattach slave device(%d) to master device(%d) \n", ldata->id, e_devicemgr.vck_id);
1018                          }
1019                     }
1020                }
1021           }
1022      }
1023 }
1024
1025 static int
1026 _e_devicemgr_xinput_init(void)
1027 {
1028    int event, error;
1029    int major = 2, minor = 0;
1030
1031    if (!XQueryExtension(e_devicemgr.disp, "XInputExtension", &e_devicemgr.xi2_opcode, &event, &error))
1032      {
1033         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] XInput Extension isn't supported.\n", __FUNCTION__);
1034         goto fail;
1035      }
1036
1037    if (XIQueryVersion(e_devicemgr.disp, &major, &minor) == BadRequest)
1038      {
1039         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to query XI version.\n", __FUNCTION__);
1040         goto fail;
1041      }
1042
1043    memset(&e_devicemgr.eventmask, 0L, sizeof(XIEventMask));
1044    e_devicemgr.eventmask.deviceid = XIAllDevices;
1045    e_devicemgr.eventmask.mask_len = XIMaskLen(XI_RawMotion);
1046    e_devicemgr.eventmask.mask = calloc(e_devicemgr.eventmask.mask_len, sizeof(char));
1047
1048    /* Events we want to listen for all */
1049    XISetMask(e_devicemgr.eventmask.mask, XI_DeviceChanged);
1050    XISetMask(e_devicemgr.eventmask.mask, XI_HierarchyChanged);
1051    XISetMask(e_devicemgr.eventmask.mask, XI_PropertyEvent);
1052    XISelectEvents(e_devicemgr.disp, e_devicemgr.rootWin, &e_devicemgr.eventmask, 1);
1053
1054    return 1;
1055
1056 fail:
1057    e_devicemgr.xi2_opcode = -1;
1058    return 0;
1059 }
1060
1061 static int
1062 _e_devicemgr_xkb_init(void)
1063 {
1064    int xkb_opcode, xkb_event, xkb_error;
1065    int xkb_lmaj = XkbMajorVersion;
1066    int xkb_lmin = XkbMinorVersion;
1067
1068    if (!(XkbLibraryVersion(&xkb_lmaj, &xkb_lmin)
1069          && XkbQueryExtension(e_devicemgr.disp, &xkb_opcode, &xkb_event, &xkb_error, &xkb_lmaj, &xkb_lmin)))
1070      {
1071         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][xkb_init] Failed to initialize XKB extension !\n");
1072         e_devicemgr.xkb_available = EINA_FALSE;
1073         return 0;
1074      }
1075
1076    e_devicemgr.xkb_available = EINA_TRUE;
1077    return 1;
1078 }
1079
1080 static int
1081 _e_devicemgr_cb_window_property(void *data, int ev_type, void *ev)
1082 {
1083    int res;
1084    unsigned int ret_val = 0;
1085    Ecore_X_Event_Window_Property *e = ev;
1086
1087    int enable=1;
1088    int disable=0;
1089
1090    if (e->atom == e_devicemgr.atomDeviceList && e->win == e_devicemgr.input_window)
1091      {
1092         res = ecore_x_window_prop_card32_get(e->win, e_devicemgr.atomDeviceList, &ret_val, 1);
1093
1094         if (res == 1) _e_devicemgr_show_device_list(ret_val);
1095         goto out;
1096      }
1097
1098    if (e->atom == e_devicemgr.atomVirtualTouchpad && e->win == e_devicemgr.input_window)
1099      {
1100         res = ecore_x_window_prop_card32_get(e->win, e_devicemgr.atomVirtualTouchpad, &ret_val, 1);
1101
1102         if (res == 1 && e_devicemgr.virtual_touchpad_id > 0)
1103           {
1104              ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt,
1105                                                                      ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_SHUTDOWN, 0, 0, 0, 0);
1106           }
1107         goto out;
1108      }
1109    if (e->atom == e_devicemgr.atomGameModeEnabled && e->win == e_devicemgr.input_window)
1110      {
1111         res = ecore_x_window_prop_card32_get(e->win, e_devicemgr.atomGameModeEnabled, &ret_val, 1);
1112
1113         if (res == 1)
1114           {
1115              /* "Game Mode Enable" means that gamepad input shall uniquely go to gamepad-using game app WITHOUT X server,
1116                 therefore DISABLING the gamepad (for X server),
1117                 and vice versa -- "Game Mode Disable" means "gamepad ENABLE".*/
1118              if (ret_val == 1)
1119                {
1120                   XIChangeProperty(e_devicemgr.disp, e_devicemgr.gamepad_id, e_devicemgr.atomDeviceEnabled,
1121                                    XA_INTEGER, 8, PropModeReplace, &disable, 1);
1122                }
1123              else
1124                {
1125                   XIChangeProperty(e_devicemgr.disp, e_devicemgr.gamepad_id, e_devicemgr.atomDeviceEnabled,
1126                                    XA_INTEGER, 8, PropModeReplace, &enable, 1);
1127                }
1128           }
1129         goto out;
1130      }
1131    if (e->atom == e_devicemgr.atomPalmDisablingWinRunning && e->win == e_devicemgr.input_window)
1132      {
1133
1134         Ecore_X_Window highlight_win;
1135         res = ecore_x_window_prop_card32_get(e->win, e_devicemgr.atomPalmDisablingWinRunning, &ret_val, 1);
1136         if (res <=0)
1137            goto out;
1138
1139         SLOG(LOG_DEBUG, "DEVICEMGR", "E_PROP_PALM_DISABLING_WIN_RUNNING (0x%x -> 0x%x)\n", e_devicemgr.palmDisablingWin, ret_val);
1140
1141         e_devicemgr.palmDisablingWin = ret_val;
1142
1143         res = ecore_x_window_prop_window_get(e_devicemgr.rootWin, ECORE_X_ATOM_NET_ACTIVE_WINDOW, &highlight_win, 1);
1144         if (res <=0)
1145            goto out;
1146
1147         SLOG(LOG_DEBUG, "DEVICEMGR", "highlight_win: 0x%x)\n", highlight_win);
1148
1149         if (e_devicemgr.palmDisablingWin == highlight_win)
1150           {
1151              e_devicemgr.palm_disabled = EINA_TRUE;
1152              XIChangeProperty(e_devicemgr.disp, e_devicemgr.gesture_id, e_devicemgr.atomPalmRejectionMode,
1153                                    XA_INTEGER, 8, PropModeReplace, &enable, 1);
1154           }
1155         else
1156           {
1157               e_devicemgr.palm_disabled = EINA_FALSE;
1158               XIChangeProperty(e_devicemgr.disp, e_devicemgr.gesture_id, e_devicemgr.atomPalmRejectionMode,
1159                                 XA_INTEGER, 8, PropModeReplace, &disable, 1);
1160           }
1161         goto out;
1162      }
1163    if (e->atom == ECORE_X_ATOM_NET_ACTIVE_WINDOW && e->win == e_devicemgr.rootWin)
1164      {
1165         SLOG(LOG_DEBUG, "DEVICEMGR", "active window is changed. Try to Change gesture property. id: %d, atom: %d, enable: %d\n",
1166                  e_devicemgr.gesture_id, e_devicemgr.atomWindowStackisChanged, enable);
1167         XIChangeProperty(e_devicemgr.disp, e_devicemgr.gesture_id, e_devicemgr.atomWindowStackisChanged,
1168                            XA_INTEGER, 8, PropModeReplace, &enable, 1);
1169
1170         if(e_devicemgr.palmDisablingWin == -1)
1171            goto out;
1172
1173         Ecore_X_Window highlight_win;
1174
1175         res = ecore_x_window_prop_window_get(e_devicemgr.rootWin, ECORE_X_ATOM_NET_ACTIVE_WINDOW, &highlight_win, 1);
1176         if (res <=0)
1177            goto out;
1178
1179         if (e_devicemgr.palm_disabled == EINA_FALSE && e_devicemgr.palmDisablingWin == highlight_win)
1180           {
1181              e_devicemgr.palm_disabled = EINA_TRUE;
1182              XIChangeProperty(e_devicemgr.disp, e_devicemgr.gesture_id, e_devicemgr.atomPalmRejectionMode,
1183                                 XA_INTEGER, 8, PropModeReplace, &enable, 1);
1184           }
1185         else if (e_devicemgr.palm_disabled == EINA_TRUE)
1186           {
1187              e_devicemgr.palm_disabled = EINA_FALSE;
1188              XIChangeProperty(e_devicemgr.disp, e_devicemgr.gesture_id, e_devicemgr.atomPalmRejectionMode,
1189                                 XA_INTEGER, 8, PropModeReplace, &disable, 1);
1190           }
1191         goto out;
1192      }
1193 out:
1194    return 1;
1195 }
1196
1197 static int _e_devicemgr_cb_window_destroy(void *data, int ev_type, void *ev)
1198 {
1199    Ecore_X_Event_Window_Destroy *e = ev;
1200    int disable = 0;
1201    int no_window = -1;
1202
1203    if (e_devicemgr.palmDisablingWin != -1 && e->win == e_devicemgr.palmDisablingWin)
1204      {
1205         XIChangeProperty(e_devicemgr.disp, e_devicemgr.gesture_id, e_devicemgr.atomPalmRejectionMode,
1206            XA_INTEGER, 8, PropModeReplace, &disable, 1);
1207         ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomPalmDisablingWinRunning, &no_window, 1);
1208         e_devicemgr.palmDisablingWin = -1;
1209         e_devicemgr.palm_disabled = EINA_FALSE;
1210      }
1211    return 1;
1212 }
1213
1214 static int
1215 _e_devicemgr_cb_event_generic(void *data, int ev_type, void *event)
1216 {
1217    Ecore_X_Event_Generic *e = (Ecore_X_Event_Generic *)event;
1218    XIDeviceEvent *evData = (XIDeviceEvent *)(e->data);
1219
1220    if (e->extension != e_devicemgr.xi2_opcode)
1221      {
1222         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Invalid event !(extension:%d, evtype:%d)\n", __FUNCTION__, e->extension, e->evtype);
1223         return 1;
1224      }
1225
1226    if (!evData || evData->send_event)
1227    {
1228       SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Generic event data is not available or the event was sent via XSendEvent (and will be ignored) !\n", __FUNCTION__);
1229       return 1;
1230    }
1231    switch (e->evtype)
1232    {
1233       case XI_HierarchyChanged:
1234          _e_devicemgr_xi2_device_hierarchy_handler((XIHierarchyEvent *)evData);
1235          break;
1236
1237       case XI_DeviceChanged:
1238          _e_devicemgr_xi2_device_changed_handler((XIDeviceChangedEvent *)evData);
1239          break;
1240
1241       case XI_PropertyEvent:
1242          _e_devicemgr_xi2_device_property_handler((XIPropertyEvent *)evData);
1243          break;
1244    }
1245
1246    return 1;
1247 }
1248
1249 static int
1250 _e_devicemgr_cb_zone_add(void *data, int ev_type, void *event)
1251 {
1252    E_Event_Zone_Add *ev;
1253    E_Zone *zone;
1254    Eina_List *l;
1255
1256    ev = event;
1257    zone = ev->zone;
1258    if (!zone || !zone->name) return 1;
1259
1260    l = eina_list_data_find_list(e_devicemgr.zones, zone);
1261    if (l)
1262      {
1263         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_add] zone exists already in zone list !\n");
1264         return 1;
1265      }
1266
1267    SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_add] z->name=%s, z->w=%d, z->h=%d, z->x=%d, z->y=%d\n",
1268        zone->name, zone->w, zone->h, zone->x, zone->y);
1269    SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_add] z->useful_geometry.w=%d, z->useful_geometry.h=%d, z->useful_geometry.x=%d, z->useful_geometry.y=%d\n",
1270        zone->useful_geometry.w, zone->useful_geometry.h, zone->useful_geometry.x, zone->useful_geometry.y);
1271
1272    e_devicemgr.zones = eina_list_append(e_devicemgr.zones, zone);
1273    e_devicemgr.num_zones++;
1274
1275    SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_add] num_zones=%d\n", e_devicemgr.num_zones);
1276
1277    return 1;
1278 }
1279
1280 static int
1281 _e_devicemgr_cb_zone_del(void *data, int ev_type, void *event)
1282 {
1283    E_Event_Zone_Del *ev;
1284    E_Zone *zone;
1285    Eina_List *l;
1286
1287    ev = event;
1288    zone = ev->zone;
1289    if (!zone || !zone->name) return 1;
1290
1291    SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_del] z->name=%s, z->w=%d, z->h=%d, z->x=%d, z->y=%d\n",
1292        zone->name, zone->w, zone->h, zone->x, zone->y);
1293    SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_del] z->useful_geometry.w=%d, z->useful_geometry.h=%d, z->useful_geometry.x=%d, z->useful_geometry.y=%d\n",
1294        zone->useful_geometry.w, zone->useful_geometry.h, zone->useful_geometry.x, zone->useful_geometry.y);
1295
1296    if (e_devicemgr.num_zones < 2)//basic zone + additional zone(s)
1297      {
1298         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_del] Zone list needs to be checked into !\n");
1299         return 1;
1300      }
1301
1302    l = eina_list_data_find_list(e_devicemgr.zones, zone);
1303    if (!l)
1304      {
1305         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_del] zone doesn't exist in zone list !\n");
1306         return 1;
1307      }
1308
1309    if (e_devicemgr.num_zones == 2 && e_devicemgr.virtual_touchpad_id > 0)
1310      {
1311         ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt,
1312                                                                 ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_SHUTDOWN, 0, 0, 0, 0);
1313      }
1314
1315    e_devicemgr.zones = eina_list_remove(e_devicemgr.zones, zone);
1316    e_devicemgr.num_zones--;
1317
1318    SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_del] num_zones=%d\n", e_devicemgr.num_zones);
1319
1320    return 1;
1321 }
1322
1323 static void
1324 _e_devicemgr_hook_border_resize_end(void *data, void *border)
1325 {
1326    E_Border *bd = (E_Border *)border;
1327    if (!bd) return;
1328
1329    e_devicemgr.virtual_touchpad_pointed_window_info[0] = bd->x + bd->client_inset.l;
1330    e_devicemgr.virtual_touchpad_pointed_window_info[1] = bd->y + bd->client_inset.t;
1331    e_devicemgr.virtual_touchpad_pointed_window_info[2] = bd->client.w;
1332    e_devicemgr.virtual_touchpad_pointed_window_info[3] = bd->client.h;
1333
1334    SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][hook_border_resize_end] application win=0x%x, px=%d, py=%d, pw=%d, ph=%d\n", bd->client.win,
1335               e_devicemgr.virtual_touchpad_pointed_window_info[0], e_devicemgr.virtual_touchpad_pointed_window_info[1],
1336               e_devicemgr.virtual_touchpad_pointed_window_info[2], e_devicemgr.virtual_touchpad_pointed_window_info[3]);
1337 }
1338
1339 static void
1340 _e_devicemgr_hook_border_move_end(void *data, void *border)
1341 {
1342    E_Border *bd = (E_Border *)border;
1343    if (!bd) return;
1344
1345    e_devicemgr.virtual_touchpad_pointed_window_info[0] = bd->x + bd->client_inset.l;
1346    e_devicemgr.virtual_touchpad_pointed_window_info[1] = bd->y + bd->client_inset.t;
1347    e_devicemgr.virtual_touchpad_pointed_window_info[2] = bd->client.w;
1348    e_devicemgr.virtual_touchpad_pointed_window_info[3] = bd->client.h;
1349
1350    SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][hook_border_move_end] application win=0x%x, px=%d, py=%d, pw=%d, ph=%d\n", bd->client.win,
1351               e_devicemgr.virtual_touchpad_pointed_window_info[0], e_devicemgr.virtual_touchpad_pointed_window_info[1],
1352               e_devicemgr.virtual_touchpad_pointed_window_info[2], e_devicemgr.virtual_touchpad_pointed_window_info[3]);
1353 }
1354
1355 static Eina_Bool
1356 _e_devicemgr_cb_mouse_in(void *data, int type, void *event)
1357 {
1358    int px, py;
1359    int pw, ph;
1360    int vw, vh;
1361    E_Border *bd;
1362    unsigned int val = 0;
1363    Ecore_X_Event_Mouse_In *ev = event;
1364
1365    if (!e_devicemgr.virtual_multitouch_done) return ECORE_CALLBACK_PASS_ON;
1366
1367    bd = e_border_find_by_window(ev->event_win);
1368    if (!bd)
1369      {
1370         if (e_devicemgr.rootWin == ecore_x_window_parent_get(ev->event_win))
1371           {
1372
1373              if (!e_devicemgr.virtual_multitouch_done && e_devicemgr.virtual_touchpad_pointed_window != 0)
1374                return ECORE_CALLBACK_PASS_ON;
1375
1376              e_devicemgr.virtual_touchpad_pointed_window = 0;
1377              ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt,
1378                                                                      ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_POINTED_WINDOW, 0, 0, 0, 0);
1379              _e_devicemgr_update_input_transform_matrix(EINA_TRUE/* reset */);
1380              return ECORE_CALLBACK_PASS_ON;
1381           }
1382
1383         return ECORE_CALLBACK_PASS_ON;
1384      }
1385
1386    if (bd->zone->id == 0)
1387      {
1388         return ECORE_CALLBACK_PASS_ON;
1389      }
1390
1391    e_devicemgr.virtual_touchpad_pointed_window_info[0] = bd->x + bd->client_inset.l;
1392    e_devicemgr.virtual_touchpad_pointed_window_info[1] = bd->y + bd->client_inset.t;
1393    e_devicemgr.virtual_touchpad_pointed_window_info[2] = bd->client.w;
1394    e_devicemgr.virtual_touchpad_pointed_window_info[3] = bd->client.h;
1395    e_devicemgr.virtual_touchpad_pointed_window = bd->client.win;
1396
1397    SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_mouse_in] application win=0x%x, px=%d, py=%d, pw=%d, ph=%d\n", bd->client.win,
1398               e_devicemgr.virtual_touchpad_pointed_window_info[0], e_devicemgr.virtual_touchpad_pointed_window_info[1],
1399               e_devicemgr.virtual_touchpad_pointed_window_info[2], e_devicemgr.virtual_touchpad_pointed_window_info[3]);
1400    ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt,
1401                                                            ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_POINTED_WINDOW,
1402                                                            e_devicemgr.virtual_touchpad_pointed_window, 0, 0, 0);
1403
1404    return ECORE_CALLBACK_PASS_ON;
1405 }
1406
1407 static Eina_Bool
1408 _e_devicemgr_get_zones(void)
1409 {
1410    Eina_List *ml;
1411    E_Manager *man;
1412
1413    if (e_devicemgr.zones)
1414       return EINA_FALSE;
1415
1416    EINA_LIST_FOREACH(e_manager_list(), ml, man)
1417      {
1418         if (man)
1419           {
1420              Eina_List *cl;
1421              E_Container *con;
1422
1423              EINA_LIST_FOREACH(man->containers, cl, con)
1424                {
1425                   if (con)
1426                     {
1427                        Eina_List *zl;
1428                        E_Zone *z;
1429
1430                        EINA_LIST_FOREACH(con->zones, zl, z)
1431                          {
1432                             if (z)
1433                               {
1434                                  SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][_e_devicemgr_get_zones] z->name=%s, z->w=%d, z->h=%d, z->x=%d, z->y=%d\n",
1435                                           z->name, z->w, z->h, z->x, z->y);
1436                                  SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][_e_devicemgr_get_zones] z->useful_geometry.w=%d, z->useful_geometry.h=%d, z->useful_geometry.x=%d, z->useful_geometry.y=%d\n",
1437                                           z->useful_geometry.w, z->useful_geometry.h, z->useful_geometry.x, z->useful_geometry.y);
1438                                  e_devicemgr.zones = eina_list_append(e_devicemgr.zones, z);
1439                                  e_devicemgr.num_zones++;
1440                               }
1441                          }
1442                     }
1443                }
1444           }
1445      }
1446
1447    return (e_devicemgr.zones) ? EINA_TRUE : EINA_FALSE;
1448 }
1449
1450 static int
1451 _e_devicemgr_marshalize_string (char* buf, int num, char* srcs[])
1452 {
1453    int i;
1454    char * p = buf;
1455
1456    for (i=0; i<num; i++)
1457      {
1458         p += sprintf (p, srcs[i]);
1459         *p = '\0';
1460         p++;
1461      }
1462
1463    *p = '\0';
1464    p++;
1465
1466    return (p - buf);
1467 }
1468
1469 static void
1470 _e_devicemgr_init_output(void)
1471 {
1472    int i;
1473    XRROutputInfo *output_info = NULL;
1474
1475
1476    XRRScreenResources* res = XRRGetScreenResources (e_devicemgr.disp, e_devicemgr.rootWin);
1477    e_devicemgr.output = 0;
1478
1479    if (res && (res->noutput != 0))
1480      {
1481         for ( i = 0 ; i  <res->noutput ; i++ )
1482           {
1483              output_info = XRRGetOutputInfo(e_devicemgr.disp, res, res->outputs[i]);
1484              if (output_info && output_info->name && !strncmp(output_info->name, "LVDS1", 5))
1485                {
1486                   e_devicemgr.output = res->outputs[i];
1487                   SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][_e_devicemgr_init_output] LVDS1 was found !\n");
1488                   XRRFreeOutputInfo(output_info);
1489                   break;
1490                }
1491              else
1492                {
1493                   e_devicemgr.output = res->outputs[i];
1494                   SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][_e_devicemgr_init_output] LVDS1 was not found yet !\n");
1495                }
1496
1497              if (output_info) XRRFreeOutputInfo(output_info);
1498           }
1499      }
1500
1501    if (!e_devicemgr.output)
1502      {
1503         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][_e_devicemgr_init_output] Failed to init output !\n");
1504      }
1505
1506    if (res)
1507         XRRFreeScreenResources(res);
1508 }
1509
1510 static void
1511 _e_devicemgr_init_transform_matrix(void)
1512 {
1513    memset(e_devicemgr.tmatrix, 0, sizeof(e_devicemgr.tmatrix));
1514
1515    e_devicemgr.tmatrix[8] = 1.0f;
1516    e_devicemgr.tmatrix[0] = 1.0f;
1517    e_devicemgr.tmatrix[4] = 1.0f;
1518 }
1519
1520 static void
1521 _e_devicemgr_init_input(void)
1522 {
1523    int i;
1524    int ndevices;
1525    XIDeviceInfo *dev, *info = NULL;
1526    DeviceMgr_Device_Info *data = NULL;
1527
1528    if (e_devicemgr.xi2_opcode < 0)
1529      {
1530         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to initialize input !\n", __FUNCTION__);
1531         return;
1532      }
1533
1534    info = XIQueryDevice(e_devicemgr.disp, XIAllDevices, &ndevices);
1535
1536    if (!info)
1537      {
1538         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] There is no queried XI device.\n", __FUNCTION__);
1539         return;
1540      }
1541
1542    for (i = 0; i < ndevices ; i++)
1543      {
1544         dev = &info[i];
1545
1546         switch (dev->use)
1547           {
1548              case XISlavePointer:
1549                 if (strcasestr(dev->name, "Virtual core XTEST pointer"))
1550                   {
1551                      e_devicemgr.vcp_xtest_pointer_id = dev->deviceid;
1552                      continue;
1553                   }
1554                 if (strcasestr(dev->name, "XTEST")
1555 #ifdef _F_SUPPORT_XTEST_TOUCH_EVENT_
1556                     && strncmp(dev->name, TOUCH_DEVICE_NAME, LEN_TOUCH_DEVICE_NAME)
1557 #endif //_F_SUPPORT_XTEST_TOUCH_EVENT_
1558                 ) continue;
1559                 if (strcasestr(dev->name, "keyboard")) goto handle_keyboard;
1560                 if (1==_e_devicemgr_check_device_type(dev->deviceid, E_DEVICEMGR_GAMEPAD, dev->name)) goto handle_keyboard;
1561
1562                 data = malloc(sizeof(DeviceMgr_Device_Info));
1563
1564                 if (!data)
1565                   {
1566                      SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__);
1567                      goto out;
1568                   }
1569
1570                 data->id = dev->deviceid;
1571                 data->name = eina_stringshare_add(dev->name);
1572                 data->use = dev->use;
1573                 data->master_id = dev->attachment;
1574                 if (1==_e_devicemgr_check_device_type(dev->deviceid, E_DEVICEMGR_TOUCHSCREEN, dev->name))
1575                   {
1576                      //Now we have a touchscreen device.
1577                      data->type = E_DEVICEMGR_TOUCHSCREEN;
1578                      e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
1579                      e_devicemgr.num_touchscreen_devices++;
1580                      SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Slave touchscreen device (id=%d, name=%s, num_touchscreen_devices=%d) was added/enabled !\n",
1581                                  __FUNCTION__, dev->deviceid, dev->name, e_devicemgr.num_touchscreen_devices);
1582                   }
1583                 else
1584                   {
1585                      //Now we have a mouse.
1586                      data->type = E_DEVICEMGR_MOUSE;
1587                      e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
1588                      e_devicemgr.num_pointer_devices++;
1589
1590                      SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Slave pointer device (id=%d, name=%s, num_pointer_devices=%d) was added/enabled !\n",
1591                                  __FUNCTION__, dev->deviceid, dev->name, e_devicemgr.num_pointer_devices);
1592                   }
1593                 break;
1594
1595              case XISlaveKeyboard:
1596                 if (strcasestr(dev->name, "Virtual core XTEST keyboard"))
1597                   {
1598                      e_devicemgr.vck_xtest_keyboard_id = dev->deviceid;
1599                      continue;
1600                   }
1601
1602                 if (strcasestr(dev->name, "XTEST")
1603 #ifdef _F_SUPPORT_XTEST_TOUCH_EVENT_
1604                 && strncmp(dev->name, FUNCTION_KEY_DEVICE_NAME, LEN_FUNCTION_KEY_DEVICE_NAME)
1605 #endif //_F_SUPPORT_XTEST_TOUCH_EVENT_
1606                 ) continue;
1607
1608                 if (strcasestr(dev->name, "Gesture"))//gesture
1609                   {
1610                      //Now we have a gesture device.
1611                      data = malloc(sizeof(DeviceMgr_Device_Info));
1612                      if (!data)
1613                      {
1614                         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__);
1615                         goto out;
1616                      }
1617                      data->id = dev->deviceid;
1618                      data->name = eina_stringshare_add(dev->name);
1619                      data->master_id = dev->attachment;
1620
1621                      e_devicemgr.gesture_id = data->id;
1622                      e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
1623
1624                      _e_devicemgr_detach_slave(e_devicemgr.gesture_id);
1625
1626                      break;
1627                   }
1628 handle_keyboard:
1629                 data = malloc(sizeof(DeviceMgr_Device_Info));
1630
1631                 if (!data)
1632                   {
1633                      SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__);
1634                      goto out;
1635                   }
1636
1637                 data->use = dev->use;
1638
1639                 if (strcasestr(dev->name, "keyboard") && !strcasestr(dev->name, "XTEST" ))//keyboard
1640                   {
1641                      //Now we have a keyboard device
1642                      data->id = dev->deviceid;
1643                      data->name = eina_stringshare_add(dev->name);
1644                      data->type = E_DEVICEMGR_KEYBOARD;
1645                      data->master_id = dev->attachment;
1646
1647                      e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
1648                      e_devicemgr.num_keyboard_devices++;
1649                      _e_devicemgr_lockmodifier_set();
1650
1651                      if (e_devicemgr.num_keyboard_devices >= 1)
1652                        {
1653                           _e_devicemgr_set_keyboard_exist((unsigned int)e_devicemgr.num_keyboard_devices, 1);
1654                        }
1655
1656                      SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Slave keyboard device (id=%d, name=%s, num_keyboard_devices=%d) was added/enabled !\n",
1657                                  __FUNCTION__, dev->deviceid, dev->name, e_devicemgr.num_keyboard_devices);
1658                   }
1659                 else if (1==_e_devicemgr_check_device_type(dev->deviceid, E_DEVICEMGR_GAMEPAD, info->name))
1660                   {
1661                      //Now we have a game pad device.
1662                      data->id = dev->deviceid;
1663                      data->name = eina_stringshare_add(dev->name);
1664                      data->type = E_DEVICEMGR_GAMEPAD;
1665                      data->master_id = dev->attachment;
1666
1667                      e_devicemgr.gamepad_id = data->id;
1668
1669                      e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
1670
1671                      SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] game pad device (id=%d, name=%s) was added/enabled !\n",
1672                                  __FUNCTION__, dev->deviceid, dev->name);
1673                   }
1674                 else//HW key
1675                   {
1676                      data->type = E_DEVICEMGR_HWKEY;
1677                      data->id = dev->deviceid;
1678                      data->name = eina_stringshare_add(dev->name);
1679                      data->master_id = dev->attachment;
1680
1681                      e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
1682                      e_devicemgr.num_hwkey_devices++;
1683                   }
1684                 break;
1685
1686              case XIFloatingSlave:
1687                 if (strcasestr(dev->name, "Gesture"))//gesture
1688                   {
1689                      //Now we have a gesture device.
1690                      data = malloc(sizeof(DeviceMgr_Device_Info));
1691                      if (!data)
1692                      {
1693                         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__);
1694                         goto out;
1695                      }
1696                      data->id = dev->deviceid;
1697                      data->name = eina_stringshare_add(dev->name);
1698                      data->master_id = dev->attachment;
1699
1700                      e_devicemgr.gesture_id = data->id;
1701                      e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
1702
1703                      break;
1704                   }
1705                 if (1!=_e_devicemgr_check_device_type(dev->deviceid, E_DEVICEMGR_TOUCHSCREEN, dev->name)) continue;
1706
1707                 //Now we have a touchscreen device.
1708                 data = malloc(sizeof(DeviceMgr_Device_Info));
1709
1710                 if (!data)
1711                   {
1712                      SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__);
1713                      goto out;
1714                   }
1715
1716                 data->id = dev->deviceid;
1717                 data->name = eina_stringshare_add(dev->name);
1718                 data->use = dev->use;
1719                 data->type = E_DEVICEMGR_TOUCHSCREEN;
1720                 data->master_id = dev->attachment;
1721                 e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
1722                 e_devicemgr.num_touchscreen_devices++;
1723                 SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] FloatingSlave touchscreen device (id=%d, name=%s, num_touchscreen_devices=%d) was added/enabled !\n",
1724                    __FUNCTION__, dev->deviceid, dev->name, e_devicemgr.num_touchscreen_devices);
1725                 _e_devicemgr_append_prop_touchscreen_device_id(dev->deviceid);
1726                 break;
1727
1728              case XIMasterPointer:
1729                 SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] XIMasterPointer (VCP) (id=%d, name=%s)\n", __FUNCTION__, dev->deviceid, dev->name);
1730                 e_devicemgr.vcp_id = dev->deviceid;
1731                 break;
1732
1733              case XIMasterKeyboard:
1734                 SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] XIMasterKeyboard (VCK) (id=%d, name=%s)\n", __FUNCTION__, dev->deviceid, dev->name);
1735                 e_devicemgr.vck_id = dev->deviceid;
1736                 break;
1737           }
1738      }
1739
1740 out:
1741    XIFreeDeviceInfo(info);
1742 }
1743
1744 static void
1745 _e_devicemgr_xi2_device_property_handler(XIPropertyEvent *event)
1746 {
1747    if ((event->property == e_devicemgr.atomRelativeMoveStatus))
1748      {
1749         if( (event->what) && !(e_devicemgr.cursor_show_ack) )
1750           {
1751              e_devicemgr.cursor_show = 1;
1752              e_devicemgr.rel_move_deviceid = event->deviceid;
1753              _e_devicemgr_enable_mouse_cursor(e_devicemgr.cursor_show);
1754
1755              SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr] Relative Move Status !(e_devicemgr.cursor_show=%d)\n", e_devicemgr.cursor_show);
1756
1757              e_devicemgr.cursor_show_ack = 1;
1758              XIChangeProperty(e_devicemgr.disp, event->deviceid, e_devicemgr.atomRelativeMoveAck, XA_INTEGER, 8,
1759                               PropModeReplace, &e_devicemgr.cursor_show_ack, 1);
1760           }
1761         else if( !(event->what) )
1762           {
1763              e_devicemgr.cursor_show = 0;
1764              e_devicemgr.cursor_show_ack = 0;
1765              e_devicemgr.rel_move_deviceid = event->deviceid;
1766              _e_devicemgr_enable_mouse_cursor(e_devicemgr.cursor_show);
1767
1768              SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr] Relative Move Status !(e_devicemgr.cursor_show=%d)\n", e_devicemgr.cursor_show);
1769           }
1770      }
1771 }
1772
1773 static void
1774 _e_devicemgr_xi2_device_changed_handler(XIDeviceChangedEvent *event)
1775 {
1776    if (event->reason == XISlaveSwitch)
1777      {
1778         _e_devicemgr_slave_switched(event->deviceid, event->sourceid);
1779      }
1780    else if (event->reason == XIDeviceChange)
1781      {
1782         _e_devicemgr_device_changed(event->deviceid, event->sourceid);
1783      }
1784 }
1785
1786 static void
1787 _e_devicemgr_xi2_device_hierarchy_handler(XIHierarchyEvent *event)
1788 {
1789    int i;
1790
1791    if (event->flags & XIMasterAdded || event->flags & XIMasterRemoved)
1792      {
1793         for( i = 0 ; i < event->num_info ; i++ )
1794           {
1795              if (event->info[i].flags & XIMasterAdded)
1796                {
1797                   _e_devicemgr_master_pointer_added(event->info[i].deviceid);
1798                }
1799              else if (event->info[i].flags & XIMasterRemoved)
1800                {
1801                   _e_devicemgr_master_pointer_removed(event->info[i].deviceid);
1802                }
1803           }
1804      }
1805
1806    if (event->flags & XISlaveAdded || event->flags & XISlaveRemoved)
1807      {
1808         for( i = 0 ; i < event->num_info ; i++ )
1809           {
1810              if (event->info[i].flags & XISlaveAdded)
1811                {
1812                   if (1==_e_devicemgr_check_device_type(event->info[i].deviceid, E_DEVICEMGR_GAMEPAD, "Gamepad"))
1813                     {
1814                         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Slave gamepad device is added!\n", __FUNCTION__);
1815                         e_devicemgr.gamepad_id = event->info[i].deviceid;
1816                         break;
1817                     }
1818                }
1819              else if (event->info[i].flags & XISlaveRemoved)
1820                {
1821                   if (event->info[i].deviceid == e_devicemgr.gamepad_id)
1822                     {
1823                         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Slave gamepad device is removed!\n", __FUNCTION__);
1824                         e_devicemgr.gamepad_id = -1;
1825                         break;
1826                     }
1827                }
1828           }
1829      }
1830
1831    if (event->flags & XIDeviceEnabled || event->flags & XIDeviceDisabled)
1832      {
1833         for( i = 0 ; i < event->num_info ; i++ )
1834           {
1835              if (event->info[i].flags & XIDeviceEnabled)
1836                {
1837                   _e_devicemgr_device_enabled(event->info[i].deviceid, event->info[i].use);
1838                }
1839              else if (event->info[i].flags & XIDeviceDisabled)
1840                {
1841                   _e_devicemgr_device_disabled(event->info[i].deviceid, event->info[i].use);
1842                }
1843           }
1844      }
1845 }
1846
1847 static int
1848 _e_devicemgr_check_device_type(int deviceid, DeviceMgrDeviceType type, const char* devname)
1849 {
1850    char *tmp = NULL;
1851    Atom act_type;
1852    unsigned long nitems, bytes_after;
1853    unsigned char *data = NULL, *ptr;
1854    int j, act_format, ret = 0;
1855
1856    if (type != E_DEVICEMGR_TOUCHSCREEN && type != E_DEVICEMGR_MOUSE && type != E_DEVICEMGR_GAMEPAD) return 0;
1857
1858    if (XIGetProperty(e_devicemgr.disp, deviceid, e_devicemgr.atomAxisLabels, 0, 1000, False,
1859                               XA_ATOM, &act_type, &act_format,
1860                               &nitems, &bytes_after, &data) != Success)
1861      {
1862         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][check_device_type] Failed to get XI2 Axis device property !(deviceid=%d)\n", deviceid);
1863         goto out;
1864      }
1865
1866    if (!nitems || !data) goto out;
1867
1868    ptr = data;
1869
1870    for (j = 0; j < nitems; j++)
1871      {
1872         switch(act_type)
1873           {
1874              case XA_ATOM:
1875                {
1876                   Ecore_X_Atom atomTemp = *(Ecore_X_Atom*)ptr;
1877                   if (!atomTemp) goto out;
1878
1879                   tmp = ecore_x_atom_name_get(atomTemp);
1880                   if (!tmp) break;
1881
1882                   if ((type == E_DEVICEMGR_TOUCHSCREEN) && (strcasestr(tmp, "Abs X") || strcasestr(tmp, "Abs MT Position X")) && !strcasestr(devname, "maru"))
1883                     {
1884                        ret = 1;
1885                        goto out;
1886                     }
1887                   else if (type == E_DEVICEMGR_MOUSE && strcasestr(tmp, "Rel X"))
1888                     {
1889                        ret = 1;
1890                        goto out;
1891                     }
1892                   else if (type == E_DEVICEMGR_GAMEPAD && (strcasestr(tmp, "Abs Hat 0 X") || strcasestr(tmp, "Abs Hat 0 Y")))
1893                     {
1894                        goto gamepad_handling;
1895                     }
1896                   free(tmp);
1897                   tmp = NULL;
1898                }
1899              break;
1900           }
1901
1902         ptr += act_format/8;
1903      }
1904
1905 out:
1906    if (data) XFree(data);
1907    if (tmp) free(tmp);
1908
1909    return ret;
1910
1911 gamepad_handling:
1912
1913    if (data) XFree(data);
1914    if (tmp) free(tmp);
1915    data = NULL;
1916    tmp = NULL;
1917
1918    if (XIGetProperty(e_devicemgr.disp, deviceid, e_devicemgr.atomButtonLabels, 0, 1000, False,
1919                               XA_ATOM, &act_type, &act_format,
1920                               &nitems, &bytes_after, &data) != Success)
1921      {
1922         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][check_device_type] Failed to get XI2 Button device property !(deviceid=%d)\n", deviceid);
1923         goto out;
1924      }
1925
1926    if (!nitems) goto out;
1927
1928    ptr = data;
1929
1930    for (j = 0; j < nitems; j++)
1931      {
1932         switch(act_type)
1933           {
1934              case XA_ATOM:
1935                {
1936                   Ecore_X_Atom atomTemp = *(Ecore_X_Atom*)ptr;
1937                   if (!atomTemp) goto out;
1938
1939                   tmp = ecore_x_atom_name_get(atomTemp);
1940                   if(tmp)
1941                     {
1942                        if (strcasestr(tmp, "Button A") || strcasestr(tmp, "Button B"))
1943                          {
1944                             ret = 1;
1945                             goto out;
1946                          }
1947                        free(tmp);
1948                        tmp = NULL;
1949                     }
1950                }
1951              break;
1952           }
1953
1954         ptr += act_format/8;
1955      }
1956      goto out;
1957 }
1958
1959 static void
1960 _e_devicemgr_device_enabled(int id, int type)
1961 {
1962    int ndevices;
1963    XIDeviceInfo *info = NULL;
1964    DeviceMgr_Device_Info *data = NULL;
1965
1966    info = XIQueryDevice(e_devicemgr.disp, id, &ndevices);
1967
1968    if (!info || ndevices <= 0)
1969      {
1970         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] There is no queried XI device. (device id=%d, type=%d)\n", __FUNCTION__, id, type);
1971         goto out;
1972      }
1973
1974    switch(info->use)
1975      {
1976         case XISlavePointer:
1977            if (strcasestr(info->name, "XTEST")
1978 #ifdef _F_SUPPORT_XTEST_TOUCH_EVENT_
1979                && strncmp(info->name, TOUCH_DEVICE_NAME, LEN_TOUCH_DEVICE_NAME)
1980 #endif //_F_SUPPORT_XTEST_TOUCH_EVENT_
1981            ) goto out;
1982            if (strcasestr(info->name, "keyboard")) goto handle_keyboard;
1983            if (1==_e_devicemgr_check_device_type(id, E_DEVICEMGR_GAMEPAD, info->name)) goto handle_keyboard;
1984
1985            data = malloc(sizeof(DeviceMgr_Device_Info));
1986
1987            if (!data)
1988              {
1989                 SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__);
1990                 goto out;
1991              }
1992
1993            data->id = id;
1994            data->name = eina_stringshare_add(info->name);
1995            data->master_id = info->attachment;
1996            data->use = info->use;
1997
1998            if (1==_e_devicemgr_check_device_type(id, E_DEVICEMGR_TOUCHSCREEN, info->name))
1999              {
2000                 //Now we have a touchscreen device.
2001                 data->type = E_DEVICEMGR_TOUCHSCREEN;
2002                 if (strcasestr(data->name, "virtual") && strcasestr(data->name, "multitouch"))
2003                   {
2004                      _e_devicemgr_virtual_multitouch_helper_init(id);
2005                   }
2006                 e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
2007                 e_devicemgr.num_touchscreen_devices++;
2008                 SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Slave touchscreen device (id=%d, name=%s, num_touchscreen_devices=%d) was added/enabled !\n",
2009                             __FUNCTION__, id, info->name, e_devicemgr.num_touchscreen_devices);
2010              }
2011            else
2012              {
2013                 //Now we have a mouse.
2014                 data->type = E_DEVICEMGR_MOUSE;
2015                 e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
2016                 e_devicemgr.num_pointer_devices++;
2017                 SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Slave pointer device (id=%d, name=%s, num_pointer_devices=%d) was added/enabled !\n",
2018                            __FUNCTION__, id, info->name, e_devicemgr.num_pointer_devices);
2019                 if (strcasestr(info->name, E_VIRTUAL_TOUCHPAD_NAME))
2020                   {
2021                      e_devicemgr.virtual_touchpad_id = id;
2022                      _e_devicemgr_virtual_touchpad_helper_enable(EINA_TRUE);
2023                   }
2024              }
2025            break;
2026
2027         case XISlaveKeyboard:
2028            if (strcasestr(info->name, "XTEST")
2029 #ifdef _F_SUPPORT_XTEST_TOUCH_EVENT_
2030                && strncmp(info->name, FUNCTION_KEY_DEVICE_NAME, LEN_FUNCTION_KEY_DEVICE_NAME)
2031 #endif //_F_SUPPORT_XTEST_TOUCH_EVENT_
2032            ) goto out;
2033 handle_keyboard:
2034            data = malloc(sizeof(DeviceMgr_Device_Info));
2035
2036            if (!data)
2037              {
2038                 SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__);
2039                 goto out;
2040              }
2041
2042            if (strcasestr(info->name, "keyboard"))//keyboard
2043              {
2044                 int ret_val=-1;
2045                 //Now we have a keyboard device.
2046                 data->id = id;
2047                 data->name = eina_stringshare_add(info->name);
2048                 data->type = E_DEVICEMGR_KEYBOARD;
2049                         data->master_id = info->attachment;
2050
2051                 e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
2052                 e_devicemgr.num_keyboard_devices++;
2053
2054                 if (e_devicemgr.num_keyboard_devices >= 1)
2055                   _e_devicemgr_set_keyboard_exist((unsigned int)e_devicemgr.num_keyboard_devices, 1);
2056
2057                 SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Slave keyboard device (id=%d, name=%s, num_keyboard_devices=%d) was added/enabled !\n",
2058                            __FUNCTION__, id, info->name, e_devicemgr.num_keyboard_devices);
2059                 int res = ecore_x_window_prop_card32_get(e_devicemgr.input_window, e_devicemgr.atomExKeyboardEnabled, &ret_val, 1);
2060                 if(res <= 0)
2061                    SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr] fail to get keyboard enable prop\n");
2062                 if(ret_val == 0)
2063                   {
2064                      if(_e_devicemgr_detach_slave(data->id) == EINA_FALSE)
2065                        {
2066                           SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] : fail to detach slave device(%d) \n", data->id);
2067                        }
2068                   }
2069              }
2070            else if (1==_e_devicemgr_check_device_type(id, E_DEVICEMGR_GAMEPAD, info->name))
2071              {
2072                 int ret_val=-1;
2073                 //Now we have a game pad device.
2074                 data->id = id;
2075                 data->name = eina_stringshare_add(info->name);
2076                 data->type = E_DEVICEMGR_GAMEPAD;
2077                 data->master_id = info->attachment;
2078
2079                 e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
2080                 SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] game pad device (id=%d, name=%s) was added/enabled !\n",
2081                             __FUNCTION__, id, info->name);
2082
2083                 int res = ecore_x_window_prop_card32_get(e_devicemgr.input_window, e_devicemgr.atomExKeyboardEnabled, &ret_val, 1);
2084                 if(res <= 0)
2085                    SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr] fail to get keyboard enable prop\n");
2086                 if(ret_val == 0)
2087                   {
2088                      if(_e_devicemgr_detach_slave(data->id) == EINA_FALSE)
2089                        {
2090                           SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] : fail to detach slave device(%d) \n", data->id);
2091                        }
2092                   }
2093              }
2094            else//HW key
2095              {
2096                 data->type = E_DEVICEMGR_HWKEY;
2097                 data->id = id;
2098                 data->name = eina_stringshare_add(info->name);
2099
2100                 e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
2101                 e_devicemgr.num_hwkey_devices++;
2102              }
2103
2104            _e_devicemgr_lockmodifier_set();
2105            break;
2106
2107         case XIFloatingSlave:
2108            if (1 == _e_devicemgr_check_device_type(id, E_DEVICEMGR_TOUCHSCREEN, info->name))
2109              {
2110                 //Now we have a floating touchscreen device.
2111                 data = malloc(sizeof(DeviceMgr_Device_Info));
2112
2113                 if (!data)
2114                   {
2115                      SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__);
2116                      goto out;
2117                   }
2118
2119                 data->id = id;
2120                 data->name = eina_stringshare_add(info->name);
2121                 data->master_id = info->attachment;
2122                 data->use = info->use;
2123                 data->type = E_DEVICEMGR_TOUCHSCREEN;
2124                 e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
2125                 e_devicemgr.num_touchscreen_devices++;
2126
2127                 _e_devicemgr_append_prop_touchscreen_device_id(id);
2128
2129                 if (strcasestr(info->name, "virtual") && strcasestr(info->name, "multitouch"))
2130                   {
2131                      _e_devicemgr_virtual_multitouch_helper_init(id);
2132                   }
2133                 SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] FloatingSlave touchscreen device (id=%d, name=%s, num_touchscreen_devices=%d) was added/enabled !\n",
2134                            __FUNCTION__, id, info->name, e_devicemgr.num_touchscreen_devices);
2135              }
2136            break;
2137      }
2138
2139 out:
2140    if (info) XIFreeDeviceInfo(info);
2141 }
2142
2143 static void
2144 _e_devicemgr_device_disabled(int id, int type)
2145 {
2146    Eina_List* l;
2147    DeviceMgr_Device_Info *data;
2148
2149    if (!e_devicemgr.device_list)
2150      {
2151         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] device list is empty ! something's wrong ! (id=%d, type=%d)\n", __FUNCTION__, id, type);
2152         goto out;
2153      }
2154
2155    EINA_LIST_FOREACH(e_devicemgr.device_list, l, data)
2156      {
2157         if (data && data->id == id)
2158           {
2159              switch( data->type )
2160                {
2161                   case E_DEVICEMGR_HWKEY:
2162                      e_devicemgr.num_hwkey_devices--;
2163                      SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Slave H/W key device (id=%d, name=%s, type=%d) was removed/disabled !\n",
2164                                  __FUNCTION__, id, data->name, type);
2165
2166                      e_devicemgr.device_list = eina_list_remove(e_devicemgr.device_list, data);
2167                      free(data);
2168                      goto out;
2169
2170                   case E_DEVICEMGR_KEYBOARD:
2171                      e_devicemgr.num_keyboard_devices--;
2172
2173                      if (e_devicemgr.num_keyboard_devices <= 0)
2174                        {
2175                           e_devicemgr.num_keyboard_devices = 0;
2176                           _e_devicemgr_set_keyboard_exist(0, 0);
2177                        }
2178
2179                      SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Slave keyboard device (id=%d, name=%s, type=%d, num_keyboard_devices=%d) was removed/disabled !\n",
2180                                 __FUNCTION__, id, data->name, type, e_devicemgr.num_keyboard_devices);
2181
2182                      e_devicemgr.device_list = eina_list_remove(e_devicemgr.device_list, data);
2183                      free(data);
2184                      goto out;
2185
2186                   case E_DEVICEMGR_MOUSE:
2187                      e_devicemgr.num_pointer_devices--;
2188
2189                      if (e_devicemgr.num_pointer_devices <= 0)
2190                        {
2191                           e_devicemgr.num_pointer_devices = 0;
2192                        }
2193
2194                      SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Slave pointer device (id=%d, name=%s, type=%d, num_pointer_devices=%d) was removed/disabled !\n",
2195                                 __FUNCTION__, id, data->name, type, e_devicemgr.num_pointer_devices);
2196                      if (e_devicemgr.virtual_touchpad_id == id)
2197                        {
2198                           e_devicemgr.virtual_touchpad_id = -1;
2199                           _e_devicemgr_virtual_touchpad_helper_enable(EINA_FALSE);
2200                        }
2201                      e_devicemgr.device_list = eina_list_remove(e_devicemgr.device_list, data);
2202                      free(data);
2203                      goto out;
2204
2205                   case E_DEVICEMGR_TOUCHSCREEN:
2206                      if (strcasestr(data->name, "virtual") && strcasestr(data->name, "multitouch"))
2207                        _e_devicemgr_virtual_multitouch_helper_fini();
2208                      e_devicemgr.num_touchscreen_devices--;
2209                      SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] %sSlave touchscreen device (id=%d, name=%s, type=%d, num_touchscreen_devices=%d) was removed/disabled !\n",
2210                                 __FUNCTION__, (data->use == XISlavePointer) ? "" : "Floating", id, data->name, type, e_devicemgr.num_touchscreen_devices);
2211
2212                      if (data->use == XIFloatingSlave)
2213                         _e_devicemgr_remove_prop_touchscreen_device_id(data->id);
2214
2215                      e_devicemgr.device_list = eina_list_remove(e_devicemgr.device_list, data);
2216                      free(data);
2217                      goto out;
2218
2219                   case E_DEVICEMGR_GAMEPAD:
2220                      SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Slave gamepad device (id=%d, name=%s, type=%d) was removed/disabled !\n",
2221                                 __FUNCTION__, id, data->name, type);
2222
2223                      e_devicemgr.device_list = eina_list_remove(e_devicemgr.device_list, data);
2224                      free(data);
2225                      goto out;
2226
2227                   default:
2228                      SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Unknown type of device ! (id=%d, type=%d, name=%s, device type=%d)\n",
2229                                 __FUNCTION__, data->id, type, data->name, data->type);
2230                      e_devicemgr.device_list = eina_list_remove(e_devicemgr.device_list, data);
2231                      free(data);
2232                      goto out;
2233                }
2234           }
2235      }
2236
2237 out:
2238    return;
2239 }
2240
2241 static void
2242 _e_devicemgr_master_pointer_added(int id)
2243 {
2244    int ndevices;
2245    XIDeviceInfo *info = NULL;
2246
2247    info = XIQueryDevice(e_devicemgr.disp, id, &ndevices);
2248
2249    if (!info || ndevices <= 0)
2250      {
2251         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][master_pointer_added] There is no queried XI device. (device id=%d)\n", id);
2252         goto out;
2253      }
2254
2255    if (info->use != XIMasterPointer) goto out;
2256
2257    //Now we have a MasterPointer.
2258    if (strcasestr(E_NEW_MASTER_NAME" pointer", info->name))
2259      {
2260         //SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][master_pointer_added] XIMasterPointer is added !(id=%d, name=%s)\n", info->deviceid, info->name);
2261         e_devicemgr.new_master_pointer_id = info->deviceid;
2262
2263         Eina_List *l;
2264         Eina_List *l2;
2265         int touchscreen_id = -1;
2266         DeviceMgr_Device_Info *devinfo;
2267
2268         EINA_LIST_FOREACH_SAFE(e_devicemgr.device_list, l, l2, devinfo)
2269           {
2270              if (!devinfo) continue;
2271              if (devinfo->type == E_DEVICEMGR_TOUCHSCREEN)
2272                {
2273                   touchscreen_id = devinfo->id;
2274                   break;
2275                }
2276           }
2277
2278         if (touchscreen_id != -1)
2279           _e_devicemgr_reattach_slave
2280              (touchscreen_id, e_devicemgr.new_master_pointer_id);
2281      }
2282
2283 out:
2284    if (info) XIFreeDeviceInfo(info);
2285 }
2286
2287 static void
2288 _e_devicemgr_master_pointer_removed(int id)
2289 {
2290    if (e_devicemgr.new_master_pointer_id == id)
2291      {
2292         //SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][master_pointer_removed] XIMasterPointer was removed ! (id=%d, name=%s)\n",
2293         //           id, E_NEW_MASTER_NAME" pointer");
2294         e_devicemgr.new_master_pointer_id = -1;
2295
2296         Eina_List *l;
2297         Eina_List *l2;
2298         int touchscreen_id = -1;
2299         DeviceMgr_Device_Info *devinfo;
2300
2301         EINA_LIST_FOREACH_SAFE(e_devicemgr.device_list, l, l2, devinfo)
2302           {
2303              if (!devinfo) continue;
2304              if (devinfo->type == E_DEVICEMGR_TOUCHSCREEN)
2305                {
2306                   touchscreen_id = devinfo->id;
2307                   break;
2308                }
2309           }
2310
2311         if (touchscreen_id != -1)
2312           _e_devicemgr_reattach_slave
2313              (touchscreen_id, e_devicemgr.vcp_id);
2314      }
2315 }
2316
2317 static void
2318 _e_devicemgr_slave_switched(int deviceid, int sourceid)
2319 {
2320    unsigned int val;
2321    Eina_List *l;
2322    DeviceMgr_Device_Info *device_info;
2323
2324    EINA_LIST_FOREACH(e_devicemgr.device_list, l, device_info)
2325      {
2326         if (!device_info || device_info->id!=sourceid) continue;
2327         if (device_info->type==E_DEVICEMGR_TOUCHSCREEN)
2328           {
2329              val = 1;
2330              ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomTouchInput, &val, 1);
2331           }
2332         else if (device_info->type==E_DEVICEMGR_MOUSE)
2333           {
2334              val = 0;
2335              ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomTouchInput, &val, 1);
2336           }
2337      }
2338 }
2339
2340 static void
2341 _e_devicemgr_device_changed(int deviceid, int sourceid)
2342 {
2343    //SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][device_change_handler] deviceid:%d, sourceid:%d\n", deviceid, sourceid);
2344 }
2345
2346 static void
2347 _e_devicemgr_append_prop_touchscreen_device_id(int id)
2348 {
2349    unsigned int *prop_data = NULL, *new_data = NULL;
2350    int ret, count, i;
2351
2352    ret = ecore_x_window_prop_property_get(e_devicemgr.rootWin, e_devicemgr.atomMultitouchDeviceId,
2353       ECORE_X_ATOM_CARDINAL, 32, (unsigned char **)&prop_data, &count);
2354    if (!ret || !prop_data)
2355      {
2356         ecore_x_window_prop_property_set(e_devicemgr.rootWin, e_devicemgr.atomMultitouchDeviceId,
2357            ECORE_X_ATOM_CARDINAL, 32, &id, 1);
2358      }
2359    else
2360      {
2361         new_data = (int *)calloc(1, sizeof(int)*count+1);
2362         if (!new_data)
2363           {
2364              SLOG(LOG_WARN, "DEVICEMGR", "failed to allocate memory\n");
2365              if (prop_data) free(prop_data);
2366              return;
2367           }
2368         for (i=0; i<count; i++)
2369           {
2370              new_data[i] = prop_data[i];
2371              if (prop_data[i] == id)
2372                {
2373                   SLOG(LOG_DEBUG, "DEVICEMGR", "id(%d) was already registered in property\n", id);
2374                   if (new_data) free(new_data);
2375                   if (prop_data) free(prop_data);
2376                   return;
2377                }
2378           }
2379         new_data[count] = id;
2380         ecore_x_window_prop_property_set(e_devicemgr.rootWin, e_devicemgr.atomMultitouchDeviceId,
2381            ECORE_X_ATOM_CARDINAL, 32, new_data, count+1);
2382      }
2383
2384    if (new_data) free(new_data);
2385    if (prop_data) free(prop_data);
2386 }
2387
2388 static void
2389 _e_devicemgr_remove_prop_touchscreen_device_id(int id)
2390 {
2391    unsigned int *prop_data = NULL, *new_data = NULL;
2392    int ret, count, i, j=0;
2393
2394    ret = ecore_x_window_prop_property_get(e_devicemgr.rootWin, e_devicemgr.atomMultitouchDeviceId,
2395       ECORE_X_ATOM_CARDINAL, 32, (unsigned char **)&prop_data, &count);
2396    if (!ret || !prop_data)
2397      {
2398         SLOG(LOG_ERROR, "DEVICEMGR", "Failed to get multitouch device property\n");
2399      }
2400    else
2401      {
2402         new_data = (int *)calloc(1, sizeof(int)*count-1);
2403         for (i=0; i<count; i++)
2404           {
2405              if (prop_data[i] == id)
2406                {
2407                   SLOG(LOG_DEBUG, "DEVICEMGR", "id(%d) found in multitouch device property\n");
2408                   continue;
2409                }
2410              else
2411                {
2412                   if (j >= count)
2413                     {
2414                        SLOG(LOG_DEBUG, "DEVICEMGR", "id(%d) was not in multitouch device property\n");
2415                        if (new_data) free(new_data);
2416                        if (prop_data) free(prop_data);
2417                        return;
2418                     }
2419                   if (new_data != NULL) new_data[j] = prop_data[i];
2420                   j++;
2421                }
2422           }
2423         ecore_x_window_prop_property_set(e_devicemgr.rootWin, e_devicemgr.atomMultitouchDeviceId,
2424            ECORE_X_ATOM_CARDINAL, 32, new_data, count-1);
2425      }
2426
2427    if (new_data) free(new_data);
2428    if (prop_data) free(prop_data);
2429 }
2430
2431 static void _e_devicemgr_enable_mouse_cursor(unsigned int val)
2432 {
2433    if (!val)
2434      {
2435         _e_devicemgr_set_mouse_exist(0, 0);
2436      }
2437    else if (1 == val)
2438      {
2439         _e_devicemgr_set_mouse_exist(1, 0);
2440      }
2441 }
2442
2443 static void
2444 _e_devicemgr_set_confine_information(int deviceid, E_Zone *zone, Eina_Bool isset, int region[4], Eina_Bool pointer_warp, Eina_Bool confine)
2445 {
2446    int confine_region[6];
2447
2448    if (isset && !zone && !region)
2449      {
2450         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][set_confine_information] zone or region is needed for setting confine information !\n");
2451         return;
2452      }
2453
2454    if (isset)
2455      {
2456         if (zone)
2457           {
2458              confine_region[0] = zone->x;
2459              confine_region[1] = zone->y;
2460              confine_region[2] = zone->x + zone->w;
2461              confine_region[3] = zone->y + zone->h;
2462              //SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][set_confine_information][zone] x=%d, y=%d, w=%d, h=%d\n", confine_region[0], confine_region[1], confine_region[2], confine_region[3]);
2463           }
2464         else
2465           {
2466              confine_region[0] = region[0];
2467              confine_region[1] = region[1];
2468              confine_region[2] = region[2];
2469              confine_region[3] = region[3];
2470              //SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][set_confine_information][region] x=%d, y=%d, w=%d, h=%d\n", confine_region[0], confine_region[1], confine_region[2], confine_region[3]);
2471           }
2472         if (pointer_warp) confine_region[4] = 1;
2473         else confine_region[4] = 0;
2474         if (confine) confine_region[5] = 1;
2475         else confine_region[5] = 0;
2476         XIChangeProperty(e_devicemgr.disp, deviceid, e_devicemgr.atomVirtualTouchpadConfineRegion,
2477                                        XA_INTEGER, 32, PropModeReplace, (unsigned char*)&confine_region[0], 6);
2478         XFlush(e_devicemgr.disp);
2479         XSync(e_devicemgr.disp, False);
2480      }
2481    else
2482      {
2483         confine_region[0] = 0;
2484         XIChangeProperty(e_devicemgr.disp, deviceid, e_devicemgr.atomVirtualTouchpadConfineRegion,
2485                                        XA_INTEGER, 32, PropModeReplace, (unsigned char*)&confine_region[0], 1);
2486         XFlush(e_devicemgr.disp);
2487         XSync(e_devicemgr.disp, False);
2488      }
2489 }
2490
2491 static void
2492 _e_devicemgr_set_mouse_exist(unsigned int val, int propset)
2493 {
2494    if (!val)
2495      {
2496         char* cmds[] = {"e_devicemgr", "cursor_enable", "0", NULL };
2497         e_devicemgr.rroutput_buf_len = _e_devicemgr_marshalize_string (e_devicemgr.rroutput_buf,3, cmds);
2498
2499         XRRChangeOutputProperty(e_devicemgr.disp, e_devicemgr.output, e_devicemgr.atomRROutput, XA_CARDINAL, 8, PropModeReplace, (unsigned char *)e_devicemgr.rroutput_buf, e_devicemgr.rroutput_buf_len);
2500         XSync(e_devicemgr.disp, False);
2501         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr] cursor show = 0\n");
2502
2503         if (propset) ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomXMouseExist, &val, 1);
2504      }
2505    else if (1 == val)
2506      {
2507         char* cmds[] = {"e_devicemgr", "cursor_enable", "1", NULL };
2508         e_devicemgr.rroutput_buf_len = _e_devicemgr_marshalize_string (e_devicemgr.rroutput_buf,3, cmds);
2509
2510         XRRChangeOutputProperty(e_devicemgr.disp, e_devicemgr.output, e_devicemgr.atomRROutput, XA_CARDINAL, 8, PropModeReplace, (unsigned char *)e_devicemgr.rroutput_buf, e_devicemgr.rroutput_buf_len);
2511         XSync(e_devicemgr.disp, False);
2512         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr] cursor show = 1\n");
2513
2514         if (propset) ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomXMouseExist, &val, 1);
2515      }
2516    else
2517      {
2518         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Invalid value for enabling cursor !(val=%d)\n", __FUNCTION__, val);
2519      }
2520 }
2521
2522 static void
2523 _e_devicemgr_set_keyboard_exist(unsigned int val, int is_connected)
2524 {
2525    ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomXExtKeyboardExist, &val, 1);
2526 }
2527
2528 static int
2529 _e_devicemgr_get_lockmodifier_mask(void)
2530 {
2531    Window dummy1, dummy2;
2532    int dummy3, dummy4, dummy5, dummy6;
2533    unsigned int mask;
2534
2535    XQueryPointer(e_devicemgr.disp, DefaultRootWindow(e_devicemgr.disp), &dummy1, &dummy2,
2536                             &dummy3, &dummy4, &dummy5, &dummy6, &mask);
2537    return (mask & (NumLockMask | CapsLockMask));
2538 }
2539
2540 static int
2541 _e_devicemgr_xkb_set_on(unsigned int mask)
2542 {
2543    if (!mask) return 0;
2544
2545    XkbLockModifiers(e_devicemgr.disp, XkbUseCoreKbd, mask, mask);
2546    return 1;
2547 }
2548
2549 static int
2550 _e_devicemgr_lockmodifier_set(void)
2551 {
2552    unsigned int mask;
2553
2554    if (e_devicemgr.xkb_available != EINA_TRUE) return -1;
2555
2556    //Get current numlock/capslock status from Xserver
2557    mask = _e_devicemgr_get_lockmodifier_mask();
2558    SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][lockmodifier_set] NumLock mask=%d, CapsLock mask=%d\n",
2559                NumLockMask & mask, CapsLockMask & mask);
2560
2561    //If one of lockmodiers is set, try to turn it on for all keyboard devices.
2562    if (mask && _e_devicemgr_xkb_set_on(mask)) return 1;
2563
2564    return 0;
2565 }
2566
2567 static Eina_Bool
2568 _e_devicemgr_create_master_device(char* master_name)
2569 {
2570    int ret;
2571    XIAddMasterInfo c;
2572
2573    if (!master_name)
2574      {
2575         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][create_master_device] name of master device is needed !\n");
2576         return EINA_FALSE;
2577      }
2578
2579    c.type = XIAddMaster;
2580    c.name = master_name;
2581    c.send_core = 1;
2582    c.enable = 1;
2583
2584    ret = XIChangeHierarchy(e_devicemgr.disp, (XIAnyHierarchyChangeInfo*)&c, 1);
2585    XFlush(e_devicemgr.disp);
2586    XSync(e_devicemgr.disp, False);
2587
2588    if (ret!=Success) return EINA_FALSE;
2589
2590    SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][create_master_device] new master (%s) was created !\n", E_NEW_MASTER_NAME);
2591
2592    return EINA_TRUE;
2593 }
2594
2595 static Eina_Bool
2596 _e_devicemgr_remove_master_device(int master_id)
2597 {
2598    int ret;
2599    XIRemoveMasterInfo r;
2600
2601    if (master_id < 0)
2602      {
2603         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][remove_master_device] master_id(%d) is invalid !\n", master_id);
2604          return EINA_FALSE;
2605      }
2606
2607    r.type = XIRemoveMaster;
2608    r.deviceid = master_id;
2609    r.return_mode = XIFloating;
2610
2611    ret = XIChangeHierarchy(e_devicemgr.disp, (XIAnyHierarchyChangeInfo*)&r, 1);
2612    XFlush(e_devicemgr.disp);
2613    XSync(e_devicemgr.disp, False);
2614
2615    if (ret!=Success) return EINA_FALSE;
2616
2617    SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][remove_master_device] new master (%s) was removed !\n", E_NEW_MASTER_NAME);
2618
2619    return EINA_TRUE;
2620 }
2621
2622 static Eina_Bool
2623 _e_devicemgr_detach_slave(int slave_id)
2624 {
2625    int ret;
2626    XIDetachSlaveInfo detach;
2627    detach.type = XIDetachSlave;
2628    detach.deviceid = slave_id;
2629
2630    ret = XIChangeHierarchy(e_devicemgr.disp, (XIAnyHierarchyChangeInfo*)&detach, 1);
2631    XFlush(e_devicemgr.disp);
2632    XSync(e_devicemgr.disp, False);
2633
2634    if (ret!=Success) return EINA_FALSE;
2635
2636    SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][detach_slave] slave (id=%d) was removed !\n", slave_id);
2637
2638    return EINA_TRUE;
2639 }
2640
2641 static Eina_Bool
2642 _e_devicemgr_reattach_slave(int slave_id, int master_id)
2643 {
2644    int ret;
2645    XIAttachSlaveInfo attach;
2646
2647    attach.type = XIAttachSlave;
2648    attach.deviceid = slave_id;
2649    attach.new_master = master_id;
2650
2651    ret = XIChangeHierarchy(e_devicemgr.disp, (XIAnyHierarchyChangeInfo*)&attach, 1);
2652    XFlush(e_devicemgr.disp);
2653    XSync(e_devicemgr.disp, False);
2654
2655    if (ret!=Success) return EINA_FALSE;
2656
2657    SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][reattach_slave] slave (id=%d) was reattached to master (id:%d) !\n", slave_id, master_id);
2658
2659    return EINA_TRUE;
2660 }
2661
2662 static void
2663 _e_devicemgr_show_device_list(unsigned int val)
2664 {
2665    SLOG(LOG_DEBUG, "DEVICEMGR",  "\n[e_devicemgr] - Device List = Start =====================\n");
2666
2667    if (e_devicemgr.device_list)
2668      {
2669         Eina_List* l;
2670         DeviceMgr_Device_Info *data;
2671
2672         EINA_LIST_FOREACH(e_devicemgr.device_list, l, data)
2673           {
2674              if (data)
2675                {
2676                   SLOG(LOG_DEBUG, "DEVICEMGR",  "Device id : %d Name : %s\n", data->id, data->name);
2677                   switch (data->type)
2678                     {
2679                        case E_DEVICEMGR_HWKEY:
2680                           SLOG(LOG_DEBUG, "DEVICEMGR",  " : type : H/W Key\n");
2681                           break;
2682
2683                        case E_DEVICEMGR_KEYBOARD:
2684                           SLOG(LOG_DEBUG, "DEVICEMGR",  " : type : Keyboard\n");
2685                           break;
2686
2687                        case E_DEVICEMGR_MOUSE:
2688                           SLOG(LOG_DEBUG, "DEVICEMGR",  " : type : Mouse\n");
2689                           break;
2690
2691                        case E_DEVICEMGR_TOUCHSCREEN:
2692                           SLOG(LOG_DEBUG, "DEVICEMGR",  " : type : Touchscreen (use=%s)\n", (data->use == XIFloatingSlave) ? "FloatingSlave" : "Slave");
2693                           break;
2694
2695                        case E_DEVICEMGR_GAMEPAD:
2696                           SLOG(LOG_DEBUG, "DEVICEMGR",  " : type : Gamepad\n");
2697                           break;
2698
2699                        default:
2700                           SLOG(LOG_DEBUG, "DEVICEMGR",  " : type : Unknown\n");
2701                     }
2702                }
2703           }
2704      }
2705    else
2706      {
2707         SLOG(LOG_DEBUG, "DEVICEMGR",  "No input devices...\n");
2708      }
2709
2710    SLOG(LOG_DEBUG, "DEVICEMGR",  "\n[e_devicemgr] - Device List = End =====================\n");
2711 }
2712
2713 static Eina_Bool
2714 _e_devicemgr_virtual_touchpad_helper_enable(Eina_Bool is_enable)
2715 {
2716    Eina_Bool result;
2717
2718    if (is_enable)
2719      {
2720         if (e_devicemgr.num_zones < 2) return EINA_FALSE;
2721         result = _e_devicemgr_create_master_device(E_NEW_MASTER_NAME);
2722         if (EINA_FALSE==result)
2723           {
2724              SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][virtual_touchpad_helper_enable] Failed to create master device ! (name=%s)\n",
2725                         E_NEW_MASTER_NAME);
2726              return EINA_FALSE;
2727           }
2728         _e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, _e_devicemgr_get_nth_zone(2), EINA_TRUE, NULL, EINA_TRUE, EINA_FALSE);
2729      }
2730    else
2731      {
2732         result = _e_devicemgr_remove_master_device(e_devicemgr.new_master_pointer_id);
2733         if (EINA_FALSE==result)
2734           {
2735              SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][virtual_touchpad_helper_enable] Failed to remove master device ! (id=%d)\n",
2736                         e_devicemgr.new_master_pointer_id);
2737              return EINA_FALSE;
2738           }
2739         //_e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, NULL, EINA_FALSE, NULL, EINA_FALSE);
2740      }
2741
2742    return EINA_TRUE;
2743 }
2744
2745 static E_Zone*
2746 _e_devicemgr_get_nth_zone(int index)
2747 {
2748    Eina_List *l;
2749    E_Zone *zone;
2750    int count = 0;
2751
2752    if (e_devicemgr.num_zones < index)
2753      {
2754         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][get_nth_zone] %d th zone doesn't exist ! (num_zones=%d)\n",
2755                    index, e_devicemgr.num_zones);
2756         return NULL;
2757      }
2758
2759    EINA_LIST_FOREACH(e_devicemgr.zones, l, zone)
2760      {
2761         if (zone)
2762           {
2763              if (count==(index-1)) return zone;
2764              else count++;
2765           }
2766      }
2767
2768    return NULL;
2769 }
2770
2771 static int
2772 _e_devicemgr_get_configuration (void)
2773 {
2774    if (!e_mod_devicemgr_config_init())
2775      {
2776         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][get_configuration] Failed @ e_mod_devicemgr_config_init()..!\n");
2777         return 0;
2778      }
2779
2780    e_devicemgr.scrnconf_enable = _e_devicemgr_cfg->ScrnConf.enable;
2781    e_devicemgr.default_dispmode = _e_devicemgr_cfg->ScrnConf.default_dispmode;
2782    e_devicemgr.isPopUpEnabled = _e_devicemgr_cfg->ScrnConf.isPopUpEnabled;
2783
2784    return 1;
2785 }
2786
2787 static int
2788 _e_devicemgr_update_configuration (void)
2789 {
2790    e_mod_devicemgr_config_save();
2791
2792    return 1;
2793 }
2794
2795 static void
2796 _e_devicemgr_virtual_multitouch_helper_init(int deviceid)
2797 {
2798    int i;
2799
2800    for ( i=0 ; i < MAX_TOUCH ; i++ )
2801      {
2802         if (e_devicemgr.virtual_multitouch_id[i] < 0)
2803           {
2804              e_devicemgr.virtual_multitouch_id[i] = deviceid;
2805              break;
2806           }
2807      }
2808
2809    if (i < MAX_TOUCH-1) return;
2810
2811    SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][virtual_multitouch_helper_init] virtual touchscreen device were attached !\n");
2812
2813    e_devicemgr.mouse_in_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_mouse_in, NULL);
2814    e_devicemgr.border_move_end_hook = e_border_hook_add(E_BORDER_HOOK_MOVE_END, _e_devicemgr_hook_border_move_end, NULL);
2815    e_devicemgr.border_resize_end_hook = e_border_hook_add(E_BORDER_HOOK_RESIZE_END, _e_devicemgr_hook_border_resize_end, NULL);
2816
2817    if (!e_devicemgr.mouse_in_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add ECORE_X_EVENT_MOUSE_IN handler\n", __FUNCTION__);
2818    if (!e_devicemgr.border_move_end_hook) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add E_BORDER_HOOK_MOVE_END hook\n", __FUNCTION__);
2819    if (!e_devicemgr.border_resize_end_hook) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add E_BORDER_HOOK_RESIZE_END hook\n", __FUNCTION__);
2820 }
2821
2822 static void
2823 _e_devicemgr_virtual_multitouch_helper_fini(void)
2824 {
2825    SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][virtual_multitouch_helper_init] virtual touchscreen device(s) were removed !\n");
2826    memset(&e_devicemgr.virtual_multitouch_id, -1, sizeof(e_devicemgr.virtual_multitouch_id));
2827
2828    if (e_devicemgr.mouse_in_handler) ecore_event_handler_del(e_devicemgr.mouse_in_handler);
2829    if (e_devicemgr.border_move_end_hook) e_border_hook_del(e_devicemgr.border_move_end_hook);
2830    if (e_devicemgr.border_resize_end_hook) e_border_hook_del(e_devicemgr.border_resize_end_hook);
2831
2832    e_devicemgr.mouse_in_handler = NULL;
2833    e_devicemgr.border_move_end_hook = NULL;
2834    e_devicemgr.border_resize_end_hook = NULL;
2835 }
2836
2837 static void
2838 _e_devicemgr_update_input_transform_matrix(Eina_Bool reset)
2839 {
2840    int i;
2841
2842    static float identity_matrix[] = { 1.0f, 0, 0, 0, 1.0f, 0, 0, 0, 1.0f };
2843
2844    if (0 > e_devicemgr.virtual_multitouch_id[0])
2845      {
2846         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][update_input_transform_matrix] e_devicemgr.virtual_multitouch_id is invalid !\n");
2847         return;
2848      }
2849
2850    for( i = 0 ; i < 3 ; i++ )
2851      {
2852         if (reset)
2853           XIChangeProperty(e_devicemgr.disp, e_devicemgr.virtual_multitouch_id[i], e_devicemgr.atomInputTransform,
2854                                          e_devicemgr.atomFloat, 32, PropModeReplace, (unsigned char*)&identity_matrix, 9);
2855         else
2856           XIChangeProperty(e_devicemgr.disp, e_devicemgr.virtual_multitouch_id[i], e_devicemgr.atomInputTransform,
2857                                          e_devicemgr.atomFloat, 32, PropModeReplace, (unsigned char*)&e_devicemgr.tmatrix[0], 9);
2858      }
2859
2860    XFlush(e_devicemgr.disp);
2861    XSync(e_devicemgr.disp, False);
2862
2863    if (reset) SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][update_input_transform_matrix] transform matrix was reset to identity_matrix !\n");
2864    else SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][update_input_transform_matrix] transform matrix was updated !\n");
2865 }
2866