79a5c0d783b27c70c49c7d29a4f0a6233992bd53
[framework/uifw/e17-extra-modules.git] / devicemgr / 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
8 #define E_MOD_SCRNCONF_CHK_RET(cond, val) {if (!(cond)) { SLOG(LOG_DEBUG, "DEVICEMGR", "[%s] : '%s' failed.\n", __func__, #cond); return val; }}
9 #define E_MOD_SCRNCONF_CHK_GOTO(cond, dst) {if (!(cond)) { SLOG(LOG_DEBUG, "DEVICEMGR", "[%s] : '%s' failed.\n", __func__, #cond); goto dst; }}
10
11 extern char *strcasestr(const char *s, const char *find);
12 DeviceMgr e_devicemgr;
13 static Eina_Bool e_mod_set_disp_clone = EINA_FALSE;
14
15 static int _e_devicemgr_init (void);
16 static void _e_devicemgr_fini (void);
17 static int _e_devicemgr_get_configuration (void);
18 static int _e_devicemgr_update_configuration (void);
19
20 static int _e_devicemgr_cb_crtc_change     (void *data, int type, void *ev);
21 static int _e_devicemgr_cb_output_change   (void *data, int type, void *ev);
22 static int _e_devicemgr_cb_output_property (void *data, int type, void *ev);
23 static int _e_devicemgr_cb_client_message  (void* data, int type, void* event);
24
25 /* this is needed to advertise a label for the module IN the code (not just
26  * the .desktop file) but more specifically the api version it was compiled
27  * for so E can skip modules that are compiled for an incorrect API version
28  * safely) */
29 EAPI E_Module_Api e_modapi =
30 {
31    E_MODULE_API_VERSION,
32    "DeviceMgr Module of Window Manager"
33 };
34
35 EAPI void*
36 e_modapi_init(E_Module* m)
37 {
38    if (!_e_devicemgr_init())
39      {
40         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed @ _e_devicemgr_init()..!\n", __FUNCTION__);
41         return NULL;
42      }
43
44    /* add handlers */
45    e_devicemgr.client_message_handler = ecore_event_handler_add (ECORE_X_EVENT_CLIENT_MESSAGE, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_client_message, NULL);
46    e_devicemgr.window_property_handler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_window_property, NULL);
47    e_devicemgr.event_generic_handler = ecore_event_handler_add(ECORE_X_EVENT_GENERIC, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_event_generic, NULL);
48    e_devicemgr.zone_add_handler = ecore_event_handler_add(E_EVENT_ZONE_ADD, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_zone_add, NULL);
49    e_devicemgr.zone_del_handler = ecore_event_handler_add(E_EVENT_ZONE_DEL, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_zone_del, NULL);
50
51    if (!e_devicemgr.window_property_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add ECORE_X_EVENT_WINDOW_PROPERTY handler\n", __FUNCTION__);
52    if (!e_devicemgr.event_generic_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add ECORE_X_EVENT_GENERIC handler\n", __FUNCTION__);
53    if (!e_devicemgr.zone_add_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add E_EVENT_ZONE_ADD handler\n", __FUNCTION__);
54    if (!e_devicemgr.zone_del_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add E_EVENT_ZONE_DEL handler\n", __FUNCTION__);
55
56    if (e_devicemgr.scrnconf_enable)
57      {
58         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);
59         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);
60         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);
61
62         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__);
63         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__);
64         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__);
65      }
66
67    return m;
68 }
69
70 EAPI int
71 e_modapi_shutdown(E_Module* m)
72 {
73    ecore_event_handler_del (e_devicemgr.randr_crtc_handler);
74    ecore_event_handler_del (e_devicemgr.randr_output_handler);
75    ecore_event_handler_del (e_devicemgr.randr_output_property_handler);
76    ecore_event_handler_del(e_devicemgr.window_property_handler);
77    ecore_event_handler_del(e_devicemgr.event_generic_handler);
78    ecore_event_handler_del(e_devicemgr.zone_add_handler);
79    ecore_event_handler_del(e_devicemgr.zone_del_handler);
80    e_devicemgr.window_property_handler = NULL;
81    e_devicemgr.event_generic_handler = NULL;
82    e_devicemgr.zone_add_handler = NULL;
83    e_devicemgr.zone_del_handler = NULL;
84
85    e_devicemgr.randr_crtc_handler = NULL;
86    e_devicemgr.randr_output_handler = NULL;
87    e_devicemgr.randr_output_property_handler = NULL;
88    _e_devicemgr_fini();
89
90    return 1;
91 }
92
93 EAPI int
94 e_modapi_save(E_Module* m)
95 {
96    /* Do Something */
97    return 1;
98 }
99
100 static int
101 _e_devicemgr_init(void)
102 {
103    unsigned int val = 1;
104    int res, ret = 1;
105
106    memset(&e_devicemgr, 0, sizeof(DeviceMgr));
107
108    e_devicemgr.disp = ecore_x_display_get();
109
110    if (!e_devicemgr.disp)
111      {
112         SLOG(LOG_DEBUG, "DEVICEMGR", "\e[32m[e_devicemgr] Failed to open display..!\e[0m\n");
113         ret = 0;
114         goto out;
115      }
116
117    e_devicemgr.rootWin = ecore_x_window_root_first_get();
118
119    /* init data structure */
120    e_devicemgr.vcp_id = -1;
121    e_devicemgr.vcp_xtest_pointer_id = -1;
122    e_devicemgr.vck_xtest_keyboard_id = -1;
123    e_devicemgr.new_master_pointer_id = -1;
124    e_devicemgr.virtual_touchpad_id = -1;
125    e_devicemgr.virtual_multitouch_done = 1;
126    e_devicemgr.device_list = NULL;
127    e_devicemgr.atomRROutput = ecore_x_atom_get(E_PROP_XRROUTPUT);
128    e_devicemgr.atomDeviceName = ecore_x_atom_get(E_PROP_DEVICE_NAME);
129    e_devicemgr.atomDeviceList = ecore_x_atom_get(E_PROP_DEVICE_LIST);
130    e_devicemgr.atomXMouseExist = ecore_x_atom_get(E_PROP_X_MOUSE_EXIST);
131    e_devicemgr.atomXMouseCursorEnable = ecore_x_atom_get(E_PROP_X_MOUSE_CURSOR_ENABLE);
132    e_devicemgr.atomXExtKeyboardExist = ecore_x_atom_get(E_PROP_X_EXT_KEYBOARD_EXIST);
133    e_devicemgr.atomHWKbdInputStarted = ecore_x_atom_get(E_PROP_HW_KEY_INPUT_STARTED);
134    e_devicemgr.atomAxisLabels = ecore_x_atom_get(E_PROP_X_EVDEV_AXIS_LABELS);
135    e_devicemgr.atomVirtualTouchpadConfineRegion = ecore_x_atom_get(E_PROP_VIRTUAL_TOUCHPAD_CONFINE_REGION);
136    e_devicemgr.atomVirtualTouchpad = ecore_x_atom_get(E_PROP_VIRTUAL_TOUCHPAD);
137    e_devicemgr.atomVirtualTouchpadInt = ecore_x_atom_get(E_PROP_VIRTUAL_TOUCHPAD_INT);
138    e_devicemgr.atomDeviceMgrInputWindow = ecore_x_atom_get(E_PROP_DEVICEMGR_INPUTWIN);
139    e_devicemgr.atomTouchInput = ecore_x_atom_get(E_PROP_TOUCH_INPUT);
140    e_devicemgr.atomScrnConfDispModeSet = ecore_x_atom_get(STR_ATOM_SCRNCONF_DISPMODE_SET);
141    e_devicemgr.atomVirtMonReq = ecore_x_atom_get(STR_ATOM_VIRT_MONITOR_REQUEST);
142    e_devicemgr.atomHibReq = ecore_x_atom_get(STR_ATOM_HIB_REQUEST);
143    e_devicemgr.atomDevMgrCfg = ecore_x_atom_get(STR_ATOM_DEVICEMGR_CFG);
144    e_devicemgr.atomFloat = ecore_x_atom_get(XATOM_FLOAT);
145    e_devicemgr.atomInputTransform = ecore_x_atom_get(EVDEVMULTITOUCH_PROP_TRANSFORM);
146
147    ecore_x_window_prop_card32_set(e_devicemgr.rootWin, e_devicemgr.atomTouchInput, &val, 1);
148    memset(&e_devicemgr.virtual_touchpad_area_info, -1, sizeof(e_devicemgr.virtual_touchpad_area_info));
149    memset(&e_devicemgr.virtual_multitouch_id, -1, sizeof(e_devicemgr.virtual_multitouch_id));
150    e_devicemgr.virtual_touchpad_pointed_window = 0;
151    e_devicemgr.zones = NULL;
152
153    e_devicemgr.input_window = ecore_x_window_input_new(e_devicemgr.rootWin, -1, -1, 1, 1);
154
155    if (!e_devicemgr.input_window)
156      {
157         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to create input_window !\n");
158      }
159    else
160      {
161         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Succeed to create input_window (0x%x)!\n", e_devicemgr.input_window);
162         ecore_x_window_prop_property_set(e_devicemgr.rootWin, e_devicemgr.atomDeviceMgrInputWindow, ECORE_X_ATOM_WINDOW, 32, &e_devicemgr.input_window, 1);
163      }
164
165    res = _e_devicemgr_xinput_init();
166    if (!res)
167      {
168         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to initialize XInput Extension !\n");
169         ret =0;
170         goto out;
171      }
172
173    res = _e_devicemgr_xkb_init();
174    if (!res)
175      {
176         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to initialize XKB Extension !\n");
177         ret = 0;
178         goto out;
179      }
180
181    e_mod_scrnconf_external_init();
182
183    _e_devicemgr_init_transform_matrix();
184    _e_devicemgr_init_input();
185    _e_devicemgr_init_output();
186
187    res = _e_devicemgr_get_configuration();
188    if (!res)
189      {
190         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to get configuration from %s.cfg file !\n", E_DEVICEMGR_CFG);
191         ret =0;
192         goto out;
193      }
194
195    e_mod_scrnconf_container_bg_canvas_visible_set(EINA_FALSE);
196    if(EINA_FALSE == e_mod_sf_rotation_init())
197      {
198         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to init rotation!\n");
199      }
200      
201 out:
202    return ret;
203 }
204
205 static void
206 _e_devicemgr_fini(void)
207 {
208    if(EINA_FALSE == e_mod_sf_rotation_deinit())
209      {
210         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to deinit rotation!\n");
211      }
212
213    e_mod_devicemgr_config_shutdown();
214 }
215
216
217 static void
218 _get_preferred_size (int sc_output, int *preferred_w, int *preferred_h)
219 {
220    if (sc_output == SC_EXT_OUTPUT_HDMI)
221      {
222         *preferred_w = e_devicemgr.hdmi_preferred_w;
223         *preferred_h = e_devicemgr.hdmi_preferred_h;
224      }
225    else if (sc_output == SC_EXT_OUTPUT_VIRTUAL)
226      {
227         *preferred_w = e_devicemgr.virtual_preferred_w;
228         *preferred_h = e_devicemgr.virtual_preferred_h;
229      }
230    else
231      {
232         *preferred_w = 0;
233         *preferred_h = 0;
234      }
235 }
236
237 static int
238 _e_devicemgr_cb_crtc_change (void *data, int type, void *ev)
239 {
240    if (type == ECORE_X_EVENT_RANDR_CRTC_CHANGE)
241      {
242         //SLOG(LOG_DEBUG, "DEVICEMGR", "[scrn-conf]: Crtc Change!: \n");
243         //Ecore_X_Event_Randr_Crtc_Change *event = (Ecore_X_Event_Randr_Crtc_Change *)ev;
244         /* available information:
245            struct _Ecore_X_Event_Randr_Crtc_Change
246            {
247               Ecore_X_Window                win;
248               Ecore_X_Randr_Crtc            crtc;
249               Ecore_X_Randr_Mode            mode;
250               Ecore_X_Randr_Orientation     orientation;
251               int                           x;
252               int                           y;
253               int                           width;
254               int                           height;
255            };
256         */
257      }
258
259    return EINA_TRUE;
260 }
261
262 static int
263 _e_devicemgr_cb_output_change (void *data, int type, void *ev)
264 {
265    int sc_output = 0;
266    int sc_res = 0;
267    int sc_stat = 0;
268    int preferred_w =0, preferred_h = 0;
269
270    if (type == ECORE_X_EVENT_RANDR_OUTPUT_CHANGE)
271      {
272        //SLOG(LOG_DEBUG, "DEVICEMGR", "[scrn-conf]: Output Change!: \n");
273        Ecore_X_Event_Randr_Output_Change *event = (Ecore_X_Event_Randr_Output_Change *)ev;
274        /* available information:
275           struct _Ecore_X_Event_Randr_Output_Change
276           {
277              Ecore_X_Window                  win;
278              Ecore_X_Randr_Output            output;
279              Ecore_X_Randr_Crtc              crtc;
280              Ecore_X_Randr_Mode              mode;
281              Ecore_X_Randr_Orientation       orientation;
282              Ecore_X_Randr_Connection_Status connection;
283              Ecore_X_Render_Subpixel_Order   subpixel_order;
284           };
285        */
286        SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: Output Connection!: %d (connected = %d, disconnected = %d, unknown %d)\n",
287                 event->connection, ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED, ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED, ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN);
288
289        /* check status of a output */
290        if (event->connection == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED &&
291            event->crtc == 0 &&
292            event->mode == 0)
293          {
294             /* if display mode is set by the client message, ignore output conncetion */
295             if (e_mod_set_disp_clone)
296               {
297                  /* reset flag to default */
298                  e_mod_set_disp_clone = EINA_FALSE;
299                  return EINA_TRUE;
300               }
301
302             sc_stat = e_mod_scrnconf_external_get_status();
303             if (sc_stat == UTILX_SCRNCONF_STATUS_CONNECT ||
304                 sc_stat == UTILX_SCRNCONF_STATUS_ACTIVE)
305              {
306                 SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : external monitor status is already connected \n");
307                 return 1;
308              }
309
310             /* set the output of the external monitor */
311             sc_output = e_mod_scrnconf_external_get_output_from_xid (event->output);
312             E_MOD_SCRNCONF_CHK_RET (sc_output != SC_EXT_OUTPUT_NULL, 1);
313             e_mod_scrnconf_external_set_output (sc_output);
314
315             /* set the resolution of the external monitor */
316             _get_preferred_size (sc_output, &preferred_w, &preferred_h);
317             sc_res = e_mod_scrnconf_external_get_default_res (sc_output, preferred_w, preferred_h);
318             E_MOD_SCRNCONF_CHK_GOTO (sc_res != SC_EXT_RES_NULL, fail);
319             e_mod_scrnconf_external_set_res (sc_res);
320
321             /* set the default display mode of the external monitor */
322             if (e_devicemgr.default_dispmode == UTILX_SCRNCONF_DISPMODE_CLONE ||
323                 e_devicemgr.default_dispmode == UTILX_SCRNCONF_DISPMODE_EXTENDED)
324               {
325
326                  if (!e_mod_scrnconf_external_set_dispmode (sc_output, e_devicemgr.default_dispmode, sc_res))
327                    {
328                        e_mod_scrnconf_external_set_status (UTILX_SCRNCONF_STATUS_CONNECT);
329                        /* generate dialog */
330                        if (e_devicemgr.isPopUpEnabled)
331                           e_mod_scrnconf_external_dialog_new (sc_output);
332                        goto fail;
333                    }
334
335                  e_mod_scrnconf_external_set_status (UTILX_SCRNCONF_STATUS_ACTIVE);
336               }
337             else
338               {
339                  e_mod_scrnconf_external_set_status (UTILX_SCRNCONF_STATUS_CONNECT);
340               }
341
342             /* generate dialog */
343             if (e_devicemgr.isPopUpEnabled)
344                e_mod_scrnconf_external_dialog_new (sc_output);
345
346             e_mod_scrnconf_external_send_current_status();
347          }
348        else if (event->connection == ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED)
349          {
350             /* if display mode is set by the client message, ignore output disconnected */
351             if (e_mod_set_disp_clone)
352                return EINA_TRUE;
353
354             /* set the output of the external monitor */
355             sc_output = e_mod_scrnconf_external_get_output_from_xid (event->output);
356             E_MOD_SCRNCONF_CHK_RET (sc_output != SC_EXT_OUTPUT_NULL, 1);
357
358             e_mod_scrnconf_external_reset (sc_output);
359
360             e_mod_scrnconf_external_send_current_status();
361
362             /* if dialog is still showing, destroy dialog */
363             e_mod_scrnconf_external_dialog_free();
364
365             e_mod_scrnconf_container_bg_canvas_visible_set(EINA_FALSE);
366          }
367        else if (event->connection == ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN)
368          {
369             /* if dialog is still showing, destroy dialog */
370             e_mod_scrnconf_external_dialog_free();
371
372             if (e_devicemgr.default_dispmode == UTILX_SCRNCONF_DISPMODE_EXTENDED)
373               {
374                  e_mod_scrnconf_container_bg_canvas_visible_set(EINA_TRUE);
375               }
376          }
377
378      }
379
380    return EINA_TRUE;
381
382 fail:
383    e_mod_scrnconf_external_reset (sc_output);
384    return EINA_TRUE;
385 }
386
387 static int
388 _e_devicemgr_cb_output_property (void *data, int type, void *ev)
389 {
390    if (type == ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY)
391      {
392        //SLOG(LOG_DEBUG, "DEVICEMGR", "[scrn-conf]: Output Property Notify!: \n");
393        //Ecore_X_Event_Randr_Output_Property_Notify *event = (Ecore_X_Event_Randr_Output_Property_Notify *)ev;
394        /* available information:
395           struct _Ecore_X_Event_Randr_Output_Property_Notify
396           {
397           Ecore_X_Window                win;
398           Ecore_X_Randr_Output          output;
399           Ecore_X_Atom                  property;
400           Ecore_X_Time                  time;
401           Ecore_X_Randr_Property_Change state;
402           };
403        */
404      }
405
406    return EINA_TRUE;
407 }
408
409 static int
410 _e_devicemgr_cb_client_message (void* data, int type, void* event)
411 {
412    Ecore_X_Event_Client_Message* ev = event;
413    int req = 0;
414    int sc_dispmode = 0;
415    int sc_res = 0;
416    int sc_stat = 0;
417    int sc_output = 0;
418    int preferred_w = 0, preferred_h = 0;
419    int pos[2];
420    int cx, cy;
421    int x1, y1, x2, y2;
422    int w, h, px = 0, py = 0;
423    int vw, vh, pw = 0, ph = 0;
424    int region[5];
425    int pos_rootx, pos_rooty;
426
427    if (ev->message_type == e_devicemgr.atomVirtualTouchpadInt)
428      {
429         if (e_devicemgr.num_zones < 2)
430           {
431              ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt,
432                                                                      ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_SHUTDOWN, 0, 0, 0, 0);
433              return 1;
434           }
435
436         if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_NEED_TO_INIT)
437           {
438              ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt,
439                                                                      ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_DO_INIT, 0, 0, 0, 0);
440           }
441         else if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_AREA_INFO)
442           {
443              e_devicemgr.virtual_touchpad_area_info[0] = ev->data.l[1];
444              e_devicemgr.virtual_touchpad_area_info[1] = ev->data.l[2];
445              e_devicemgr.virtual_touchpad_area_info[2] = ev->data.l[3];
446              e_devicemgr.virtual_touchpad_area_info[3] = ev->data.l[4];
447              SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_client_message] virtual_touchpad_area_info=%d %d %d %d\n",
448                                 e_devicemgr.virtual_touchpad_area_info[0], e_devicemgr.virtual_touchpad_area_info[1],
449                                 e_devicemgr.virtual_touchpad_area_info[2], e_devicemgr.virtual_touchpad_area_info[3]);
450           }
451         else if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_WINDOW)
452           {
453              e_devicemgr.virtual_touchpad_window = (Ecore_X_Window)ev->data.l[1];
454              SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_client_message] virtual_touchpad_window=0x%x\n", e_devicemgr.virtual_touchpad_window);
455           }
456         else if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_CONFINE_SET)
457           {
458              _e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, _e_devicemgr_get_nth_zone(2), EINA_TRUE, NULL, EINA_FALSE, EINA_TRUE);
459              SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_client_message] E_VIRTUAL_TOUCHPAD_CONFINE_SET\n");
460           }
461         else if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_CONFINE_UNSET)
462           {
463              _e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, NULL, EINA_FALSE, NULL, EINA_FALSE, EINA_FALSE);
464              SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_client_message] E_VIRTUAL_TOUCHPAD_CONFINE_UNSET\n");
465           }
466         else if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_MT_BEGIN)
467           {
468              SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_client_message] E_VIRTUAL_TOUCHPAD_MT_BEGIN !virtual_multitouch_done=%d\n", e_devicemgr.virtual_multitouch_done);
469
470              if (0 != e_devicemgr.virtual_touchpad_pointed_window)
471                {
472                   XISetClientPointer(e_devicemgr.disp, e_devicemgr.virtual_touchpad_pointed_window, e_devicemgr.virtual_touchpad_id);
473                   XSync(e_devicemgr.disp, 0);
474                   ecore_x_pointer_xy_get(e_devicemgr.virtual_touchpad_pointed_window, &pos[0], &pos[1]);
475                   SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][_cb_client_message] cursor pos x=%d, y=%d\n", pos[0], pos[1]);
476
477                   if (pos[0] < 0 || pos[1] < 0 ) return 1;
478
479                   e_devicemgr.virtual_multitouch_done = 0;
480
481                   x1 = e_devicemgr.virtual_touchpad_pointed_window_info[0];
482                   y1 = e_devicemgr.virtual_touchpad_pointed_window_info[1];
483                   w = e_devicemgr.virtual_touchpad_pointed_window_info[2];
484                   h = e_devicemgr.virtual_touchpad_pointed_window_info[3];
485
486                   x2 = x1+w;
487                   y2 = y1+h;
488                   cx = x1 + pos[0];
489                   cy = y1 + pos[1];
490
491                   if (INSIDE(cx, cy, x1, y1, x1+(w/2), y1+(h/2)))
492                     {
493                        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));
494                        pw = pos[0]*2;
495                        ph = pos[1]*2;
496                        px = x1;
497                        py = y1;
498                        SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 1st box (effective area = %d, %d, %d, %d)!\n", px, py, pw, ph);
499                     }
500                   else if (INSIDE(cx, cy, x1+(w/2), y1, x2, y1+(h/2)))
501                     {
502                        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));
503                        pw = (w-pos[0])*2;
504                        ph = pos[1]*2;
505                        px = x2-pw;
506                        py = y1;
507                        SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 2nd box (effective area = %d, %d, %d, %d)!\n", px, py, pw, ph);
508                     }
509                   else if (INSIDE(cx, cy, x1, y1+(h/2), x1+(w/2), y2))
510                     {
511                        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);
512                        pw = pos[0]*2;
513                        ph = (h-pos[1])*2;
514                        px = x1;
515                        py = y2-ph;
516                        SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 3rd box (effective area = %d, %d, %d, %d)!\n", px, py, pw, ph);
517                     }
518                   else if (INSIDE(cx, cy, x1+(w/2), y1+(h/2), x2, y2))
519                     {
520                        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);
521                        pw = (w-pos[0])*2;
522                        ph = (h-pos[1])*2;
523                        px = x2-pw;
524                        py = y2-ph;
525                        SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 4th box (effective area = %d, %d, %d, %d)!\n", px, py, pw, ph);
526                     }
527                   else
528                     {
529                        SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] !!! pointer is not in 4 boxes !!!\n");
530                     }
531
532                   vw = e_devicemgr.virtual_touchpad_area_info[2] -e_devicemgr.virtual_touchpad_area_info[0];
533                   vh = e_devicemgr.virtual_touchpad_area_info[3] -e_devicemgr.virtual_touchpad_area_info[1];
534
535                   if (vw > pw) e_devicemgr.tmatrix[0] = (float)vw/pw;
536                   else e_devicemgr.tmatrix[0] = (float)pw/vw;
537                   if (vh > ph) e_devicemgr.tmatrix[4] = (float)vh/ph;
538                   else e_devicemgr.tmatrix[4] = (float)ph/vh;
539
540                   e_devicemgr.virtual_touchpad_cursor_pos[0] = pos[0];
541                   e_devicemgr.virtual_touchpad_cursor_pos[1] = pos[1];
542                   e_devicemgr.tmatrix[2] = (float)px*e_devicemgr.tmatrix[0]*(-1);
543                   e_devicemgr.tmatrix[5] = (float)py*e_devicemgr.tmatrix[4]*(-1);
544                   _e_devicemgr_update_input_transform_matrix(EINA_FALSE);
545
546                   region[0] = e_devicemgr.virtual_touchpad_pointed_window_info[0] + 10;
547                   region[1] = e_devicemgr.virtual_touchpad_pointed_window_info[1] + 10;
548                   region[2] = e_devicemgr.virtual_touchpad_pointed_window_info[2] - 20;
549                   region[3] = e_devicemgr.virtual_touchpad_pointed_window_info[3] - 20;
550                   region[4] = 0;
551                   _e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, NULL, EINA_TRUE, &region[0], EINA_FALSE, EINA_TRUE);
552                   ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt,
553                                                                           ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_MT_MATRIX_SET_DONE, 0, 0, 0, 0);
554                }
555           }
556         else if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_MT_END)
557           {
558              e_devicemgr.virtual_multitouch_done = 1;
559              SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_client_message] E_VIRTUAL_TOUCHPAD_MT_END !virtual_multitouch_done=%d\n", e_devicemgr.virtual_multitouch_done);
560              if (0 != e_devicemgr.virtual_touchpad_pointed_window)
561                {
562                   _e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, NULL, EINA_FALSE, NULL, EINA_FALSE, EINA_FALSE);
563                   //_e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, _e_devicemgr_get_nth_zone(2), EINA_TRUE, NULL, EINA_FALSE);
564                   if (e_devicemgr.virtual_touchpad_cursor_pos[0] >= 0 && e_devicemgr.virtual_touchpad_cursor_pos[1] >= 0)
565                     {
566                        pos_rootx = e_devicemgr.virtual_touchpad_cursor_pos[0] + e_devicemgr.virtual_touchpad_pointed_window_info[0];
567                        pos_rooty = e_devicemgr.virtual_touchpad_cursor_pos[1] + e_devicemgr.virtual_touchpad_pointed_window_info[1];
568                        ecore_x_pointer_warp(e_devicemgr.virtual_touchpad_pointed_window, e_devicemgr.virtual_touchpad_cursor_pos[0], e_devicemgr.virtual_touchpad_cursor_pos[1]);
569                        e_devicemgr.virtual_touchpad_cursor_pos[0] = -1;
570                        e_devicemgr.virtual_touchpad_cursor_pos[1] = -1;
571                   }
572                }
573           }
574
575         return 1;
576      }
577
578    if (ev->message_type == e_devicemgr.atomScrnConfDispModeSet)
579      {
580         sc_dispmode = (int)ev->data.s[0];
581
582         sc_stat = e_mod_scrnconf_external_get_status();
583         if (sc_stat == UTILX_SCRNCONF_STATUS_NULL)
584           {
585              SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : external monitor is not connected \n");
586              return 1;
587           }
588
589         if (sc_dispmode == e_mod_scrnconf_external_get_dispmode())
590           {
591              SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : the same dispmode is already set \n");
592              return 1;
593           }
594
595         sc_output = e_mod_scrnconf_external_get_output();
596         E_MOD_SCRNCONF_CHK_RET(sc_output != SC_EXT_OUTPUT_NULL, 1);
597
598         _get_preferred_size (sc_output, &preferred_w, &preferred_h);
599         sc_res = e_mod_scrnconf_external_get_default_res (sc_output, preferred_w, preferred_h);
600         E_MOD_SCRNCONF_CHK_RET(sc_res != SC_EXT_RES_NULL, 1);
601
602         if (!e_mod_scrnconf_external_set_dispmode (sc_output, sc_dispmode, sc_res))
603           {
604              SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to get external output \n");
605              return 1;
606           }
607
608         e_mod_scrnconf_external_set_status (UTILX_SCRNCONF_STATUS_ACTIVE);
609         e_mod_scrnconf_external_send_current_status();
610
611         /* if disp_mode is set by the client message, set clone flag for preventing
612            the output disconnect/connect */
613         if (sc_dispmode == UTILX_SCRNCONF_DISPMODE_CLONE)
614            e_mod_set_disp_clone = EINA_TRUE;
615      }
616    else if (ev->message_type == e_devicemgr.atomVirtMonReq)
617      {
618         req = (int)ev->data.s[0];
619         e_devicemgr.virtual_preferred_w = (int)ev->data.s[1];
620         e_devicemgr.virtual_preferred_h = (int)ev->data.s[2];
621
622         /* deal with edid data */
623         e_mod_drv_virt_mon_set (req);
624      }
625    else if (ev->message_type == e_devicemgr.atomHibReq)
626      {
627         req = (int)ev->data.s[0];
628      }
629    else if (ev->message_type == e_devicemgr.atomDevMgrCfg)
630      {
631         Eina_Bool set_popup = EINA_FALSE;
632         req = (int)ev->data.s[0];
633         if (req == DEVICEMGR_CFG_POPUP)
634           {
635              set_popup = (Eina_Bool)ev->data.s[1];
636              e_devicemgr.isPopUpEnabled = set_popup;
637              _e_devicemgr_cfg->ScrnConf.isPopUpEnabled = set_popup;
638           }
639         else if (req == DEVICEMGR_CFG_DEFAULT_DISPMODE)
640           {
641              sc_dispmode = (int)ev->data.s[1];
642              e_devicemgr.default_dispmode = sc_dispmode;
643              _e_devicemgr_cfg->ScrnConf.default_dispmode = sc_dispmode;
644           }
645         else
646           {
647              return 1;
648           }
649
650         /* update deivcemgr configuration */
651         _e_devicemgr_update_configuration();
652      }
653    else
654      {
655          ;
656      }
657
658    return 1;
659 }
660
661 static int
662 _e_devicemgr_xinput_init(void)
663 {
664    int event, error;
665    int major = 2, minor = 0;
666
667    if (!XQueryExtension(e_devicemgr.disp, "XInputExtension", &e_devicemgr.xi2_opcode, &event, &error))
668      {
669         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] XInput Extension isn't supported.\n", __FUNCTION__);
670         goto fail;
671      }
672
673    if (XIQueryVersion(e_devicemgr.disp, &major, &minor) == BadRequest)
674      {
675         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to query XI version.\n", __FUNCTION__);
676         goto fail;
677      }
678
679    memset(&e_devicemgr.eventmask, 0L, sizeof(XIEventMask));
680    e_devicemgr.eventmask.deviceid = XIAllDevices;
681    e_devicemgr.eventmask.mask_len = XIMaskLen(XI_RawMotion);
682    e_devicemgr.eventmask.mask = calloc(e_devicemgr.eventmask.mask_len, sizeof(char));
683
684    /* Events we want to listen for all */
685    XISetMask(e_devicemgr.eventmask.mask, XI_DeviceChanged);
686    XISetMask(e_devicemgr.eventmask.mask, XI_HierarchyChanged);
687    XISelectEvents(e_devicemgr.disp, e_devicemgr.rootWin, &e_devicemgr.eventmask, 1);
688
689    return 1;
690
691 fail:
692    e_devicemgr.xi2_opcode = -1;
693    return 0;
694 }
695
696 static int
697 _e_devicemgr_xkb_init(void)
698 {
699    int xkb_opcode, xkb_event, xkb_error;
700    int xkb_lmaj = XkbMajorVersion;
701    int xkb_lmin = XkbMinorVersion;
702
703    if (!(XkbLibraryVersion(&xkb_lmaj, &xkb_lmin)
704          && XkbQueryExtension(e_devicemgr.disp, &xkb_opcode, &xkb_event, &xkb_error, &xkb_lmaj, &xkb_lmin)))
705      {
706         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][xkb_init] Failed to initialize XKB extension !\n");
707         e_devicemgr.xkb_available = EINA_FALSE;
708         return 0;
709      }
710
711    e_devicemgr.xkb_available = EINA_TRUE;
712    return 1;
713 }
714
715 static int
716 _e_devicemgr_cb_window_property(void *data, int ev_type, void *ev)
717 {
718    int res;
719    unsigned int ret_val = 0;
720    Ecore_X_Event_Window_Property *e = ev;
721
722    if (e->atom == e_devicemgr.atomDeviceList && e->win == e_devicemgr.rootWin)
723      {
724         res = ecore_x_window_prop_card32_get(e->win, e_devicemgr.atomDeviceList, &ret_val, 1);
725
726         if (res == 1) _e_devicemgr_show_device_list(ret_val);
727         goto out;
728      }
729
730    if (e->atom == e_devicemgr.atomVirtualTouchpad && e->win == e_devicemgr.rootWin)
731      {
732         res = ecore_x_window_prop_card32_get(e->win, e_devicemgr.atomVirtualTouchpad, &ret_val, 1);
733
734         if (res == 1 && e_devicemgr.virtual_touchpad_id > 0)
735           {
736              ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt,
737                                                                      ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_SHUTDOWN, 0, 0, 0, 0);
738           }
739         goto out;
740      }
741
742 out:
743    return 1;
744 }
745
746 static int
747 _e_devicemgr_cb_event_generic(void *data, int ev_type, void *event)
748 {
749    Ecore_X_Event_Generic *e = (Ecore_X_Event_Generic *)event;
750    XIDeviceEvent *evData = (XIDeviceEvent *)(e->data);
751
752    if (e->extension != e_devicemgr.xi2_opcode)
753      {
754         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Invalid event !(extension:%d, evtype:%d)\n", __FUNCTION__, e->extension, e->evtype);
755         return 1;
756      }
757
758    if (!evData || evData->send_event)
759    {
760       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__);
761       return 1;
762    }
763
764    switch (e->evtype)
765    {
766       case XI_HierarchyChanged:
767          _e_devicemgr_xi2_device_hierarchy_handler((XIHierarchyEvent *)evData);
768          break;
769
770       case XI_DeviceChanged:
771          _e_devicemgr_xi2_device_changed_handler((XIDeviceChangedEvent *)evData);
772          break;
773    }
774
775    return 1;
776 }
777
778 static int
779 _e_devicemgr_cb_zone_add(void *data, int ev_type, void *event)
780 {
781    E_Event_Zone_Add *ev;
782    E_Zone *zone;
783    Eina_List *l;
784
785    ev = event;
786    zone = ev->zone;
787    if (!zone || !zone->name) return 1;
788
789    l = eina_list_data_find_list(e_devicemgr.zones, zone);
790    if (l)
791      {
792         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_add] zone exists already in zone list !\n");
793         return 1;
794      }
795
796    SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_add] z->name=%s, z->w=%d, z->h=%d, z->x=%d, z->y=%d\n",
797        zone->name, zone->w, zone->h, zone->x, zone->y);
798    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",
799        zone->useful_geometry.w, zone->useful_geometry.h, zone->useful_geometry.x, zone->useful_geometry.y);
800
801    e_devicemgr.zones = eina_list_append(e_devicemgr.zones, zone);
802    e_devicemgr.num_zones++;
803
804    SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_add] num_zones=%d\n", e_devicemgr.num_zones);
805
806    return 1;
807 }
808
809 static int
810 _e_devicemgr_cb_zone_del(void *data, int ev_type, void *event)
811 {
812    E_Event_Zone_Del *ev;
813    E_Zone *zone;
814    Eina_List *l;
815
816    ev = event;
817    zone = ev->zone;
818    if (!zone || !zone->name) return 1;
819
820    SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_del] z->name=%s, z->w=%d, z->h=%d, z->x=%d, z->y=%d\n",
821        zone->name, zone->w, zone->h, zone->x, zone->y);
822    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",
823        zone->useful_geometry.w, zone->useful_geometry.h, zone->useful_geometry.x, zone->useful_geometry.y);
824
825    if (e_devicemgr.num_zones < 2)//basic zone + additional zone(s)
826      {
827         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_del] Zone list needs to be checked into !\n");
828         return 1;
829      }
830
831    l = eina_list_data_find_list(e_devicemgr.zones, zone);
832    if (!l)
833      {
834         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_del] zone doesn't exist in zone list !\n");
835         return 1;
836      }
837
838    if (e_devicemgr.num_zones == 2 && e_devicemgr.virtual_touchpad_id > 0)
839      {
840         ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt,
841                                                                 ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_SHUTDOWN, 0, 0, 0, 0);
842      }
843
844    e_devicemgr.zones = eina_list_remove(e_devicemgr.zones, zone);
845    e_devicemgr.num_zones--;
846
847    SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_del] num_zones=%d\n", e_devicemgr.num_zones);
848
849    return 1;
850 }
851
852 static void
853 _e_devicemgr_hook_border_resize_end(void *data, void *border)
854 {
855    E_Border *bd = (E_Border *)border;
856    if (!bd) return;
857
858    e_devicemgr.virtual_touchpad_pointed_window_info[0] = bd->x + bd->client_inset.l;
859    e_devicemgr.virtual_touchpad_pointed_window_info[1] = bd->y + bd->client_inset.t;
860    e_devicemgr.virtual_touchpad_pointed_window_info[2] = bd->client.w;
861    e_devicemgr.virtual_touchpad_pointed_window_info[3] = bd->client.h;
862
863    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,
864               e_devicemgr.virtual_touchpad_pointed_window_info[0], e_devicemgr.virtual_touchpad_pointed_window_info[1],
865               e_devicemgr.virtual_touchpad_pointed_window_info[2], e_devicemgr.virtual_touchpad_pointed_window_info[3]);
866 }
867
868 static void
869 _e_devicemgr_hook_border_move_end(void *data, void *border)
870 {
871    E_Border *bd = (E_Border *)border;
872    if (!bd) return;
873
874    e_devicemgr.virtual_touchpad_pointed_window_info[0] = bd->x + bd->client_inset.l;
875    e_devicemgr.virtual_touchpad_pointed_window_info[1] = bd->y + bd->client_inset.t;
876    e_devicemgr.virtual_touchpad_pointed_window_info[2] = bd->client.w;
877    e_devicemgr.virtual_touchpad_pointed_window_info[3] = bd->client.h;
878
879    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,
880               e_devicemgr.virtual_touchpad_pointed_window_info[0], e_devicemgr.virtual_touchpad_pointed_window_info[1],
881               e_devicemgr.virtual_touchpad_pointed_window_info[2], e_devicemgr.virtual_touchpad_pointed_window_info[3]);
882 }
883
884 static Eina_Bool
885 _e_devicemgr_cb_mouse_in(void *data, int type, void *event)
886 {
887    int px, py;
888    int pw, ph;
889    int vw, vh;
890    E_Border *bd;
891    unsigned int val = 0;
892    Ecore_X_Event_Mouse_In *ev = event;
893
894    if (!e_devicemgr.virtual_multitouch_done) return ECORE_CALLBACK_PASS_ON;
895
896    bd = e_border_find_by_window(ev->event_win);
897    if (!bd)
898      {
899         if (e_devicemgr.rootWin == ecore_x_window_parent_get(ev->event_win))
900           {
901
902              if (!e_devicemgr.virtual_multitouch_done && e_devicemgr.virtual_touchpad_pointed_window != 0)
903                return ECORE_CALLBACK_PASS_ON;
904
905              e_devicemgr.virtual_touchpad_pointed_window = 0;
906              ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt,
907                                                                      ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_POINTED_WINDOW, 0, 0, 0, 0);
908              _e_devicemgr_update_input_transform_matrix(EINA_TRUE/* reset */);
909              return ECORE_CALLBACK_PASS_ON;
910           }
911
912         return ECORE_CALLBACK_PASS_ON;
913      }
914
915    if (bd->zone->id == 0)
916      {
917         return ECORE_CALLBACK_PASS_ON;
918      }
919
920    e_devicemgr.virtual_touchpad_pointed_window_info[0] = bd->x + bd->client_inset.l;
921    e_devicemgr.virtual_touchpad_pointed_window_info[1] = bd->y + bd->client_inset.t;
922    e_devicemgr.virtual_touchpad_pointed_window_info[2] = bd->client.w;
923    e_devicemgr.virtual_touchpad_pointed_window_info[3] = bd->client.h;
924    e_devicemgr.virtual_touchpad_pointed_window = bd->client.win;
925
926    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,
927               e_devicemgr.virtual_touchpad_pointed_window_info[0], e_devicemgr.virtual_touchpad_pointed_window_info[1],
928               e_devicemgr.virtual_touchpad_pointed_window_info[2], e_devicemgr.virtual_touchpad_pointed_window_info[3]);
929    ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt,
930                                                            ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_POINTED_WINDOW,
931                                                            e_devicemgr.virtual_touchpad_pointed_window, 0, 0, 0);
932
933    return ECORE_CALLBACK_PASS_ON;
934 }
935
936 static Eina_Bool
937 _e_devicemgr_get_zones(void)
938 {
939    Eina_List *ml;
940    E_Manager *man;
941
942    if (e_devicemgr.zones)
943       return EINA_FALSE;
944
945    EINA_LIST_FOREACH(e_manager_list(), ml, man)
946      {
947         if (man)
948           {
949              Eina_List *cl;
950              E_Container *con;
951
952              EINA_LIST_FOREACH(man->containers, cl, con)
953                {
954                   if (con)
955                     {
956                        Eina_List *zl;
957                        E_Zone *z;
958
959                        EINA_LIST_FOREACH(con->zones, zl, z)
960                          {
961                             if (z)
962                               {
963                                  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",
964                                           z->name, z->w, z->h, z->x, z->y);
965                                  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",
966                                           z->useful_geometry.w, z->useful_geometry.h, z->useful_geometry.x, z->useful_geometry.y);
967                                  e_devicemgr.zones = eina_list_append(e_devicemgr.zones, z);
968                                  e_devicemgr.num_zones++;
969                               }
970                          }
971                     }
972                }
973           }
974      }
975
976    return (e_devicemgr.zones) ? EINA_TRUE : EINA_FALSE;
977 }
978
979 static int
980 _e_devicemgr_marshalize_string (char* buf, int num, char* srcs[])
981 {
982    int i;
983    char * p = buf;
984
985    for (i=0; i<num; i++)
986      {
987         p += sprintf (p, srcs[i]);
988         *p = '\0';
989         p++;
990      }
991
992    *p = '\0';
993    p++;
994
995    return (p - buf);
996 }
997
998 static void
999 _e_devicemgr_init_output(void)
1000 {
1001    int i;
1002    XRROutputInfo *output_info = NULL;
1003
1004
1005    XRRScreenResources* res = XRRGetScreenResources (e_devicemgr.disp, e_devicemgr.rootWin);
1006    e_devicemgr.output = 0;
1007
1008    if (res && (res->noutput != 0))
1009      {
1010         for ( i = 0 ; i  <res->noutput ; i++ )
1011           {
1012              output_info = XRRGetOutputInfo(e_devicemgr.disp, res, res->outputs[i]);
1013              if (output_info && output_info->name && !strncmp(output_info->name, "LVDS1", 5))
1014                {
1015                   e_devicemgr.output = res->outputs[i];
1016                   SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][_e_devicemgr_init_output] LVDS1 was found !\n");
1017                   XRRFreeOutputInfo(output_info);
1018                   break;
1019                }
1020              else
1021                {
1022                   e_devicemgr.output = res->outputs[i];
1023                   SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][_e_devicemgr_init_output] LVDS1 was not found yet !\n");
1024                }
1025
1026              if (output_info) XRRFreeOutputInfo(output_info);
1027           }
1028      }
1029
1030    if (!e_devicemgr.output)
1031      {
1032         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][_e_devicemgr_init_output] Failed to init output !\n");
1033      }
1034 }
1035
1036 static void
1037 _e_devicemgr_init_transform_matrix(void)
1038 {
1039    memset(e_devicemgr.tmatrix, 0, sizeof(e_devicemgr.tmatrix));
1040
1041    e_devicemgr.tmatrix[8] = 1.0f;
1042    e_devicemgr.tmatrix[0] = 1.0f;
1043    e_devicemgr.tmatrix[4] = 1.0f;
1044 }
1045
1046 static void
1047 _e_devicemgr_init_input(void)
1048 {
1049    int i;
1050    int ndevices;
1051    XIDeviceInfo *dev, *info = NULL;
1052    DeviceMgr_Device_Info *data = NULL;
1053
1054    if (e_devicemgr.xi2_opcode < 0)
1055      {
1056         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to initialize input !\n", __FUNCTION__);
1057         return;
1058      }
1059
1060    info = XIQueryDevice(e_devicemgr.disp, XIAllDevices, &ndevices);
1061
1062    if (!info)
1063      {
1064         SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] There is no queried XI device.\n", __FUNCTION__);
1065         return;
1066      }
1067
1068    for (i = 0; i < ndevices ; i++)
1069      {
1070         dev = &info[i];
1071
1072         switch (dev->use)
1073           {
1074              case XISlavePointer:
1075                 if (strcasestr(dev->name, "Virtual core XTEST pointer"))
1076                   {
1077                      e_devicemgr.vcp_xtest_pointer_id = dev->deviceid;
1078                      continue;
1079                   }
1080                 if (strcasestr(dev->name, "XTEST")) continue;
1081                 if (strcasestr(dev->name, "keyboard")) goto handle_keyboard;
1082
1083                 data = malloc(sizeof(DeviceMgr_Device_Info));
1084
1085                 if (!data)
1086                   {
1087                      SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__);
1088                      goto out;
1089                   }
1090
1091                 data->id = dev->deviceid;
1092                 data->name = eina_stringshare_add(dev->name);
1093                 if (1==_e_devicemgr_check_device_type(dev->deviceid, E_DEVICEMGR_TOUCHSCREEN, dev->name))
1094                   {
1095                      //Now we have a touchscreen device.
1096                      data->type = E_DEVICEMGR_TOUCHSCREEN;
1097                      e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
1098                      e_devicemgr.num_touchscreen_devices++;
1099                      SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Slave touchscreen device (id=%d, name=%s, num_touchscreen_devices=%d) was added/enabled !\n",
1100                                  __FUNCTION__, dev->deviceid, dev->name, e_devicemgr.num_touchscreen_devices);
1101                   }
1102                 else
1103                   {
1104                      //Now we have a mouse.
1105                      data->type = E_DEVICEMGR_MOUSE;
1106                      e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
1107                      e_devicemgr.num_pointer_devices++;
1108
1109                      if (1==e_devicemgr.num_pointer_devices) _e_devicemgr_set_mouse_exist(1, 1);
1110                      SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Slave pointer device (id=%d, name=%s, num_pointer_devices=%d) was added/enabled !\n",
1111                                  __FUNCTION__, dev->deviceid, dev->name, e_devicemgr.num_pointer_devices);
1112                   }
1113                 break;
1114
1115              case XISlaveKeyboard:
1116                 if (strcasestr(dev->name, "Virtual core XTEST keyboard"))
1117                   {
1118                      e_devicemgr.vck_xtest_keyboard_id = dev->deviceid;
1119                      continue;
1120                   }
1121
1122                 if (strcasestr(dev->name, "XTEST")) continue;
1123 handle_keyboard:
1124                 data = malloc(sizeof(DeviceMgr_Device_Info));
1125
1126                 if (!data)
1127                   {
1128                      SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__);
1129                      goto out;
1130                   }
1131
1132                 if (strcasestr(dev->name, "keyboard") && !strcasestr(dev->name, "XTEST" ))//keyboard
1133                   {
1134                      //Now we have a keyboard device
1135                      data->id = dev->deviceid;
1136                      data->name = eina_stringshare_add(dev->name);
1137                      data->type = E_DEVICEMGR_KEYBOARD;
1138
1139                      e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
1140                      e_devicemgr.num_keyboard_devices++;
1141                      _e_devicemgr_lockmodifier_set();
1142
1143                      if (e_devicemgr.num_keyboard_devices >= 1)
1144                        {
1145                           _e_devicemgr_set_keyboard_exist((unsigned int)e_devicemgr.num_keyboard_devices, 1);
1146                        }
1147
1148                      SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Slave keyboard device (id=%d, name=%s, num_keyboard_devices=%d) was added/enabled !\n",
1149                                  __FUNCTION__, dev->deviceid, dev->name, e_devicemgr.num_keyboard_devices);
1150                   }
1151                 else//HW key
1152                   {
1153                      data->type = E_DEVICEMGR_HWKEY;
1154                      data->id = dev->deviceid;
1155                      data->name = eina_stringshare_add(dev->name);
1156
1157                      e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
1158                      e_devicemgr.num_hwkey_devices++;
1159                   }
1160                 break;
1161
1162              case XIFloatingSlave:
1163                 break;
1164
1165              case XIMasterPointer:
1166                 SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] XIMasterPointer (VCP) (id=%d, name=%s)\n", __FUNCTION__, dev->deviceid, dev->name);
1167                 e_devicemgr.vcp_id = dev->deviceid;
1168                 break;
1169
1170              case XIMasterKeyboard:
1171                 SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] XIMasterKeyboard (VCK) (id=%d, name=%s)\n", __FUNCTION__, dev->deviceid, dev->name);
1172                 e_devicemgr.vck_id = dev->deviceid;
1173                 break;
1174           }
1175      }
1176
1177 out:
1178    XIFreeDeviceInfo(info);
1179 }
1180
1181 static void
1182 _e_devicemgr_xi2_device_changed_handler(XIDeviceChangedEvent *event)
1183 {
1184    if (event->reason == XISlaveSwitch)
1185      {
1186         _e_devicemgr_slave_switched(event->deviceid, event->sourceid);
1187      }
1188    else if (event->reason == XIDeviceChange)
1189      {
1190         _e_devicemgr_device_changed(event->deviceid, event->sourceid);
1191      }
1192 }
1193
1194 static void
1195 _e_devicemgr_xi2_device_hierarchy_handler(XIHierarchyEvent *event)
1196 {
1197    int i;
1198
1199    if (event->flags & XIMasterAdded || event->flags & XIMasterRemoved)
1200      {
1201         for( i = 0 ; i < event->num_info ; i++ )
1202           {
1203              if (event->info[i].flags & XIMasterAdded)
1204                {
1205                   _e_devicemgr_master_pointer_added(event->info[i].deviceid);
1206                }
1207              else if (event->info[i].flags & XIMasterRemoved)
1208                {
1209                   _e_devicemgr_master_pointer_removed(event->info[i].deviceid);
1210                }
1211           }
1212      }
1213
1214    if (event->flags & XIDeviceEnabled || event->flags & XIDeviceDisabled)
1215      {
1216         for( i = 0 ; i < event->num_info ; i++ )
1217           {
1218              if (event->info[i].flags & XIDeviceEnabled)
1219                {
1220                   _e_devicemgr_device_enabled(event->info[i].deviceid, event->info[i].use);
1221                }
1222              else if (event->info[i].flags & XIDeviceDisabled)
1223                {
1224                   _e_devicemgr_device_disabled(event->info[i].deviceid, event->info[i].use);
1225                }
1226           }
1227      }
1228 }
1229
1230 static int
1231 _e_devicemgr_check_device_type(int deviceid, DeviceMgrDeviceType type, const char* devname)
1232 {
1233    char *tmp = NULL;
1234    Atom act_type;
1235    unsigned long nitems, bytes_after;
1236    unsigned char *data, *ptr;
1237    int j, act_format, ret = 0;
1238
1239    if (type != E_DEVICEMGR_TOUCHSCREEN && type != E_DEVICEMGR_MOUSE) return 0;
1240
1241    if (XIGetProperty(e_devicemgr.disp, deviceid, e_devicemgr.atomAxisLabels, 0, 1000, False,
1242                               XA_ATOM, &act_type, &act_format,
1243                               &nitems, &bytes_after, &data) != Success)
1244      {
1245         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][check_device_type] Failed to get XI2 device property !(deviceid=%d)\n", deviceid);
1246         goto out;
1247      }
1248
1249    if (!nitems) goto out;
1250
1251    ptr = data;
1252
1253    for (j = 0; j < nitems; j++)
1254      {
1255         switch(act_type)
1256           {
1257              case XA_ATOM:
1258                {
1259                   Ecore_X_Atom atomTemp = *(Ecore_X_Atom*)ptr;
1260                   if (!atomTemp) goto out;
1261
1262                   tmp = ecore_x_atom_name_get(atomTemp);
1263                   if ((type == E_DEVICEMGR_TOUCHSCREEN) && (strcasestr(tmp, "Abs X") || strcasestr(tmp, "Abs MT Position X")) && !strcasestr(devname, "maru"))
1264                     {
1265                        ret = 1;
1266                        goto out;
1267                     }
1268                   else if (type == E_DEVICEMGR_MOUSE && strcasestr(tmp, "Rel X"))
1269                     {
1270                        ret = 1;
1271                        goto out;
1272                     }
1273                }
1274              break;
1275           }
1276
1277         ptr += act_format/8;
1278      }
1279
1280 out:
1281    if (data) XFree(data);
1282    if (tmp) free(tmp);
1283
1284    return ret;
1285 }
1286
1287 static void
1288 _e_devicemgr_device_enabled(int id, int type)
1289 {
1290    int ndevices;
1291    XIDeviceInfo *info = NULL;
1292    DeviceMgr_Device_Info *data = NULL;
1293
1294    info = XIQueryDevice(e_devicemgr.disp, id, &ndevices);
1295
1296    if (!info || ndevices <= 0)
1297      {
1298         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] There is no queried XI device. (device id=%d, type=%d)\n", __FUNCTION__, id, type);
1299         goto out;
1300      }
1301
1302    switch(info->use)
1303      {
1304         case XISlavePointer:
1305            if (strcasestr(info->name, "XTEST")) goto out;
1306            if (strcasestr(info->name, "keyboard")) goto handle_keyboard;
1307
1308            data = malloc(sizeof(DeviceMgr_Device_Info));
1309
1310            if (!data)
1311              {
1312                 SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__);
1313                 goto out;
1314              }
1315
1316            data->id = id;
1317            data->name = eina_stringshare_add(info->name);
1318
1319            if (1==_e_devicemgr_check_device_type(id, E_DEVICEMGR_TOUCHSCREEN, info->name))
1320              {
1321                 //Now we have a touchscreen device.
1322                 data->type = E_DEVICEMGR_TOUCHSCREEN;
1323                 if (strcasestr(data->name, "virtual") && strcasestr(data->name, "multitouch"))
1324                   {
1325                      _e_devicemgr_virtual_multitouch_helper_init(id);
1326                   }
1327                 e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
1328                 e_devicemgr.num_touchscreen_devices++;
1329                 SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Slave touchscreen device (id=%d, name=%s, num_touchscreen_devices=%d) was added/enabled !\n",
1330                             __FUNCTION__, id, info->name, e_devicemgr.num_touchscreen_devices);
1331              }
1332            else
1333              {
1334                 //Now we have a mouse.
1335                 data->type = E_DEVICEMGR_MOUSE;
1336                 e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
1337                 e_devicemgr.num_pointer_devices++;
1338                 if (1==e_devicemgr.num_pointer_devices) _e_devicemgr_set_mouse_exist(1, 1);
1339                 SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Slave pointer device (id=%d, name=%s, num_pointer_devices=%d) was added/enabled !\n",
1340                            __FUNCTION__, id, info->name, e_devicemgr.num_pointer_devices);
1341                 if (strcasestr(info->name, E_VIRTUAL_TOUCHPAD_NAME))
1342                   {
1343                      e_devicemgr.virtual_touchpad_id = id;
1344                      _e_devicemgr_virtual_touchpad_helper_enable(EINA_TRUE);
1345                   }
1346              }
1347            break;
1348
1349         case XISlaveKeyboard:
1350            if (strcasestr(info->name, "XTEST")) goto out;
1351 handle_keyboard:
1352            data = malloc(sizeof(DeviceMgr_Device_Info));
1353
1354            if (!data)
1355              {
1356                 SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__);
1357                 goto out;
1358              }
1359
1360            if (strcasestr(info->name, "keyboard"))//keyboard
1361              {
1362                 //Now we have a keyboard device.
1363                 data->id = id;
1364                 data->name = eina_stringshare_add(info->name);
1365                 data->type = E_DEVICEMGR_KEYBOARD;
1366
1367                 e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
1368                 e_devicemgr.num_keyboard_devices++;
1369
1370                 if (e_devicemgr.num_keyboard_devices >= 1)
1371                   _e_devicemgr_set_keyboard_exist((unsigned int)e_devicemgr.num_keyboard_devices, 1);
1372
1373                 SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Slave keyboard device (id=%d, name=%s, num_keyboard_devices=%d) was added/enabled !\n",
1374                            __FUNCTION__, id, info->name, e_devicemgr.num_keyboard_devices);
1375              }
1376            else//HW key
1377              {
1378                 data->type = E_DEVICEMGR_HWKEY;
1379                 data->id = id;
1380                 data->name = eina_stringshare_add(info->name);
1381
1382                 e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data);
1383                 e_devicemgr.num_hwkey_devices++;
1384              }
1385
1386            _e_devicemgr_lockmodifier_set();
1387            break;
1388
1389         case XIFloatingSlave:
1390            if (1 == _e_devicemgr_check_device_type(id, E_DEVICEMGR_TOUCHSCREEN, info->name))
1391              {
1392                 //Now we have a floating touchscreen device.
1393                 if (strcasestr(info->name, "virtual") && strcasestr(info->name, "multitouch"))
1394                   {
1395                      _e_devicemgr_virtual_multitouch_helper_init(id);
1396                   }
1397                 SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] FloatingSlave touchscreen device (id=%d, name=%s) was added/enabled !\n",
1398                             __FUNCTION__, id, info->name);
1399              }
1400            break;
1401      }
1402
1403 out:
1404    if (info) XIFreeDeviceInfo(info);
1405 }
1406
1407 static void
1408 _e_devicemgr_device_disabled(int id, int type)
1409 {
1410    Eina_List* l;
1411    DeviceMgr_Device_Info *data;
1412
1413    if (!e_devicemgr.device_list)
1414      {
1415         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] device list is empty ! something's wrong ! (id=%d, type=%d)\n", __FUNCTION__, id, type);
1416         goto out;
1417      }
1418
1419    EINA_LIST_FOREACH(e_devicemgr.device_list, l, data)
1420      {
1421         if (data && data->id == id)
1422           {
1423              switch( data->type )
1424                {
1425                   case E_DEVICEMGR_HWKEY:
1426                      e_devicemgr.num_hwkey_devices--;
1427                      SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Slave H/W key device (id=%d, name=%s, type=%d) was removed/disabled !\n",
1428                                  __FUNCTION__, id, data->name, type);
1429
1430                      e_devicemgr.device_list = eina_list_remove(e_devicemgr.device_list, data);
1431                      free(data);
1432                      goto out;
1433
1434                   case E_DEVICEMGR_KEYBOARD:
1435                      e_devicemgr.num_keyboard_devices--;
1436
1437                      if (e_devicemgr.num_keyboard_devices <= 0)
1438                        {
1439                           e_devicemgr.num_keyboard_devices = 0;
1440                           _e_devicemgr_set_keyboard_exist(0, 0);
1441                        }
1442
1443                      SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Slave keyboard device (id=%d, name=%s, type=%d, num_keyboard_devices=%d) was removed/disabled !\n",
1444                                 __FUNCTION__, id, data->name, type, e_devicemgr.num_keyboard_devices);
1445
1446                      e_devicemgr.device_list = eina_list_remove(e_devicemgr.device_list, data);
1447                      free(data);
1448                      goto out;
1449
1450                   case E_DEVICEMGR_MOUSE:
1451                      e_devicemgr.num_pointer_devices--;
1452
1453                      if (e_devicemgr.num_pointer_devices <= 0)
1454                        {
1455                           e_devicemgr.num_pointer_devices = 0;
1456                           _e_devicemgr_set_mouse_exist(0, 1);
1457                        }
1458
1459                      SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Slave pointer device (id=%d, name=%s, type=%d, num_pointer_devices=%d) was removed/disabled !\n",
1460                                 __FUNCTION__, id, data->name, type, e_devicemgr.num_pointer_devices);
1461                      if (e_devicemgr.virtual_touchpad_id == id)
1462                        {
1463                           e_devicemgr.virtual_touchpad_id = -1;
1464                           _e_devicemgr_virtual_touchpad_helper_enable(EINA_FALSE);
1465                        }
1466                      e_devicemgr.device_list = eina_list_remove(e_devicemgr.device_list, data);
1467                      free(data);
1468                      goto out;
1469
1470                   case E_DEVICEMGR_TOUCHSCREEN:
1471                      if (strcasestr(data->name, "virtual") && strcasestr(data->name, "multitouch"))
1472                        _e_devicemgr_virtual_multitouch_helper_fini();
1473                      e_devicemgr.num_touchscreen_devices--;
1474                      SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Slave touchscreen device (id=%d, name=%s, type=%d, num_touchscreen_devices=%d) was removed/disabled !\n",
1475                                 __FUNCTION__, id, data->name, type, e_devicemgr.num_touchscreen_devices);
1476
1477                      e_devicemgr.device_list = eina_list_remove(e_devicemgr.device_list, data);
1478                      free(data);
1479                      goto out;
1480
1481                   default:
1482                      SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Unknown type of device ! (id=%d, type=%d, name=%s, device type=%d)\n",
1483                                 __FUNCTION__, data->id, type, data->name, data->type);
1484                      e_devicemgr.device_list = eina_list_remove(e_devicemgr.device_list, data);
1485                      free(data);
1486                      goto out;
1487                }
1488           }
1489      }
1490
1491 out:
1492    return;
1493 }
1494
1495 static void
1496 _e_devicemgr_master_pointer_added(int id)
1497 {
1498    int ndevices;
1499    XIDeviceInfo *info = NULL;
1500
1501    info = XIQueryDevice(e_devicemgr.disp, id, &ndevices);
1502
1503    if (!info || ndevices <= 0)
1504      {
1505         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][master_pointer_added] There is no queried XI device. (device id=%d)\n", id);
1506         goto out;
1507      }
1508
1509    if (info->use != XIMasterPointer) goto out;
1510
1511    //Now we have a MasterPointer.
1512    if (strcasestr(E_NEW_MASTER_NAME" pointer", info->name))
1513      {
1514         //SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][master_pointer_added] XIMasterPointer is added !(id=%d, name=%s)\n", info->deviceid, info->name);
1515         e_devicemgr.new_master_pointer_id = info->deviceid;
1516
1517         Eina_List *l;
1518         Eina_List *l2;
1519         int touchscreen_id = -1;
1520         DeviceMgr_Device_Info *devinfo;
1521
1522         EINA_LIST_FOREACH_SAFE(e_devicemgr.device_list, l, l2, devinfo)
1523           {
1524              if (!devinfo) continue;
1525              if (devinfo->type == E_DEVICEMGR_TOUCHSCREEN)
1526                {
1527                   touchscreen_id = devinfo->id;
1528                   break;
1529                }
1530           }
1531
1532         if (touchscreen_id != -1)
1533           _e_devicemgr_reattach_slave
1534              (touchscreen_id, e_devicemgr.new_master_pointer_id);
1535      }
1536
1537 out:
1538    if (info) XIFreeDeviceInfo(info);
1539 }
1540
1541 static void
1542 _e_devicemgr_master_pointer_removed(int id)
1543 {
1544    if (e_devicemgr.new_master_pointer_id == id)
1545      {
1546         //SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][master_pointer_removed] XIMasterPointer was removed ! (id=%d, name=%s)\n",
1547         //           id, E_NEW_MASTER_NAME" pointer");
1548         e_devicemgr.new_master_pointer_id = -1;
1549
1550         Eina_List *l;
1551         Eina_List *l2;
1552         int touchscreen_id = -1;
1553         DeviceMgr_Device_Info *devinfo;
1554
1555         EINA_LIST_FOREACH_SAFE(e_devicemgr.device_list, l, l2, devinfo)
1556           {
1557              if (!devinfo) continue;
1558              if (devinfo->type == E_DEVICEMGR_TOUCHSCREEN)
1559                {
1560                   touchscreen_id = devinfo->id;
1561                   break;
1562                }
1563           }
1564
1565         if (touchscreen_id != -1)
1566           _e_devicemgr_reattach_slave
1567              (touchscreen_id, e_devicemgr.vcp_id);
1568      }
1569 }
1570
1571 static void
1572 _e_devicemgr_slave_switched(int deviceid, int sourceid)
1573 {
1574    unsigned int val;
1575    Eina_List *l;
1576    DeviceMgr_Device_Info *device_info;
1577
1578    EINA_LIST_FOREACH(e_devicemgr.device_list, l, device_info)
1579      {
1580         if (!device_info || device_info->id!=sourceid) continue;
1581         if (device_info->type==E_DEVICEMGR_TOUCHSCREEN)
1582           {
1583              val = 1;
1584              ecore_x_window_prop_card32_set(e_devicemgr.rootWin, e_devicemgr.atomTouchInput, &val, 1);
1585           }
1586         else if (device_info->type==E_DEVICEMGR_MOUSE)
1587           {
1588              val = 0;
1589              ecore_x_window_prop_card32_set(e_devicemgr.rootWin, e_devicemgr.atomTouchInput, &val, 1);
1590           }
1591      }
1592 }
1593
1594 static void
1595 _e_devicemgr_device_changed(int deviceid, int sourceid)
1596 {
1597    //SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][device_change_handler] deviceid:%d, sourceid:%d\n", deviceid, sourceid);
1598 }
1599
1600 static void _e_devicemgr_enable_mouse_cursor(unsigned int val)
1601 {
1602    if (!val)
1603      {
1604         e_devicemgr.num_pointer_devices--;
1605         if (e_devicemgr.num_pointer_devices <= 0)
1606           {
1607              e_devicemgr.num_pointer_devices = 0;
1608              _e_devicemgr_set_mouse_exist(0, 0);
1609           }
1610      }
1611    else if (1 == val)
1612      {
1613         e_devicemgr.num_pointer_devices++;
1614         if (1==e_devicemgr.num_pointer_devices) _e_devicemgr_set_mouse_exist(1, 0);
1615      }
1616 }
1617
1618 static void
1619 _e_devicemgr_set_confine_information(int deviceid, E_Zone *zone, Eina_Bool isset, int region[4], Eina_Bool pointer_warp, Eina_Bool confine)
1620 {
1621    int confine_region[6];
1622
1623    if (isset && !zone && !region)
1624      {
1625         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][set_confine_information] zone or region is needed for setting confine information !\n");
1626         return;
1627      }
1628
1629    if (isset)
1630      {
1631         if (zone)
1632           {
1633              confine_region[0] = zone->x;
1634              confine_region[1] = zone->y;
1635              confine_region[2] = zone->x + zone->w;
1636              confine_region[3] = zone->y + zone->h;
1637              //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]);
1638           }
1639         else
1640           {
1641              confine_region[0] = region[0];
1642              confine_region[1] = region[1];
1643              confine_region[2] = region[2];
1644              confine_region[3] = region[3];
1645              //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]);
1646           }
1647         if (pointer_warp) confine_region[4] = 1;
1648         else confine_region[4] = 0;
1649         if (confine) confine_region[5] = 1;
1650         else confine_region[5] = 0;
1651         XIChangeProperty(e_devicemgr.disp, deviceid, e_devicemgr.atomVirtualTouchpadConfineRegion,
1652                                        XA_INTEGER, 32, PropModeReplace, (unsigned char*)&confine_region[0], 6);
1653         XFlush(e_devicemgr.disp);
1654         XSync(e_devicemgr.disp, False);
1655      }
1656    else
1657      {
1658         confine_region[0] = 0;
1659         XIChangeProperty(e_devicemgr.disp, deviceid, e_devicemgr.atomVirtualTouchpadConfineRegion,
1660                                        XA_INTEGER, 32, PropModeReplace, (unsigned char*)&confine_region[0], 1);
1661         XFlush(e_devicemgr.disp);
1662         XSync(e_devicemgr.disp, False);
1663      }
1664 }
1665
1666 static void
1667 _e_devicemgr_set_mouse_exist(unsigned int val, int propset)
1668 {
1669    if (!val)
1670      {
1671         char* cmds[] = {"e_devicemgr", "cursor_enable", "0", NULL };
1672         e_devicemgr.rroutput_buf_len = _e_devicemgr_marshalize_string (e_devicemgr.rroutput_buf,3, cmds);
1673
1674         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);
1675         XSync(e_devicemgr.disp, False);
1676
1677         if (propset) ecore_x_window_prop_card32_set(e_devicemgr.rootWin, e_devicemgr.atomXMouseExist, &val, 1);
1678      }
1679    else if (1 == val)
1680      {
1681         char* cmds[] = {"e_devicemgr", "cursor_enable", "1", NULL };
1682         e_devicemgr.rroutput_buf_len = _e_devicemgr_marshalize_string (e_devicemgr.rroutput_buf,3, cmds);
1683
1684         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);
1685         XSync(e_devicemgr.disp, False);
1686
1687         if (propset) ecore_x_window_prop_card32_set(e_devicemgr.rootWin, e_devicemgr.atomXMouseExist, &val, 1);
1688      }
1689    else
1690      {
1691         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][%s] Invalid value for enabling cursor !(val=%d)\n", __FUNCTION__, val);
1692      }
1693 }
1694
1695 static void
1696 _e_devicemgr_set_keyboard_exist(unsigned int val, int is_connected)
1697 {
1698    ecore_x_window_prop_card32_set(e_devicemgr.rootWin, e_devicemgr.atomXExtKeyboardExist, &val, 1);
1699 }
1700
1701 static int
1702 _e_devicemgr_get_lockmodifier_mask(void)
1703 {
1704    Window dummy1, dummy2;
1705    int dummy3, dummy4, dummy5, dummy6;
1706    unsigned int mask;
1707
1708    XQueryPointer(e_devicemgr.disp, DefaultRootWindow(e_devicemgr.disp), &dummy1, &dummy2,
1709                             &dummy3, &dummy4, &dummy5, &dummy6, &mask);
1710    return (mask & (NumLockMask | CapsLockMask));
1711 }
1712
1713 static int
1714 _e_devicemgr_xkb_set_on(unsigned int mask)
1715 {
1716    if (!mask) return 0;
1717
1718    XkbLockModifiers(e_devicemgr.disp, XkbUseCoreKbd, mask, mask);
1719    return 1;
1720 }
1721
1722 static int
1723 _e_devicemgr_lockmodifier_set(void)
1724 {
1725    unsigned int mask;
1726
1727    if (e_devicemgr.xkb_available != EINA_TRUE) return -1;
1728
1729    //Get current numlock/capslock status from Xserver
1730    mask = _e_devicemgr_get_lockmodifier_mask();
1731    SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][lockmodifier_set] NumLock mask=%d, CapsLock mask=%d\n",
1732                NumLockMask & mask, CapsLockMask & mask);
1733
1734    //If one of lockmodiers is set, try to turn it on for all keyboard devices.
1735    if (mask && _e_devicemgr_xkb_set_on(mask)) return 1;
1736
1737    return 0;
1738 }
1739
1740 static Eina_Bool
1741 _e_devicemgr_create_master_device(char* master_name)
1742 {
1743    int ret;
1744    XIAddMasterInfo c;
1745
1746    if (!master_name)
1747      {
1748         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][create_master_device] name of master device is needed !\n");
1749         return EINA_FALSE;
1750      }
1751
1752    c.type = XIAddMaster;
1753    c.name = master_name;
1754    c.send_core = 1;
1755    c.enable = 1;
1756
1757    ret = XIChangeHierarchy(e_devicemgr.disp, (XIAnyHierarchyChangeInfo*)&c, 1);
1758    XFlush(e_devicemgr.disp);
1759    XSync(e_devicemgr.disp, False);
1760
1761    if (ret!=Success) return EINA_FALSE;
1762
1763    SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][create_master_device] new master (%s) was created !\n", E_NEW_MASTER_NAME);
1764
1765    return EINA_TRUE;
1766 }
1767
1768 static Eina_Bool
1769 _e_devicemgr_remove_master_device(int master_id)
1770 {
1771    int ret;
1772    XIRemoveMasterInfo r;
1773
1774    if (master_id < 0)
1775      {
1776         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][remove_master_device] master_id(%d) is invalid !\n", master_id);
1777          return EINA_FALSE;
1778      }
1779
1780    r.type = XIRemoveMaster;
1781    r.deviceid = master_id;
1782    r.return_mode = XIFloating;
1783
1784    ret = XIChangeHierarchy(e_devicemgr.disp, (XIAnyHierarchyChangeInfo*)&r, 1);
1785    XFlush(e_devicemgr.disp);
1786    XSync(e_devicemgr.disp, False);
1787
1788    if (ret!=Success) return EINA_FALSE;
1789
1790    SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][remove_master_device] new master (%s) was removed !\n", E_NEW_MASTER_NAME);
1791
1792    return EINA_TRUE;
1793 }
1794
1795 static Eina_Bool
1796 _e_devicemgr_detach_slave(int slave_id)
1797 {
1798    int ret;
1799    XIDetachSlaveInfo detach;
1800    detach.type = XIDetachSlave;
1801    detach.deviceid = slave_id;
1802
1803    ret = XIChangeHierarchy(e_devicemgr.disp, (XIAnyHierarchyChangeInfo*)&detach, 1);
1804    XFlush(e_devicemgr.disp);
1805    XSync(e_devicemgr.disp, False);
1806
1807    if (ret!=Success) return EINA_FALSE;
1808
1809    SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][detach_slave] slave (id=%d) was removed !\n", slave_id);
1810
1811    return EINA_TRUE;
1812 }
1813
1814 static Eina_Bool
1815 _e_devicemgr_reattach_slave(int slave_id, int master_id)
1816 {
1817    int ret;
1818    XIAttachSlaveInfo attach;
1819
1820    attach.type = XIAttachSlave;
1821    attach.deviceid = slave_id;
1822    attach.new_master = master_id;
1823
1824    ret = XIChangeHierarchy(e_devicemgr.disp, (XIAnyHierarchyChangeInfo*)&attach, 1);
1825    XFlush(e_devicemgr.disp);
1826    XSync(e_devicemgr.disp, False);
1827
1828    if (ret!=Success) return EINA_FALSE;
1829
1830    SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][reattach_slave] slave (id=%d) was reattached to master (id:%d) !\n", slave_id, master_id);
1831
1832    return EINA_TRUE;
1833 }
1834
1835 static void
1836 _e_devicemgr_show_device_list(unsigned int val)
1837 {
1838    SLOG(LOG_DEBUG, "DEVICEMGR",  "\n[e_devicemgr] - Device List = Start =====================\n");
1839
1840    if (e_devicemgr.device_list)
1841      {
1842         Eina_List* l;
1843         DeviceMgr_Device_Info *data;
1844
1845         EINA_LIST_FOREACH(e_devicemgr.device_list, l, data)
1846           {
1847              if (data)
1848                {
1849                   SLOG(LOG_DEBUG, "DEVICEMGR",  "Device id : %d Name : %s\n", data->id, data->name);
1850                   switch (data->type)
1851                     {
1852                        case E_DEVICEMGR_HWKEY:
1853                           SLOG(LOG_DEBUG, "DEVICEMGR",  " : type : H/W Key\n");
1854                           break;
1855
1856                        case E_DEVICEMGR_KEYBOARD:
1857                           SLOG(LOG_DEBUG, "DEVICEMGR",  " : type : Keyboard\n");
1858                           break;
1859
1860                        case E_DEVICEMGR_MOUSE:
1861                           SLOG(LOG_DEBUG, "DEVICEMGR",  " : type : Mouse\n");
1862                           break;
1863
1864                        case E_DEVICEMGR_TOUCHSCREEN:
1865                           SLOG(LOG_DEBUG, "DEVICEMGR",  " : type : Touchscreen\n");
1866                           break;
1867
1868                        default:
1869                           SLOG(LOG_DEBUG, "DEVICEMGR",  " : type : Unknown\n");
1870                     }
1871                }
1872           }
1873      }
1874    else
1875      {
1876         SLOG(LOG_DEBUG, "DEVICEMGR",  "No input devices...\n");
1877      }
1878
1879    SLOG(LOG_DEBUG, "DEVICEMGR",  "\n[e_devicemgr] - Device List = End =====================\n");
1880 }
1881
1882 static Eina_Bool
1883 _e_devicemgr_virtual_touchpad_helper_enable(Eina_Bool is_enable)
1884 {
1885    Eina_Bool result;
1886
1887    if (is_enable)
1888      {
1889         if (e_devicemgr.num_zones < 2) return EINA_FALSE;
1890         result = _e_devicemgr_create_master_device(E_NEW_MASTER_NAME);
1891         if (EINA_FALSE==result)
1892           {
1893              SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][virtual_touchpad_helper_enable] Failed to create master device ! (name=%s)\n",
1894                         E_NEW_MASTER_NAME);
1895              return EINA_FALSE;
1896           }
1897         _e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, _e_devicemgr_get_nth_zone(2), EINA_TRUE, NULL, EINA_TRUE, EINA_FALSE);
1898      }
1899    else
1900      {
1901         result = _e_devicemgr_remove_master_device(e_devicemgr.new_master_pointer_id);
1902         if (EINA_FALSE==result)
1903           {
1904              SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][virtual_touchpad_helper_enable] Failed to remove master device ! (id=%d)\n",
1905                         e_devicemgr.new_master_pointer_id);
1906              return EINA_FALSE;
1907           }
1908         //_e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, NULL, EINA_FALSE, NULL, EINA_FALSE);
1909      }
1910
1911    return EINA_TRUE;
1912 }
1913
1914 static E_Zone*
1915 _e_devicemgr_get_nth_zone(int index)
1916 {
1917    Eina_List *l;
1918    E_Zone *zone;
1919    int count = 0;
1920
1921    if (e_devicemgr.num_zones < index)
1922      {
1923         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][get_nth_zone] %d th zone doesn't exist ! (num_zones=%d)\n",
1924                    index, e_devicemgr.num_zones);
1925         return NULL;
1926      }
1927
1928    EINA_LIST_FOREACH(e_devicemgr.zones, l, zone)
1929      {
1930         if (zone)
1931           {
1932              if (count==(index-1)) return zone;
1933              else count++;
1934           }
1935      }
1936
1937    return NULL;
1938 }
1939
1940 static int
1941 _e_devicemgr_get_configuration (void)
1942 {
1943    if (!e_mod_devicemgr_config_init())
1944      {
1945         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][get_configuration] Failed @ e_mod_devicemgr_config_init()..!\n");
1946         return 0;
1947      }
1948
1949    e_devicemgr.scrnconf_enable = _e_devicemgr_cfg->ScrnConf.enable;
1950    e_devicemgr.default_dispmode = _e_devicemgr_cfg->ScrnConf.default_dispmode;
1951    e_devicemgr.isPopUpEnabled = _e_devicemgr_cfg->ScrnConf.isPopUpEnabled;
1952
1953    return 1;
1954 }
1955
1956 static int
1957 _e_devicemgr_update_configuration (void)
1958 {
1959    e_mod_devicemgr_config_save();
1960
1961    return 1;
1962 }
1963
1964 static void
1965 _e_devicemgr_virtual_multitouch_helper_init(int deviceid)
1966 {
1967    int i;
1968
1969    for ( i=0 ; i < MAX_TOUCH ; i++ )
1970      {
1971         if (e_devicemgr.virtual_multitouch_id[i] < 0)
1972           {
1973              e_devicemgr.virtual_multitouch_id[i] = deviceid;
1974              break;
1975           }
1976      }
1977
1978    if (i < MAX_TOUCH-1) return;
1979
1980    SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][virtual_multitouch_helper_init] virtual touchscreen device were attached !\n");
1981
1982    e_devicemgr.mouse_in_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_mouse_in, NULL);
1983    e_devicemgr.border_move_end_hook = e_border_hook_add(E_BORDER_HOOK_MOVE_END, _e_devicemgr_hook_border_move_end, NULL);
1984    e_devicemgr.border_resize_end_hook = e_border_hook_add(E_BORDER_HOOK_RESIZE_END, _e_devicemgr_hook_border_resize_end, NULL);
1985
1986    if (!e_devicemgr.mouse_in_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add ECORE_X_EVENT_MOUSE_IN handler\n", __FUNCTION__);
1987    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__);
1988    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__);
1989 }
1990
1991 static void
1992 _e_devicemgr_virtual_multitouch_helper_fini(void)
1993 {
1994    SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][virtual_multitouch_helper_init] virtual touchscreen device(s) were removed !\n");
1995    memset(&e_devicemgr.virtual_multitouch_id, -1, sizeof(e_devicemgr.virtual_multitouch_id));
1996
1997    if (e_devicemgr.mouse_in_handler) ecore_event_handler_del(e_devicemgr.mouse_in_handler);
1998    if (e_devicemgr.border_move_end_hook) e_border_hook_del(e_devicemgr.border_move_end_hook);
1999    if (e_devicemgr.border_resize_end_hook) e_border_hook_del(e_devicemgr.border_resize_end_hook);
2000
2001    e_devicemgr.mouse_in_handler = NULL;
2002    e_devicemgr.border_move_end_hook = NULL;
2003    e_devicemgr.border_resize_end_hook = NULL;
2004 }
2005
2006 static void
2007 _e_devicemgr_update_input_transform_matrix(Eina_Bool reset)
2008 {
2009    int i;
2010
2011    static float identity_matrix[] = { 1.0f, 0, 0, 0, 1.0f, 0, 0, 0, 1.0f };
2012
2013    if (0 > e_devicemgr.virtual_multitouch_id[0])
2014      {
2015         SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][update_input_transform_matrix] e_devicemgr.virtual_multitouch_id is invalid !\n");
2016         return;
2017      }
2018
2019    for( i = 0 ; i < 3 ; i++ )
2020      {
2021         if (reset)
2022           XIChangeProperty(e_devicemgr.disp, e_devicemgr.virtual_multitouch_id[i], e_devicemgr.atomInputTransform,
2023                                          e_devicemgr.atomFloat, 32, PropModeReplace, (unsigned char*)&identity_matrix, 9);
2024         else
2025           XIChangeProperty(e_devicemgr.disp, e_devicemgr.virtual_multitouch_id[i], e_devicemgr.atomInputTransform,
2026                                          e_devicemgr.atomFloat, 32, PropModeReplace, (unsigned char*)&e_devicemgr.tmatrix[0], 9);
2027      }
2028
2029    XFlush(e_devicemgr.disp);
2030    XSync(e_devicemgr.disp, False);
2031
2032    if (reset) SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][update_input_transform_matrix] transform matrix was reset to identity_matrix !\n");
2033    else SLOG(LOG_DEBUG, "DEVICEMGR",  "[e_devicemgr][update_input_transform_matrix] transform matrix was updated !\n");
2034 }
2035