Fix build against Weston 1.6 IVI Shell
[profile/ivi/ico-uxf-weston-plugin.git] / src / ico_input_mgr.c
1 /*
2  * Copyright © 2010-2011 Intel Corporation
3  * Copyright © 2008-2011 Kristian Høgsberg
4  * Copyright © 2013-2014 TOYOTA MOTOR CORPORATION.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and
7  * its documentation for any purpose is hereby granted without fee, provided
8  * that the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of the copyright holders not be used in
11  * advertising or publicity pertaining to distribution of the software
12  * without specific, written prior permission.  The copyright holders make
13  * no representations about the suitability of this software for any
14  * purpose.  It is provided "as is" without express or implied warranty.
15  *
16  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
17  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
20  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
21  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23  */
24 /**
25  * @brief   Multi Input Manager (Weston(Wayland) PlugIn)
26  *
27  * @date    Feb-21-2014
28  */
29
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <stdbool.h>
33 #include <string.h>
34 #include <unistd.h>
35 #include <linux/input.h>
36 #include <assert.h>
37 #include <signal.h>
38 #include <math.h>
39 #include <time.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <fcntl.h>
43 #include <linux/input.h>
44 #include <linux/uinput.h>
45 #include <errno.h>
46
47 #include <wayland-server.h>
48 #include <weston/ivi-layout-export.h>
49 #include <weston/compositor.h>
50 #include "ico_ivi_common_private.h"
51 #include "ico_input_mgr.h"
52 #include "ico_window_mgr_private.h"
53 #include "ico_window_mgr-server-protocol.h"
54 #include "ico_input_mgr-server-protocol.h"
55
56 /* degine maximum length                */
57 #define ICO_MINPUT_DEVICE_LEN           32
58 #define ICO_MINPUT_SW_LEN               20
59 #define ICO_MINPUT_MAX_CODES            20
60
61 /* structure definition */
62 struct uifw_region_mng;
63
64 /* working table of Multi Input Manager */
65 struct ico_input_mgr {
66     struct weston_compositor *compositor;   /* Weston Compositor                    */
67     struct wl_list  ictl_list;              /* Input Controller List                */
68     struct wl_list  app_list;               /* application List                     */
69     struct wl_list  free_region;            /* free input region table list         */
70     struct weston_seat *seat;               /* input seat                           */
71     struct wl_resource *inputmgr;
72 };
73
74 /* Input Switch Table                   */
75 struct ico_ictl_code {
76     uint16_t    code;                       /* input code numner                    */
77     char        name[ICO_MINPUT_SW_LEN];    /* input code name                      */
78 };
79
80 struct ico_ictl_input {
81     struct wl_list link;                    /* link                                 */
82     char        swname[ICO_MINPUT_SW_LEN];  /* input switch name                    */
83     int32_t     input;                      /* input Id                             */
84     uint16_t    fix;                        /* fixed assign to application          */
85     uint16_t    ncode;                      /* number of codes                      */
86     struct ico_ictl_code code[ICO_MINPUT_MAX_CODES];   /* codes                     */
87     struct ico_app_mgr  *app;               /* send event tagret application        */
88 };
89
90 /* Input Controller Management Table    */
91 struct ico_ictl_mgr {
92     struct wl_list link;                    /* link                                 */
93     struct wl_client    *client;            /* client                               */
94     struct wl_resource  *mgr_resource;      /* resource as manager                  */
95     char    device[ICO_MINPUT_DEVICE_LEN];  /* device name                          */
96     int     type;                           /* device type                          */
97     struct wl_list ico_ictl_input;          /* list of input switchs                */
98 };
99
100 /* Application Management Table */
101 struct ico_app_mgr {
102     struct wl_list link;                    /* link                                 */
103     struct wl_client    *client;            /* client                               */
104     struct wl_resource  *resource;          /* resource for send event              */
105     struct wl_resource  *mgr_resource;      /* resource as manager(if NULL, client) */
106     char    appid[ICO_IVI_APPID_LENGTH];    /* application id                       */
107 };
108
109 /* Pseudo Input Device Control Flags    */
110 #define EVENT_MOTION        0x01            /* motion event                         */
111 #define EVENT_BUTTON        0x02            /* button event                         */
112 #define EVENT_TOUCH         0x03            /* touch event                          */
113 #define EVENT_KEY           0x04            /* key event                            */
114 #define EVENT_PENDING       0xff            /* pending event input                  */
115
116 #define PENDING_X           0x01            /* pending X coordinate                 */
117 #define PENDING_Y           0x02            /* pending Y coordinate                 */
118
119 /* Input Region Table           */
120 struct uifw_region_mng  {
121     struct wl_list  link;                   /* link pointer                         */
122     struct ico_uifw_input_region region;    /* input region                         */
123 };
124
125 /* prototype of static function */
126                                             /* bind input manager form manager      */
127 static void ico_control_bind(struct wl_client *client, void *data,
128                              uint32_t version, uint32_t id);
129                                             /* unbind input manager form manager    */
130 static void ico_control_unbind(struct wl_resource *resource);
131                                             /* bind input manager form input controller*/
132 static void ico_device_bind(struct wl_client *client, void *data,
133                             uint32_t version, uint32_t id);
134                                             /* unbind input manager form input controller*/
135 static void ico_device_unbind(struct wl_resource *resource);
136                                             /* bind input manager(form application) */
137 static void ico_exinput_bind(struct wl_client *client, void *data,
138                              uint32_t version, uint32_t id);
139                                             /* unbind input manager(form application)*/
140 static void ico_exinput_unbind(struct wl_resource *resource);
141
142                                             /* find ictl manager by device name     */
143 static struct ico_ictl_mgr *find_ictlmgr_by_device(const char *device);
144                                             /* find ictl input switch by input Id   */
145 static struct ico_ictl_input *find_ictlinput_by_input(struct ico_ictl_mgr *pIctlMgr,
146                                                       const int32_t input);
147                                             /* find app manager by application Id   */
148 static struct ico_app_mgr *find_app_by_appid(const char *appid);
149                                             /* add input event to application       */
150 static void ico_mgr_add_input_app(struct wl_client *client, struct wl_resource *resource,
151                                   const char *appid, const char *device, int32_t input,
152                                   int32_t fix, int32_t keycode);
153                                             /* delete input event to application    */
154 static void ico_mgr_del_input_app(struct wl_client *client, struct wl_resource *resource,
155                                   const char *appid, const char *device, int32_t input);
156                                             /* send key input event from device     */
157 static void ico_mgr_send_key_event(struct wl_client *client, struct wl_resource *resource,
158                                    const char *target, int32_t code, int32_t value);
159                                             /* set input region                     */
160 static void ico_mgr_set_input_region(struct wl_client *client, struct wl_resource *resource,
161                                      const char *target, int32_t x, int32_t y,
162                                      int32_t width, int32_t height, int32_t hotspot_x,
163                                      int32_t hotspot_y, int32_t cursor_x, int32_t cursor_y,
164                                      int32_t cursor_width, int32_t cursor_height,
165                                      uint32_t attr);
166                                             /* unset input region                   */
167 static void ico_mgr_unset_input_region(struct wl_client *client,
168                                        struct wl_resource *resource,
169                                        const char *taret, int32_t x, int32_t y,
170                                        int32_t width, int32_t height);
171                                             /* input region set/unset               */
172 static void ico_set_input_region(int set, struct uifw_win_surface *usurf,
173                                  int32_t x, int32_t y, int32_t width, int32_t height,
174                                  int32_t hotspot_x, int32_t hotspot_y, int32_t cursor_x,
175                                  int32_t cursor_y, int32_t cursor_width,
176                                  int32_t cursor_height, uint32_t attr);
177                                             /* create and regist Input Controller table*/
178 static void ico_device_configure_input(struct wl_client *client,
179                                        struct wl_resource *resource, const char *device,
180                                        int32_t type, const char *swname, int32_t input,
181                                        const char *codename, int32_t code);
182                                             /* add input to from Input Controller table*/
183 static void ico_device_configure_code(struct wl_client *client,
184                                       struct wl_resource *resource, const char *device,
185                                       int32_t input, const char *codename, int32_t code);
186                                             /* device input event                   */
187 static void ico_device_input_event(struct wl_client *client, struct wl_resource *resource,
188                                    uint32_t time, const char *device,
189                                    int32_t input, int32_t code, int32_t state);
190                                             /* send region event                    */
191 static void ico_input_send_region_event(struct wl_array *array);
192
193 /* definition of Wayland protocol       */
194 /* Input Manager Control interface      */
195 static const struct ico_input_mgr_control_interface ico_input_mgr_implementation = {
196     ico_mgr_add_input_app,
197     ico_mgr_del_input_app,
198     ico_mgr_send_key_event
199 };
200
201 /* Extended Input interface             */
202 static const struct ico_exinput_interface ico_exinput_implementation = {
203     ico_mgr_set_input_region,
204     ico_mgr_unset_input_region
205 };
206
207 /* Input Controller Device interface    */
208 static const struct ico_input_mgr_device_interface input_mgr_ictl_implementation = {
209     ico_device_configure_input,
210     ico_device_configure_code,
211     ico_device_input_event
212 };
213
214 /* definition of class variable */
215 struct ico_input_mgr    *pInputMgr = NULL;
216
217 /* implementation */
218 /*--------------------------------------------------------------------------*/
219 /**
220  * @brief   ico_mgr_add_input_app: add input event to application from HomeScreen.
221  *
222  * @param[in]   client          client(HomeScreen)
223  * @param[in]   resource        resource of request
224  * @param[in]   appid           target application id
225  * @param[in]   device          device name
226  * @param[in]   input           input switch number
227  * @param[in]   fix             fix to application(1=fix,0=general)
228  * @param[in]   keycode         switch map to keyboard operation(0=not map to keyboard)
229  * @return      none
230  */
231 /*--------------------------------------------------------------------------*/
232 static void
233 ico_mgr_add_input_app(struct wl_client *client, struct wl_resource *resource,
234                       const char *appid, const char *device, int32_t input,
235                       int32_t fix, int32_t keycode)
236 {
237     struct ico_ictl_mgr     *pIctlMgr;
238     struct ico_ictl_input   *pInput;
239     struct ico_app_mgr      *pAppMgr;
240
241     uifw_trace("ico_mgr_add_input_app: Enter(appid=%s,dev=%s,input=%d,fix=%d,key=%d)",
242                appid, device, input, fix, keycode);
243
244     pIctlMgr = find_ictlmgr_by_device(device);
245     if (! pIctlMgr) {
246         /* not configure input controller, create   */
247         ico_device_configure_input(NULL, NULL, device, 0, NULL, input, NULL, 0);
248         pIctlMgr = find_ictlmgr_by_device(device);
249         if (! pIctlMgr) {
250             uifw_error("ico_mgr_add_input_app: Leave(No Memory)");
251             return;
252         }
253     }
254     pInput = find_ictlinput_by_input(pIctlMgr, input);
255     if (! pInput)   {
256         /* not configure input switch, create   */
257         ico_device_configure_input(NULL, NULL, device, 0, NULL, input, NULL, 0);
258         pInput = find_ictlinput_by_input(pIctlMgr, input);
259         if (! pInput)   {
260             uifw_error("ico_mgr_add_input_app: Leave(No Memory)");
261             return;
262         }
263     }
264
265     /* find application         */
266     pAppMgr = find_app_by_appid(appid);
267     if (! pAppMgr)  {
268         /* create Application Management Table  */
269         pAppMgr = (struct ico_app_mgr *)malloc(sizeof(struct ico_app_mgr));
270         if (! pAppMgr)  {
271             uifw_error("ico_mgr_add_input_app: Leave(No Memory)");
272             return;
273         }
274         memset(pAppMgr, 0, sizeof(struct ico_app_mgr));
275         strncpy(pAppMgr->appid, appid, sizeof(pAppMgr->appid)-1);
276         wl_list_insert(pInputMgr->app_list.prev, &pAppMgr->link);
277     }
278
279     pInput->app = pAppMgr;
280     pInput->fix = fix;
281     uifw_trace("ico_mgr_add_input_app: Leave(%s.%s[%d] assign to %s)",
282                pIctlMgr->device, pInput->swname ? pInput->swname : "(NULL)", input,
283                pAppMgr->appid);
284 }
285
286 /*--------------------------------------------------------------------------*/
287 /**
288  * @brief   ico_mgr_del_input_app: delete input event at application from HomeScreen.
289  *
290  * @param[in]   client          client(HomeScreen)
291  * @param[in]   resource        resource of request
292  * @param[in]   appid           target application id,
293  *                              if NULL, all applictions without fixed assign switch
294  * @param[in]   device          device name
295  *                              if NULL, all device without fixed assign switch
296  * @param[in]   input           input switch number
297  *                              if -1, all input without fixed assign switch
298  * @return      none
299  */
300 /*--------------------------------------------------------------------------*/
301 static void
302 ico_mgr_del_input_app(struct wl_client *client, struct wl_resource *resource,
303                       const char *appid, const char *device, int32_t input)
304 {
305     int     alldev = 0;
306     struct ico_ictl_mgr     *pIctlMgr = NULL;
307     struct ico_ictl_input   *pInput = NULL;
308     struct ico_app_mgr      *pAppMgr;
309
310     uifw_trace("ico_mgr_del_input_app: Enter(appid=%s,dev=%s,input=%d)",
311                appid ? appid : "(NULL)", device ? device : "(NULL)", input);
312
313     if ((device != NULL) && (*device != 0)) {
314         pIctlMgr = find_ictlmgr_by_device(device);
315         if (! pIctlMgr) {
316             /* not configure input controller, NOP  */
317             uifw_trace("ico_mgr_del_input_app: Leave(%s dose not exist)", device);
318             return;
319         }
320         if (input >= 0) {
321             pInput = find_ictlinput_by_input(pIctlMgr, input);
322             if (! pInput)   {
323                 /* not configure input switch, NOP  */
324                 uifw_trace("ico_mgr_del_input_app: Leave(%s.%d dose not exist)",
325                            device, input);
326                 return;
327             }
328         }
329     }
330     else    {
331         alldev = 1;
332     }
333
334     /* find application         */
335     if ((appid != NULL) && (*appid != 0))   {
336         pAppMgr = find_app_by_appid(appid);
337         if (! pAppMgr)  {
338             /* application dose not exist, NOP  */
339             uifw_trace("ico_mgr_del_input_app: Leave(app.%s dose not exist)", appid);
340             return;
341         }
342         if (alldev == 0)    {
343             if (input >= 0) {
344                 if (pInput->app != pAppMgr) {
345                     /* not same application, NOP        */
346                     uifw_trace("ico_mgr_del_input_app: Leave(%s.%d not app.%s, current %s)",
347                                device, input, appid,
348                                pInput->app ? pInput->app->appid : "(NULL)");
349                     return;
350                 }
351                 uifw_trace("ico_mgr_del_input_app: Leave(%s.%d app.%s deleted)",
352                            device, input, appid);
353                 pInput->app = NULL;
354                 return;
355             }
356             else    {
357                 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
358                     if ((pInput->fix == 0) && (pInput->app == pAppMgr))   {
359                         uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
360                                    pIctlMgr->device, pInput->input, appid);
361                         pInput->app = NULL;
362                     }
363                 }
364             }
365         }
366         else    {
367             /* reset all device without fixed assign    */
368             wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)    {
369                 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
370                     if ((pInput->fix == 0) && (pInput->app == pAppMgr))   {
371                         uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
372                                    pIctlMgr->device, pInput->input, pInput->app->appid);
373                         pInput->app = NULL;
374                     }
375                 }
376             }
377         }
378     }
379     else    {
380         if (alldev == 0)    {
381             if (input >= 0) {
382                 if ((pInput->fix == 0) && (pInput->app != NULL))    {
383                     uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
384                                pIctlMgr->device, pInput->input, pInput->app->appid);
385                     pInput->app = NULL;
386                 }
387             }
388             else    {
389                 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
390                     if ((pInput->fix == 0) && (pInput->app != NULL))    {
391                         uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
392                                pIctlMgr->device, pInput->input, pInput->app->appid);
393                         pInput->app = NULL;
394                     }
395                 }
396             }
397         }
398         else    {
399             /* reset all application without fixed assign       */
400             wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)    {
401                 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
402                     if ((pInput->fix == 0) && (pInput->app != NULL))    {
403                         uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
404                                    pIctlMgr->device, pInput->input, pInput->app->appid);
405                         pInput->app = NULL;
406                     }
407                 }
408             }
409         }
410     }
411     uifw_trace("ico_mgr_del_input_app: Leave");
412 }
413
414 /*--------------------------------------------------------------------------*/
415 /**
416  * @brief   ico_mgr_send_key_event: send key input event from device input controller
417  *
418  * @param[in]   client          client(HomeScreen)
419  * @param[in]   resource        resource of request
420  * @param[in]   target          target window name and application id
421  * @param[in]   code            event code
422  * @param[in]   value           event value
423  * @return      none
424  */
425 /*--------------------------------------------------------------------------*/
426 static void
427 ico_mgr_send_key_event(struct wl_client *client, struct wl_resource *resource,
428                        const char *target, int32_t code, int32_t value)
429 {
430     struct uifw_win_surface *usurf;         /* UIFW surface                 */
431     struct wl_resource      *cres;          /* event send client resource   */
432     struct wl_array dummy_array;            /* dummy array for wayland API  */
433     uint32_t    ctime;                      /* current time(ms)             */
434     uint32_t    serial;                     /* event serial number          */
435     int         keyboard_active;            /* keyborad active surface flag */
436
437     uifw_trace("ico_mgr_send_key_event: Enter(target=%s code=%x value=%d)",
438                target ? target : "(NULL)", code, value);
439
440     if (! pInputMgr->seat->keyboard)    {
441         uifw_error("ico_mgr_send_key_event: Leave(system has no keyboard)");
442         return;
443     }
444
445     ctime = weston_compositor_get_time();
446
447     if ((target == NULL) || (*target == 0) || (*target == ' ')) {
448         /* send event to surface via weston */
449
450         uifw_trace("ico_mgr_send_key_event: notify_key(%d,%d)", code, value);
451         notify_key(pInputMgr->seat, ctime, code,
452                    value ? WL_KEYBOARD_KEY_STATE_PRESSED :
453                            WL_KEYBOARD_KEY_STATE_RELEASED, STATE_UPDATE_NONE);
454     }
455     else    {
456         /* send event to fixed application  */
457         /* get application surface       */
458         usurf = ico_window_mgr_get_client_usurf(target);
459         if (! usurf)  {
460             uifw_trace("ico_mgr_send_key_event: Leave(window=%s dose not exist)",
461                        target);
462             return;
463         }
464
465         /* send event                   */
466         cres = wl_resource_find_for_client(
467                             &pInputMgr->seat->keyboard->resource_list,
468                             wl_resource_get_client(usurf->surface->resource));
469         if (cres)   {
470             if (pInputMgr->seat->keyboard->focus == usurf->surface) {
471                 keyboard_active = 1;
472             }
473             else    {
474                 keyboard_active = 0;
475             }
476             if (! keyboard_active)  {
477                 wl_array_init(&dummy_array);
478                 serial = wl_display_next_serial(pInputMgr->compositor->wl_display);
479                 wl_keyboard_send_enter(cres, serial,
480                                        usurf->surface->resource, &dummy_array);
481             }
482             serial = wl_display_next_serial(pInputMgr->compositor->wl_display);
483             uifw_trace("ico_mgr_send_key_event: send Key (%d, %d) to %08x",
484                        code, value, usurf->surfaceid);
485             wl_keyboard_send_key(cres, serial, ctime, code,
486                                  value ? WL_KEYBOARD_KEY_STATE_PRESSED :
487                                          WL_KEYBOARD_KEY_STATE_RELEASED);
488            if (! keyboard_active)  {
489                 serial = wl_display_next_serial(pInputMgr->compositor->wl_display);
490                 wl_keyboard_send_leave(cres, serial, usurf->surface->resource);
491             }
492         }
493         else    {
494             uifw_trace("ico_mgr_send_key_event: Key client %08x dose not exist",
495                        (int)usurf->surface->resource);
496         }
497     }
498     uifw_debug("ico_mgr_send_key_event: Leave");
499 }
500
501 /*--------------------------------------------------------------------------*/
502 /**
503  * @brief   ico_mgr_set_input_region: set input region for haptic devcie
504  *
505  * @param[in]   client          client(Device Input Controller)
506  * @param[in]   resource        resource of request
507  * @param[in]   target          target window (winname@appid)
508  * @param[in]   x               input region X coordinate
509  * @param[in]   y               input region X coordinate
510  * @param[in]   width           input region width
511  * @param[in]   height          input region height
512  * @param[in]   hotspot_x       hotspot of X relative coordinate
513  * @param[in]   hotspot_y       hotspot of Y relative coordinate
514  * @param[in]   cursor_x        cursor region X coordinate
515  * @param[in]   cursor_y        cursor region X coordinate
516  * @param[in]   cursor_width    cursor region width
517  * @param[in]   cursor_height   cursor region height
518  * @param[in]   attr            region attributes(currently unused)
519  * @return      none
520  */
521 /*--------------------------------------------------------------------------*/
522 static void
523 ico_mgr_set_input_region(struct wl_client *client, struct wl_resource *resource,
524                          const char *target, int32_t x, int32_t y,
525                          int32_t width, int32_t height, int32_t hotspot_x,
526                          int32_t hotspot_y, int32_t cursor_x, int32_t cursor_y,
527                          int32_t cursor_width, int32_t cursor_height, uint32_t attr)
528 {
529     struct uifw_win_surface *usurf;         /* UIFW surface                 */
530
531     uifw_trace("ico_mgr_set_input_region: Enter(%s %d/%d-%d/%d(%d/%d) %d/%d-%d/%d)",
532                target, x, y, width, height, hotspot_x, hotspot_y,
533                cursor_x, cursor_y, cursor_width, cursor_height);
534
535     /* get target surface           */
536     usurf = ico_window_mgr_get_client_usurf(target);
537     if (! usurf)    {
538         uifw_warn("ico_mgr_set_input_region: Leave(target<%s> dose not exist)", target);
539         return;
540     }
541
542     ico_set_input_region(1, usurf, x, y, width, height, hotspot_x, hotspot_y,
543                          cursor_x, cursor_y, cursor_width, cursor_height, attr);
544
545     uifw_trace("ico_mgr_set_input_region: Leave");
546 }
547
548 /*--------------------------------------------------------------------------*/
549 /**
550  * @brief   ico_mgr_unset_input_region: unset input region for haptic devcie
551  *
552  * @param[in]   client          client(Device Input Controller)
553  * @param[in]   resource        resource of request
554  * @param[in]   target          target window (winname@appid)
555  * @param[in]   x               input region X coordinate
556  * @param[in]   y               input region X coordinate
557  * @param[in]   width           input region width
558  * @param[in]   height          input region height
559  * @return      none
560  */
561 /*--------------------------------------------------------------------------*/
562 static void
563 ico_mgr_unset_input_region(struct wl_client *client, struct wl_resource *resource,
564                            const char *target, int32_t x, int32_t y,
565                            int32_t width, int32_t height)
566 {
567     struct uifw_win_surface *usurf;         /* UIFW surface                 */
568
569     uifw_trace("ico_mgr_unset_input_region: Enter(%s %d/%d-%d/%d)",
570                target, x, y, width, height);
571
572     /* get target surface           */
573     usurf = ico_window_mgr_get_client_usurf(target);
574     if (! usurf)    {
575         uifw_warn("ico_mgr_unset_input_region: Leave(target<%s> dose not exist)", target);
576         return;
577     }
578
579     ico_set_input_region(0, usurf, x, y, width, height, 0, 0, 0, 0, 0, 0, 0);
580
581     uifw_trace("ico_mgr_unset_input_region: Leave");
582 }
583
584 /*--------------------------------------------------------------------------*/
585 /**
586  * @brief   ico_input_hook_region_change: change surface attribute
587  *
588  * @param[in]   usurf           UIFW surface
589  * @return      none
590  */
591 /*--------------------------------------------------------------------------*/
592 static void
593 ico_input_hook_region_change(struct uifw_win_surface *usurf)
594 {
595     struct uifw_region_mng      *p;         /* input region mamagement table*/
596     struct ico_uifw_input_region *rp;       /* input region                 */
597     struct wl_array             array;
598     int                         chgcount = 0;
599     int                         visible;
600
601     uifw_trace("ico_input_hook_region_change: Entery(surf=%08x)", usurf->surfaceid);
602
603     wl_array_init(&array);
604
605     visible = /* get visiblety form weston_layout */ 0;
606
607     wl_list_for_each(p, &usurf->input_region, link) {
608         if (((p->region.change > 0) && (visible <= 0)) ||
609             ((p->region.change <= 0) && (visible > 0))) {
610             /* visible change, send add/remove event    */
611             rp = (struct ico_uifw_input_region *)
612                  wl_array_add(&array, sizeof(struct ico_uifw_input_region));
613             if (rp) {
614                 chgcount ++;
615                 memcpy(rp, &p->region, sizeof(struct ico_uifw_input_region));
616                 if (visible > 0)    {
617                     rp->change = ICO_INPUT_MGR_DEVICE_REGION_ADD;
618                 }
619                 else    {
620                     rp->change = ICO_INPUT_MGR_DEVICE_REGION_REMOVE;
621                 }
622             }
623             p->region.change = visible;
624             p->region.node = usurf->node_tbl->node;
625             p->region.surface_x = usurf->x;
626             p->region.surface_y = usurf->y;
627         }
628         else if ((p->region.node != usurf->node_tbl->node) ||
629                  (p->region.surface_x != usurf->x) ||
630                  (p->region.surface_y != usurf->y)) {
631             /* surface position change, send change event   */
632             p->region.node = usurf->node_tbl->node;
633             p->region.surface_x = usurf->x;
634             p->region.surface_y = usurf->y;
635
636             rp = (struct ico_uifw_input_region *)
637                  wl_array_add(&array, sizeof(struct ico_uifw_input_region));
638             if (rp) {
639                 chgcount ++;
640                 memcpy(rp, &p->region, sizeof(struct ico_uifw_input_region));
641                 rp->change = ICO_INPUT_MGR_DEVICE_REGION_CHANGE;
642             }
643         }
644     }
645     if (chgcount > 0)   {
646         /* send region delete to haptic device input controller */
647         ico_input_send_region_event(&array);
648     }
649     uifw_trace("ico_input_hook_region_change: Leave");
650 }
651
652 /*--------------------------------------------------------------------------*/
653 /**
654  * @brief   ico_input_hook_region_destroy: destory surface
655  *
656  * @param[in]   usurf           UIFW surface
657  * @return      none
658  */
659 /*--------------------------------------------------------------------------*/
660 static void
661 ico_input_hook_region_destroy(struct uifw_win_surface *usurf)
662 {
663     struct uifw_region_mng      *p;         /* input region mamagement table*/
664     struct uifw_region_mng      *np;        /* next region mamagement table */
665     struct ico_uifw_input_region *rp;       /* input region                 */
666     struct wl_array             array;
667     int                         delcount = 0;
668
669     uifw_trace("ico_input_hook_region_destroy: Entery(surf=%08x)", usurf->surfaceid);
670
671     wl_array_init(&array);
672
673     wl_list_for_each_safe(p, np, &usurf->input_region, link)    {
674         if (p->region.change > 0)   {
675             /* visible, send remove event   */
676             rp = (struct ico_uifw_input_region *)
677                  wl_array_add(&array, sizeof(struct ico_uifw_input_region));
678             if (rp) {
679                 delcount ++;
680                 memcpy(rp, &p->region, sizeof(struct ico_uifw_input_region));
681                 rp->change = ICO_INPUT_MGR_DEVICE_REGION_REMOVE;
682             }
683         }
684         wl_list_remove(&p->link);
685         wl_list_insert(pInputMgr->free_region.prev, &p->link);
686     }
687     if (delcount > 0)   {
688         /* send region delete to haptic device input controller */
689         ico_input_send_region_event(&array);
690     }
691     uifw_trace("ico_input_hook_region_destroy: Leave");
692 }
693
694 /*--------------------------------------------------------------------------*/
695 /**
696  * @brief   ico_set_input_region: input region set/unset
697  *
698  * @param[in]   set             set(1)/unset(0)
699  * @param[in]   usurf           UIFW surface
700  * @param[in]   x               input region X coordinate
701  * @param[in]   y               input region X coordinate
702  * @param[in]   width           input region width
703  * @param[in]   height          input region height
704  * @param[in]   hotspot_x       hotspot of X relative coordinate
705  * @param[in]   hotspot_y       hotspot of Y relative coordinate
706  * @param[in]   cursor_x        cursor region X coordinate
707  * @param[in]   cursor_y        cursor region X coordinate
708  * @param[in]   cursor_width    cursor region width
709  * @param[in]   cursor_height   cursor region height
710  * @param[in]   attr            region attributes(currently unused)
711  * @return      none
712  */
713 /*--------------------------------------------------------------------------*/
714 static void
715 ico_set_input_region(int set, struct uifw_win_surface *usurf,
716                      int32_t x, int32_t y, int32_t width, int32_t height,
717                      int32_t hotspot_x, int32_t hotspot_y, int32_t cursor_x, int32_t cursor_y,
718                      int32_t cursor_width, int32_t cursor_height, uint32_t attr)
719 {
720     struct uifw_region_mng      *p;         /* input region mamagement table*/
721     struct uifw_region_mng      *np;        /* next region mamagement table */
722     struct ico_uifw_input_region *rp;       /* input region                 */
723     struct wl_array             array;
724     int                         i;
725     int                         alldel;
726     int                         delcount;
727
728     uifw_trace("ico_set_input_region: Enter(%s %d/%d-%d/%d(%d/%d) %d/%d-%d/%d)",
729                set ? "Set" : "Unset", x, y, width, height, hotspot_x, hotspot_y,
730                cursor_x, cursor_y, cursor_width, cursor_height);
731
732     if (set)    {
733         if (wl_list_empty(&pInputMgr->free_region)) {
734             p = malloc(sizeof(struct uifw_region_mng) * 50);
735             if (! p)    {
736                 uifw_error("ico_set_input_region: No Memory");
737                 return;
738             }
739             memset(p, 0, sizeof(struct uifw_region_mng)*50);
740             for (i = 0; i < 50; i++, p++)  {
741                 wl_list_insert(pInputMgr->free_region.prev, &p->link);
742             }
743         }
744         p = container_of(pInputMgr->free_region.next, struct uifw_region_mng, link);
745         wl_list_remove(&p->link);
746         p->region.node = usurf->node_tbl->node;
747         p->region.surfaceid = usurf->surfaceid;
748         p->region.surface_x = usurf->x;
749         p->region.surface_y = usurf->y;
750         p->region.x = x;
751         p->region.y = y;
752         p->region.width = width;
753         p->region.height = height;
754         if ((hotspot_x <= 0) && (hotspot_y <= 0))   {
755             p->region.hotspot_x = width / 2;
756             p->region.hotspot_y = height / 2;
757         }
758         else    {
759             p->region.hotspot_x = hotspot_x;
760             p->region.hotspot_y = hotspot_y;
761         }
762         if ((cursor_width <= 0) && (cursor_height <= 0))    {
763             p->region.cursor_x = x;
764             p->region.cursor_y = y;
765             p->region.cursor_width = width;
766             p->region.cursor_height = height;
767         }
768         else    {
769             p->region.cursor_x = cursor_x;
770             p->region.cursor_y = cursor_y;
771             p->region.cursor_width = cursor_width;
772             p->region.cursor_height = cursor_height;
773         }
774         p->region.change = /* get form weston_layout */ 1;
775         wl_list_insert(usurf->input_region.prev, &p->link);
776
777         /* send input region to haptic device input controller  */
778         if (p->region.change > 0)   {
779             wl_array_init(&array);
780             rp = (struct ico_uifw_input_region *)
781                      wl_array_add(&array, sizeof(struct ico_uifw_input_region));
782             if (rp) {
783                 memcpy(rp, &p->region, sizeof(struct ico_uifw_input_region));
784                 rp->change = ICO_INPUT_MGR_DEVICE_REGION_ADD;
785                 ico_input_send_region_event(&array);
786             }
787             uifw_trace("ico_set_input_region: Leave(Set)");
788         }
789         else    {
790             uifw_trace("ico_set_input_region: Leave(Set but Unvisible)");
791         }
792     }
793     else    {
794         delcount = 0;
795
796         if ((x <= 0) && (y <= 0) && (width <= 0) && (height <= 0))  {
797             alldel = 1;
798         }
799         else    {
800             alldel = 0;
801         }
802
803         wl_array_init(&array);
804
805         wl_list_for_each_safe(p, np, &usurf->input_region, link)    {
806             if ((alldel != 0) ||
807                 ((x == p->region.x) && (y == p->region.y) &&
808                  (width == p->region.width) && (height == p->region.height)))   {
809                 if (p->region.change > 0)   {
810                     /* visible, send remove event   */
811                     rp = (struct ico_uifw_input_region *)
812                          wl_array_add(&array, sizeof(struct ico_uifw_input_region));
813                     if (rp) {
814                         delcount ++;
815                         memcpy(rp, &p->region, sizeof(struct ico_uifw_input_region));
816                         rp->change = ICO_INPUT_MGR_DEVICE_REGION_REMOVE;
817                     }
818                 }
819                 wl_list_remove(&p->link);
820                 wl_list_insert(pInputMgr->free_region.prev, &p->link);
821             }
822         }
823         if (delcount > 0)   {
824             /* send region delete to haptic device input controller */
825             ico_input_send_region_event(&array);
826         }
827         uifw_trace("ico_set_input_region: Leave(Unset)");
828     }
829 }
830
831 /*--------------------------------------------------------------------------*/
832 /**
833  * @brief   ico_input_send_region_event: send region event to Haptic dic
834  *
835  * @param[in]   usurf           UIFW surface
836  * @return      none
837  */
838 /*--------------------------------------------------------------------------*/
839 static void
840 ico_input_send_region_event(struct wl_array *array)
841 {
842     struct ico_ictl_mgr     *pIctlMgr;
843
844     wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)   {
845         if ((pIctlMgr->type == ICO_INPUT_MGR_DEVICE_TYPE_HAPTIC) &&
846             (pIctlMgr->mgr_resource != NULL))   {
847             uifw_trace("ico_input_send_region_event: send event to Hapfic");
848             ico_input_mgr_device_send_input_regions(pIctlMgr->mgr_resource, array);
849         }
850     }
851 }
852
853 /*--------------------------------------------------------------------------*/
854 /**
855  * @brief   ico_device_configure_input: configure input device and input switch
856  *          from Device Input Controller.
857  *
858  * @param[in]   client          client(Device Input Controller)
859  * @param[in]   resource        resource of request
860  * @param[in]   device          device name
861  * @param[in]   type            device type(saved but unused)
862  * @param[in]   swname          input switch name
863  * @param[in]   input           input switch number
864  * @param[in]   codename        input code name
865  * @param[in]   code            input code number
866  * @return      none
867  */
868 /*--------------------------------------------------------------------------*/
869 static void
870 ico_device_configure_input(struct wl_client *client, struct wl_resource *resource,
871                            const char *device, int32_t type, const char *swname,
872                            int32_t input, const char *codename, int32_t code)
873 {
874     struct ico_ictl_mgr     *pIctlMgr;
875     struct ico_ictl_mgr     *psameIctlMgr;
876     struct ico_ictl_input   *pInput;
877     struct ico_app_mgr      *pAppMgr;
878
879     uifw_trace("ico_device_configure_input: Enter(client=%08x,dev=%s,type=%d,swname=%s,"
880                "input=%d,code=%d[%s])", (int)client, device, type,
881                swname ? swname : "(NULL)", input, code, codename ? codename : " ");
882
883     pIctlMgr = find_ictlmgr_by_device(device);
884     if (! pIctlMgr) {
885         /* search binded table      */
886         psameIctlMgr = NULL;
887         wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)    {
888             if (pIctlMgr->client == client) {
889                 uifw_trace("ico_device_configure_input: set pIctlMgr"
890                            "(mgr=%08x,input=%d,dev=%s)", (int)pIctlMgr,
891                            input, pIctlMgr->device);
892                 if (pIctlMgr->device[0] != 0)   {
893                     /* save same device         */
894                     psameIctlMgr = pIctlMgr;
895                 }
896                 else    {
897                     /* first device             */
898                     strncpy(pIctlMgr->device, device, sizeof(pIctlMgr->device)-1);
899                     psameIctlMgr = NULL;
900                     break;
901                 }
902             }
903         }
904         if (psameIctlMgr)   {
905             /* client(device input controller) exist, but other device  */
906             pIctlMgr = (struct ico_ictl_mgr *)malloc(sizeof(struct ico_ictl_mgr));
907             if (pIctlMgr == NULL) {
908                 uifw_error("ico_device_bind: Leave(No Memory)");
909                 return;
910             }
911             memset(pIctlMgr, 0, sizeof(struct ico_ictl_mgr));
912             wl_list_init(&pIctlMgr->ico_ictl_input);
913             pIctlMgr->client = psameIctlMgr->client;
914             pIctlMgr->mgr_resource = psameIctlMgr->mgr_resource;
915
916             wl_list_insert(pInputMgr->ictl_list.prev, &pIctlMgr->link);
917         }
918     }
919
920     if (type)   {
921         pIctlMgr->type = type;
922     }
923
924     /* search and add input switch  */
925     wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
926         if (pInput->input == input)     break;
927     }
928     if (&pInput->link == &pIctlMgr->ico_ictl_input)    {
929         uifw_trace("ico_device_configure_input: create %s.%s(%d) switch",
930                    device, swname, input);
931         pInput = (struct ico_ictl_input *)malloc(sizeof(struct ico_ictl_input));
932         if (pInput == NULL) {
933             uifw_error("ico_device_configure_input: Leave(No Memory)");
934             return;
935         }
936         memset(pInput, 0, sizeof(struct ico_ictl_input));
937         if (swname) {
938             strncpy(pInput->swname, swname, sizeof(pInput->swname)-1);
939         }
940         else    {
941             strcpy(pInput->swname, "(Unknown)");
942         }
943         wl_list_insert(pIctlMgr->ico_ictl_input.prev, &pInput->link);
944     }
945     if (swname) {
946         strncpy(pInput->swname, swname, sizeof(pInput->swname)-1);
947     }
948     pInput->input = input;
949     memset(pInput->code, 0, sizeof(pInput->code));
950     pInput->ncode = 1;
951     pInput->code[0].code = code;
952     if (codename)   {
953         strncpy(pInput->code[0].name, codename, sizeof(pInput->code[0].name)-1);
954     }
955
956     if (client == NULL) {
957         /* internal call for table create   */
958         uifw_trace("ico_device_configure_input: Leave(table create)");
959         return;
960     }
961     pIctlMgr->client = client;
962
963     /* send to application and manager(ex.HomeScreen)   */
964     wl_list_for_each (pAppMgr, &pInputMgr->app_list, link)  {
965         if (pAppMgr->resource == NULL)  continue;
966         if ((pInput->app != NULL) && (pInput->app != pAppMgr) && (pInput->fix)) continue;
967
968         uifw_trace("ico_device_configure_input: send capabilities to app(%s) %s.%s[%d]",
969                    pAppMgr->appid, device, pInput->swname, input);
970         ico_exinput_send_capabilities(pAppMgr->resource, device, pIctlMgr->type,
971                                       pInput->swname, input,
972                                       pInput->code[0].name, pInput->code[0].code);
973     }
974     uifw_trace("ico_device_configure_input: Leave");
975 }
976
977 /*--------------------------------------------------------------------------*/
978 /**
979  * @brief   ico_device_configure_code: add input switch from Device Input Controller.
980  *
981  * @param[in]   client          client(Device Input Controller)
982  * @param[in]   resource        resource of request
983  * @param[in]   device          device name
984  * @param[in]   input           input switch number
985  * @param[in]   codename        input code name
986  * @param[in]   code            input code number
987  * @return      none
988  */
989 /*--------------------------------------------------------------------------*/
990 static void
991 ico_device_configure_code(struct wl_client *client, struct wl_resource *resource,
992                           const char *device, int32_t input,
993                           const char *codename, int32_t code)
994 {
995     int     i;
996     struct ico_ictl_mgr     *pIctlMgr;
997     struct ico_ictl_input   *pInput;
998     struct ico_app_mgr      *pAppMgr;
999
1000     uifw_trace("ico_device_configure_code: Enter(client=%08x,dev=%s,input=%d,code=%d[%s])",
1001                (int)client, device, input, code, codename ? codename : " ");
1002
1003     pIctlMgr = find_ictlmgr_by_device(device);
1004     if (! pIctlMgr) {
1005         uifw_warn("ico_device_configure_code: Leave(dev=%s dose not exist)", device);
1006         return;
1007     }
1008     /* search input switch      */
1009     wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
1010         if (pInput->input == input)     break;
1011     }
1012     if (&pInput->link == &pIctlMgr->ico_ictl_input)    {
1013         uifw_warn("ico_device_configure_code: Leave(input=%s.%d dose not exist)",
1014                   device, input);
1015         return;
1016     }
1017
1018     /* search input code        */
1019     for (i = 0; i < pInput->ncode; i++) {
1020         if (pInput->code[i].code == code)   break;
1021     }
1022     if (i >= pInput->ncode) {
1023         /* code dose not exist, add */
1024         if (pInput->ncode >= ICO_MINPUT_MAX_CODES) {
1025             uifw_warn("ico_device_configure_code: Leave(input=%s.%d code overflow)",
1026                       device, input);
1027             return;
1028         }
1029         i = pInput->ncode;
1030         pInput->ncode ++;
1031         pInput->code[i].code = code;
1032     }
1033     memset(pInput->code[i].name, 0, sizeof(pInput->code[i].name));
1034     strncpy(pInput->code[i].name, codename, sizeof(pInput->code[i].name)-1);
1035
1036     /* send to application and manager(ex.HomeScreen)   */
1037     wl_list_for_each (pAppMgr, &pInputMgr->app_list, link)  {
1038         if (pAppMgr->resource == NULL)  continue;
1039         if ((pInput->app != NULL) && (pInput->app != pAppMgr) && (pInput->fix)) continue;
1040         uifw_trace("ico_device_configure_input: send code to app(%s) %s.%s[%d]",
1041                    pAppMgr->appid, device, pInput->swname, input);
1042         ico_exinput_send_code(pAppMgr->resource, device, input,
1043                               pInput->code[i].name, pInput->code[i].code);
1044     }
1045     uifw_trace("ico_device_configure_code: Leave");
1046 }
1047
1048 /*--------------------------------------------------------------------------*/
1049 /**
1050  * @brief   ico_device_input_event: device input event from Device Input Controller.
1051  *
1052  * @param[in]   client          client(Device Input Controller)
1053  * @param[in]   resource        resource of request
1054  * @param[in]   time            device input time(miri-sec)
1055  * @param[in]   device          device name
1056  * @param[in]   input           input switch number
1057  * @param[in]   code            input code number
1058  * @param[in]   state           input state(1=On, 0=Off)
1059  * @return      none
1060  */
1061 /*--------------------------------------------------------------------------*/
1062 static void
1063 ico_device_input_event(struct wl_client *client, struct wl_resource *resource,
1064                        uint32_t time, const char *device,
1065                        int32_t input, int32_t code, int32_t state)
1066 {
1067     struct ico_ictl_mgr     *pIctlMgr;
1068     struct ico_ictl_input   *pInput;
1069
1070     uifw_trace("ico_device_input_event: Enter(time=%d,dev=%s,input=%d,code=%d,state=%d)",
1071                time, device, input, code, state);
1072
1073     /* find input devcie by client      */
1074     pIctlMgr = find_ictlmgr_by_device(device);
1075     if (! pIctlMgr) {
1076         uifw_error("ico_device_input_event: Leave(Unknown device(%s))", device);
1077         return;
1078     }
1079     /* find input switch by input Id    */
1080     pInput = find_ictlinput_by_input(pIctlMgr, input);
1081     if (! pInput) {
1082         uifw_warn("ico_device_input_event: Leave(Unknown input(%s,%d))",
1083                   pIctlMgr->device, input);
1084         return;
1085     }
1086
1087     if (! pInput->app)  {
1088         uifw_trace("ico_device_input_event: Leave(%s.%s not assign)",
1089                   pIctlMgr->device, pInput->swname);
1090         return;
1091     }
1092     if (! pInput->app->resource) {
1093         uifw_trace("ico_device_input_event: Leave(%s.%s assigned App.%s "
1094                    "is not running or not interested)",
1095                    pIctlMgr->device, pInput->swname, pInput->app->appid);
1096         return;
1097     }
1098
1099     /* send event to application        */
1100     uifw_trace("ico_device_input_event: send event=%s.%s[%d],%d,%d to App.%s",
1101                pIctlMgr->device, pInput->swname, input, code, state, pInput->app->appid);
1102     ico_exinput_send_input(pInput->app->resource, time, pIctlMgr->device,
1103                            input, code, state);
1104
1105     uifw_trace("ico_device_input_event: Leave");
1106 }
1107
1108 /*--------------------------------------------------------------------------*/
1109 /**
1110  * @brief   ico_control_bind: ico_input_mgr_control bind from HomeScreen
1111  *
1112  * @param[in]   client          client(HomeScreen)
1113  * @param[in]   data            data(unused)
1114  * @param[in]   version         protocol version(unused)
1115  * @param[in]   id              client object id
1116  * @return      none
1117  */
1118 /*--------------------------------------------------------------------------*/
1119 static void
1120 ico_control_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
1121 {
1122     char                    *appid;
1123     struct ico_app_mgr      *pAppMgr;
1124
1125     uifw_trace("ico_control_bind: Enter(client=%08x)", (int)client);
1126     appid = ico_window_mgr_get_appid(client);
1127
1128     if (! appid)    {
1129         /* client dose not exist        */
1130         uifw_warn("ico_control_bind: Leave(client=%08x dose not exist)", (int)client);
1131         return;
1132     }
1133
1134     /* find application         */
1135     pAppMgr = find_app_by_appid(appid);
1136     if (! pAppMgr)  {
1137         /* create Application Management Table  */
1138         pAppMgr = (struct ico_app_mgr *)malloc(sizeof(struct ico_app_mgr));
1139         if (! pAppMgr)  {
1140             uifw_error("ico_control_bind: Leave(No Memory)");
1141             return;
1142         }
1143         memset(pAppMgr, 0, sizeof(struct ico_app_mgr));
1144         strncpy(pAppMgr->appid, appid, sizeof(pAppMgr->appid)-1);
1145         wl_list_insert(pInputMgr->app_list.prev, &pAppMgr->link);
1146     }
1147     pAppMgr->client = client;
1148     if (! pAppMgr->mgr_resource)    {
1149         pAppMgr->mgr_resource = wl_resource_create(client,
1150                                                    &ico_input_mgr_control_interface, 1, id);
1151         if (pAppMgr->mgr_resource)  {
1152             wl_resource_set_implementation(pAppMgr->mgr_resource,
1153                                            &ico_input_mgr_implementation,
1154                                            pInputMgr, ico_control_unbind);
1155         }
1156     }
1157     uifw_trace("ico_control_bind: Leave");
1158 }
1159
1160 /*--------------------------------------------------------------------------*/
1161 /**
1162  * @brief   ico_control_unbind: ico_input_mgr_control unbind from HomeScreen
1163  *
1164  * @param[in]   resource        client resource(HomeScreen)
1165  * @return      none
1166  */
1167 /*--------------------------------------------------------------------------*/
1168 static void
1169 ico_control_unbind(struct wl_resource *resource)
1170 {
1171     struct ico_app_mgr  *pAppMgr;
1172
1173     uifw_trace("ico_control_unbind: Enter(resource=%08x)", (int)resource);
1174
1175     wl_list_for_each (pAppMgr, &pInputMgr->app_list, link)  {
1176         if (pAppMgr->mgr_resource == resource)  {
1177             uifw_trace("ico_control_unbind: find app.%s", pAppMgr->appid);
1178             pAppMgr->mgr_resource = NULL;
1179             break;
1180         }
1181     }
1182     uifw_trace("ico_control_unbind: Leave");
1183 }
1184
1185 /*--------------------------------------------------------------------------*/
1186 /**
1187  * @brief   ico_device_bind: ico_input_mgr_device bind from Device Input Controller
1188  *
1189  * @param[in]   client          client(Device Input Controller)
1190  * @param[in]   data            data(unused)
1191  * @param[in]   version         protocol version
1192  * @param[in]   id              client object id
1193  * @return      none
1194  */
1195 /*--------------------------------------------------------------------------*/
1196 static void
1197 ico_device_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
1198 {
1199     struct ico_ictl_mgr *pIctlMgr;
1200     struct wl_resource  *mgr_resource;
1201
1202     uifw_trace("ico_device_bind: Enter(client=%08x)", (int)client);
1203
1204     /* create ictl mgr table */
1205     pIctlMgr = (struct ico_ictl_mgr *)malloc(sizeof(struct ico_ictl_mgr));
1206     if (pIctlMgr == NULL) {
1207         uifw_error("ico_device_bind: Leave(No Memory)");
1208         return;
1209     }
1210     memset(pIctlMgr, 0, sizeof(struct ico_ictl_mgr));
1211     wl_list_init(&pIctlMgr->ico_ictl_input);
1212     pIctlMgr->client = client;
1213
1214     /* add list */
1215     wl_list_insert(pInputMgr->ictl_list.prev, &pIctlMgr->link);
1216
1217     mgr_resource = wl_resource_create(client, &ico_input_mgr_device_interface, 1, id);
1218     if (mgr_resource)   {
1219         pIctlMgr->mgr_resource = mgr_resource;
1220         wl_resource_set_implementation(mgr_resource, &input_mgr_ictl_implementation,
1221                                        pIctlMgr, ico_device_unbind);
1222     }
1223     uifw_trace("ico_device_bind: Leave");
1224 }
1225
1226 /*--------------------------------------------------------------------------*/
1227 /**
1228  * @brief   ico_device_unbind: ico_input_mgr_device unbind from Device Input Controller
1229  *
1230  * @param[in]   resource        client resource(Device Input Controller)
1231  * @return      none
1232  */
1233 /*--------------------------------------------------------------------------*/
1234 static void
1235 ico_device_unbind(struct wl_resource *resource)
1236 {
1237     uifw_trace("ico_device_unbind: Enter(resource=%08x)", (int)resource);
1238     uifw_trace("ico_device_unbind: Leave");
1239 }
1240
1241 /*--------------------------------------------------------------------------*/
1242 /**
1243  * @brief   ico_exinput_bind: ico_exinput bind from Application
1244  *
1245  * @param[in]   client          client(Application)
1246  * @param[in]   data            data(unused)
1247  * @param[in]   version         protocol version(unused)
1248  * @param[in]   id              client object id
1249  * @return      none
1250  */
1251 /*--------------------------------------------------------------------------*/
1252 static void
1253 ico_exinput_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
1254 {
1255     int                     i;
1256     char                    *appid;
1257     struct ico_app_mgr      *pAppMgr;
1258     struct ico_ictl_mgr     *pIctlMgr;
1259     struct ico_ictl_input   *pInput;
1260
1261     appid = ico_window_mgr_get_appid(client);
1262     uifw_trace("ico_exinput_bind: Enter(client=%08x,%s)", (int)client,
1263                appid ? appid : "(NULL)");
1264
1265     if (! appid)    {
1266         /* client dose not exist        */
1267         uifw_warn("ico_exinput_bind: Leave(client=%08x dose not exist)", (int)client);
1268         return;
1269     }
1270
1271     /* find application         */
1272     pAppMgr = find_app_by_appid(appid);
1273     if (! pAppMgr)  {
1274         /* create Application Management Table  */
1275         pAppMgr = (struct ico_app_mgr *)malloc(sizeof(struct ico_app_mgr));
1276         if (! pAppMgr)  {
1277             uifw_error("ico_exinput_bind: Leave(No Memory)");
1278             return;
1279         }
1280         memset(pAppMgr, 0, sizeof(struct ico_app_mgr));
1281         strncpy(pAppMgr->appid, appid, sizeof(pAppMgr->appid)-1);
1282         wl_list_insert(pInputMgr->app_list.prev, &pAppMgr->link);
1283         uifw_trace("ico_exinput_bind: Create App.%s table", appid);
1284     }
1285     pAppMgr->client = client;
1286     if (! pAppMgr->resource)    {
1287         pAppMgr->resource = wl_resource_create(client, &ico_exinput_interface, 1, id);
1288         if (pAppMgr->resource)  {
1289             wl_resource_set_implementation(pAppMgr->resource, &ico_exinput_implementation,
1290                                            pInputMgr, ico_exinput_unbind);
1291         }
1292     }
1293
1294     /* send all capabilities    */
1295     wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)    {
1296         if (pIctlMgr->client == NULL)   {
1297             uifw_trace("ico_exinput_bind: Input controller.%s not initialized",
1298                        pIctlMgr->device);
1299             continue;
1300         }
1301
1302         wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
1303             if (pInput->swname[0] == 0) {
1304                 uifw_trace("ico_exinput_bind: Input %s not initialized", pIctlMgr->device);
1305                 continue;
1306             }
1307             if ((pInput->app != NULL) && (pInput->app != pAppMgr) && (pInput->fix)) {
1308                 uifw_trace("ico_exinput_bind: Input %s.%s fixed assign to App.%s",
1309                            pIctlMgr->device, pInput->swname, pInput->app->appid);
1310                 continue;
1311             }
1312             uifw_trace("ico_exinput_bind: send capabilities to app(%s) %s.%s[%d]",
1313                        pAppMgr->appid, pIctlMgr->device, pInput->swname, pInput->input);
1314             ico_exinput_send_capabilities(pAppMgr->resource, pIctlMgr->device,
1315                                           pIctlMgr->type, pInput->swname, pInput->input,
1316                                           pInput->code[0].name, pInput->code[0].code);
1317             for (i = 1; i < pInput->ncode; i++) {
1318                 ico_exinput_send_code(pAppMgr->resource, pIctlMgr->device, pInput->input,
1319                                       pInput->code[i].name, pInput->code[i].code);
1320             }
1321         }
1322     }
1323     uifw_trace("ico_exinput_bind: Leave");
1324 }
1325
1326 /*--------------------------------------------------------------------------*/
1327 /**
1328  * @brief   ico_exinput_unbind: ico_exinput unbind from Application
1329  *
1330  * @param[in]   resource        client resource(Application)
1331  * @return      none
1332  */
1333 /*--------------------------------------------------------------------------*/
1334 static void
1335 ico_exinput_unbind(struct wl_resource *resource)
1336 {
1337     struct ico_app_mgr      *pAppMgr;
1338     struct ico_app_mgr      *pAppMgrTmp;
1339     struct ico_ictl_mgr     *pIctlMgr;
1340     struct ico_ictl_input   *pInput;
1341     int                     fix = 0;
1342
1343     uifw_trace("ico_exinput_unbind: Enter(resource=%08x)", (int)resource);
1344
1345     wl_list_for_each_safe (pAppMgr, pAppMgrTmp, &pInputMgr->app_list, link) {
1346         if (pAppMgr->resource == resource)  {
1347             uifw_trace("ico_exinput_unbind: find app.%s", pAppMgr->appid);
1348
1349             /* release application from input switch    */
1350             wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)    {
1351                 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
1352                     if (pInput->app == pAppMgr) {
1353                         if (pInput->fix == 0)   {
1354                             uifw_trace("ico_exinput_unbind: app.%s remove %s.%s",
1355                                        pAppMgr->appid, pIctlMgr->device, pInput->swname);
1356                             pInput->app = NULL;
1357                         }
1358                         else    {
1359                             uifw_trace("ico_exinput_unbind: app.%s fix assign %s.%s",
1360                                        pAppMgr->appid, pIctlMgr->device, pInput->swname);
1361                             fix ++;
1362                         }
1363                     }
1364                 }
1365             }
1366             if (fix == 0)   {
1367                 wl_list_remove(&pAppMgr->link);
1368                 free(pAppMgr);
1369             }
1370             else    {
1371                 pAppMgr->client = NULL;
1372                 pAppMgr->resource = NULL;
1373             }
1374         }
1375     }
1376     uifw_trace("ico_exinput_unbind: Leave");
1377 }
1378
1379 /*--------------------------------------------------------------------------*/
1380 /**
1381  * @brief   find_ictlmgr_by_device: find Input Controller by device name
1382  *
1383  * @param[in]   device          device name
1384  * @return      Input Controller Manager table address
1385  * @retval      !=NULL          address
1386  * @retval      ==NULL          not exist
1387  */
1388 /*--------------------------------------------------------------------------*/
1389 static struct ico_ictl_mgr *
1390 find_ictlmgr_by_device(const char *device)
1391 {
1392     struct ico_ictl_mgr     *pIctlMgr;
1393
1394     wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)    {
1395         uifw_debug("find_ictlmgr_by_device: <%s> vs <%s>", device, pIctlMgr->device);
1396         if (strcmp(pIctlMgr->device, device) == 0)  {
1397             return pIctlMgr;
1398         }
1399     }
1400     return NULL;
1401 }
1402
1403 /*--------------------------------------------------------------------------*/
1404 /**
1405  * @brief   find_ictlinput_by_input: find Input Switch by input Id
1406  *
1407  * @param[in]   pIctlMgr        Input Controller device
1408  * @param[in]   input           Input Id
1409  * @return      Input Switch table address
1410  * @retval      !=NULL          address
1411  * @retval      ==NULL          not exist
1412  */
1413 /*--------------------------------------------------------------------------*/
1414 static struct ico_ictl_input *
1415 find_ictlinput_by_input(struct ico_ictl_mgr *pIctlMgr, const int32_t input)
1416 {
1417     struct ico_ictl_input   *pInput;
1418
1419     wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
1420         if (pInput->input == input) {
1421             return pInput;
1422         }
1423     }
1424     return NULL;
1425 }
1426
1427 /*--------------------------------------------------------------------------*/
1428 /**
1429  * @brief   find_app_by_appid: find Application by application Id
1430  *
1431  * @param[in]   appid           application Id
1432  * @return      Application Management table address
1433  * @retval      !=NULL          address
1434  * @retval      ==NULL          not exist
1435  */
1436 /*--------------------------------------------------------------------------*/
1437 static struct ico_app_mgr *
1438 find_app_by_appid(const char *appid)
1439 {
1440     struct ico_app_mgr      *pAppMgr;
1441
1442     wl_list_for_each (pAppMgr, &pInputMgr->app_list, link)  {
1443         if (strcmp(pAppMgr->appid, appid) == 0) {
1444             return pAppMgr;
1445         }
1446     }
1447     return NULL;
1448 }
1449
1450 /*--------------------------------------------------------------------------*/
1451 /**
1452  * @brief   module_init: initialization of this plugin
1453  *
1454  * @param[in]   ec          weston compositor
1455  * @param[in]   argc        number of arguments(unused)
1456  * @param[in]   argv        argument list(unused)
1457  * @return      result
1458  * @retval      0           OK
1459  * @retval      -1          error
1460  */
1461 /*--------------------------------------------------------------------------*/
1462 WL_EXPORT int
1463 module_init(struct weston_compositor *ec, int *argc, char *argv[])
1464 {
1465     struct uifw_region_mng  *p;
1466     int     i;
1467
1468     uifw_info("ico_input_mgr: Enter(module_init)");
1469
1470     /* initialize management table */
1471     pInputMgr = (struct ico_input_mgr *)malloc(sizeof(struct ico_input_mgr));
1472     if (pInputMgr == NULL) {
1473         uifw_trace("ico_input_mgr: malloc failed");
1474         return -1;
1475     }
1476     memset(pInputMgr, 0, sizeof(struct ico_input_mgr));
1477     pInputMgr->compositor = ec;
1478
1479     /* interface to desktop manager(ex.HomeScreen)  */
1480     if (wl_global_create(ec->wl_display, &ico_input_mgr_control_interface, 1,
1481                          pInputMgr, ico_control_bind) == NULL) {
1482         uifw_trace("ico_input_mgr: wl_global_create mgr failed");
1483         return -1;
1484     }
1485
1486     /* interface to Input Controller(ictl) */
1487     if (wl_global_create(ec->wl_display, &ico_input_mgr_device_interface, 1,
1488                          pInputMgr, ico_device_bind) == NULL) {
1489         uifw_trace("ico_input_mgr: wl_global_create ictl failed");
1490         return -1;
1491     }
1492
1493     /* interface to App(exinput) */
1494     if (wl_global_create(ec->wl_display, &ico_exinput_interface, 1,
1495                          pInputMgr, ico_exinput_bind) == NULL) {
1496         uifw_trace("ico_input_mgr: wl_global_create exseat failed");
1497         return -1;
1498     }
1499
1500     /* initialize list */
1501     wl_list_init(&pInputMgr->ictl_list);
1502     wl_list_init(&pInputMgr->app_list);
1503     wl_list_init(&pInputMgr->free_region);
1504     p = malloc(sizeof(struct uifw_region_mng)*100);
1505     if (p)  {
1506         memset(p, 0, sizeof(struct uifw_region_mng)*100);
1507         for (i = 0; i < 100; i++, p++)  {
1508             wl_list_insert(pInputMgr->free_region.prev, &p->link);
1509         }
1510     }
1511
1512     /* found input seat */
1513     pInputMgr->seat = container_of(ec->seat_list.next, struct weston_seat, link);
1514
1515     /* set hook for input region control    */
1516     ico_window_mgr_set_hook_change(ico_input_hook_region_change);
1517     ico_window_mgr_set_hook_destory(ico_input_hook_region_destroy);
1518     ico_window_mgr_set_hook_inputregion(ico_set_input_region);
1519
1520     uifw_info("ico_input_mgr: Leave(module_init)");
1521     return 0;
1522 }