7e1699e05ca68badb0599f37ac835736b34a4ee9
[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 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    Jul-26-2013
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
42 #include <pixman.h>
43 #include <wayland-server.h>
44 #include <weston/compositor.h>
45 #include "ico_ivi_common_private.h"
46 #include "ico_ivi_shell_private.h"
47 #include "ico_input_mgr.h"
48 #include "ico_window_mgr.h"
49 #include "ico_window_mgr_private.h"
50 #include "ico_window_mgr-server-protocol.h"
51 #include "ico_input_mgr-server-protocol.h"
52
53 /* degine maximum length                */
54 #define ICO_MINPUT_DEVICE_LEN           32
55 #define ICO_MINPUT_SW_LEN               20
56 #define ICO_MINPUT_MAX_CODES            20
57
58 /* structure definition */
59 struct uifw_region_mng;
60
61 /* working table of Multi Input Manager */
62 struct ico_input_mgr {
63     struct weston_compositor *compositor;   /* Weston Compositor                    */
64     struct wl_list  ictl_list;              /* Input Controller List                */
65     struct wl_list  app_list;               /* application List                     */
66     struct wl_list  dev_list;               /* pseudo device List                   */
67     struct wl_list  free_region;            /* free input region table list         */
68     struct weston_seat *seat;               /* input seat                           */
69     struct wl_resource *inputmgr;
70 };
71
72 /* Input Switch Table                   */
73 struct ico_ictl_code {
74     uint16_t    code;                       /* input code numner                    */
75     char        name[ICO_MINPUT_SW_LEN];    /* input code name                      */
76 };
77
78 struct ico_ictl_input {
79     struct wl_list link;                    /* link                                 */
80     char        swname[ICO_MINPUT_SW_LEN];  /* input switch name                    */
81     int32_t     input;                      /* input Id                             */
82     uint16_t    fix;                        /* fixed assign to application          */
83     uint16_t    ncode;                      /* number of codes                      */
84     struct ico_ictl_code code[ICO_MINPUT_MAX_CODES];   /* codes                     */
85     struct ico_app_mgr  *app;               /* send event tagret application        */
86 };
87
88 /* Input Controller Management Table    */
89 struct ico_ictl_mgr {
90     struct wl_list link;                    /* link                                 */
91     struct wl_client    *client;            /* client                               */
92     struct wl_resource  *mgr_resource;      /* resource as manager                  */
93     char    device[ICO_MINPUT_DEVICE_LEN];  /* device name                          */
94     int     type;                           /* device type                          */
95     struct wl_list ico_ictl_input;          /* list of input switchs                */
96 };
97
98 /* Application Management Table */
99 struct ico_app_mgr {
100     struct wl_list link;                    /* link                                 */
101     struct wl_client    *client;            /* client                               */
102     struct wl_resource  *resource;          /* resource for send event              */
103     struct wl_resource  *mgr_resource;      /* resource as manager(if NULL, client) */
104     char    appid[ICO_IVI_APPID_LENGTH];    /* application id                       */
105 };
106
107 /* Pseudo Input Device Control Flags    */
108 #define EVENT_MOTION        0x01            /* motion event                         */
109 #define EVENT_BUTTON        0x02            /* button event                         */
110 #define EVENT_TOUCH         0x03            /* touch event                          */
111 #define EVENT_KEY           0x04            /* key event                            */
112 #define EVENT_PENDING       0xff            /* pending event input                  */
113
114 #define PENDING_X           0x01            /* pending X coordinate                 */
115 #define PENDING_Y           0x02            /* pending Y coordinate                 */
116
117 /* Pseudo Input Device Table    */
118 struct uifw_input_device    {
119     struct wl_list  link;                   /* link to next device                  */
120     uint16_t    type;                       /* device type                          */
121     uint16_t    no;                         /* device number                        */
122     int         disp_x;                     /* display X coordinate                 */
123     int         disp_y;                     /* display Y coordinate                 */
124     int         x;                          /* current X coordinate                 */
125     int         y;                          /* current Y coordinate                 */
126     int         pend_x;                     /* pending X coordinate                 */
127     int         pend_y;                     /* pending Y coordinate                 */
128     uint16_t    node;                       /* display number                       */
129     uint16_t    pending;                    /* pending flag                         */
130     struct weston_surface *grab;            /* current grab surface                 */
131 };
132
133 /* Input Region Table           */
134 struct uifw_region_mng  {
135     struct wl_list  link;                   /* link pointer                         */
136     struct ico_uifw_input_region region;    /* input region                         */
137 };
138
139 /* prototype of static function */
140                                             /* bind input manager form manager      */
141 static void ico_control_bind(struct wl_client *client, void *data,
142                              uint32_t version, uint32_t id);
143                                             /* unbind input manager form manager    */
144 static void ico_control_unbind(struct wl_resource *resource);
145                                             /* bind input manager form input controller*/
146 static void ico_device_bind(struct wl_client *client, void *data,
147                             uint32_t version, uint32_t id);
148                                             /* unbind input manager form input controller*/
149 static void ico_device_unbind(struct wl_resource *resource);
150                                             /* bind input manager(form application) */
151 static void ico_exinput_bind(struct wl_client *client, void *data,
152                              uint32_t version, uint32_t id);
153                                             /* unbind input manager(form application)*/
154 static void ico_exinput_unbind(struct wl_resource *resource);
155
156                                             /* find ictl manager by device name     */
157 static struct ico_ictl_mgr *find_ictlmgr_by_device(const char *device);
158                                             /* find ictl input switch by input Id   */
159 static struct ico_ictl_input *find_ictlinput_by_input(struct ico_ictl_mgr *pIctlMgr,
160                                                       const int32_t input);
161                                             /* find app manager by application Id   */
162 static struct ico_app_mgr *find_app_by_appid(const char *appid);
163                                             /* add input event to application       */
164 static void ico_mgr_add_input_app(struct wl_client *client, struct wl_resource *resource,
165                                   const char *appid, const char *device, int32_t input,
166                                   int32_t fix, int32_t keycode);
167                                             /* delete input event to application    */
168 static void ico_mgr_del_input_app(struct wl_client *client, struct wl_resource *resource,
169                                   const char *appid, const char *device, int32_t input);
170                                             /* send input event from manager        */
171 static void ico_mgr_send_input_event(struct wl_client *client, struct wl_resource *resource,
172                                      const char *target, uint32_t surfaceid, int32_t type,
173                                      int32_t deviceno, uint32_t time,
174                                      int32_t code, int32_t value);
175                                             /* set input region                     */
176 static void ico_mgr_set_input_region(struct wl_client *client, struct wl_resource *resource,
177                                      const char *target, int32_t x, int32_t y,
178                                      int32_t width, int32_t height, int32_t hotspot_x,
179                                      int32_t hotspot_y, int32_t cursor_x, int32_t cursor_y,
180                                      int32_t cursor_width, int32_t cursor_height,
181                                      uint32_t attr);
182                                             /* unset input region                   */
183 static void ico_mgr_unset_input_region(struct wl_client *client,
184                                        struct wl_resource *resource,
185                                        const char *taret, int32_t x, int32_t y,
186                                        int32_t width, int32_t height);
187                                             /* input region set/unset               */
188 static void ico_set_input_region(int set, struct uifw_win_surface *usurf,
189                                  int32_t x, int32_t y, int32_t width, int32_t height,
190                                  int32_t hotspot_x, int32_t hotspot_y, int32_t cursor_x,
191                                  int32_t cursor_y, int32_t cursor_width,
192                                  int32_t cursor_height, uint32_t attr);
193                                             /* create and regist Input Controller table*/
194 static void ico_device_configure_input(struct wl_client *client,
195                                        struct wl_resource *resource, const char *device,
196                                        int32_t type, const char *swname, int32_t input,
197                                        const char *codename, int32_t code);
198                                             /* add input to from Input Controller table*/
199 static void ico_device_configure_code(struct wl_client *client,
200                                       struct wl_resource *resource, const char *device,
201                                       int32_t input, const char *codename, int32_t code);
202                                             /* device input event                   */
203 static void ico_device_input_event(struct wl_client *client, struct wl_resource *resource,
204                                    uint32_t time, const char *device,
205                                    int32_t input, int32_t code, int32_t state);
206 static void ico_input_send_region_event(struct wl_array *array);
207
208 /* definition of Wayland protocol       */
209 /* Input Manager Control interface      */
210 static const struct ico_input_mgr_control_interface ico_input_mgr_implementation = {
211     ico_mgr_add_input_app,
212     ico_mgr_del_input_app,
213     ico_mgr_send_input_event
214 };
215
216 /* Extended Input interface             */
217 static const struct ico_exinput_interface ico_exinput_implementation = {
218     ico_mgr_set_input_region,
219     ico_mgr_unset_input_region
220 };
221
222 /* Input Controller Device interface    */
223 static const struct ico_input_mgr_device_interface input_mgr_ictl_implementation = {
224     ico_device_configure_input,
225     ico_device_configure_code,
226     ico_device_input_event
227 };
228
229 /* definition of class variable */
230 struct ico_input_mgr    *pInputMgr = NULL;
231
232 /* implementation */
233 /*--------------------------------------------------------------------------*/
234 /**
235  * @brief   ico_mgr_add_input_app: add input event to application from HomeScreen.
236  *
237  * @param[in]   client          client(HomeScreen)
238  * @param[in]   resource        resource of request
239  * @param[in]   appid           target application id
240  * @param[in]   device          device name
241  * @param[in]   input           input switch number
242  * @param[in]   fix             fix to application(1=fix,0=general)
243  * @param[in]   keycode         switch map to keyboard operation(0=not map to keyboard)
244  * @return      none
245  */
246 /*--------------------------------------------------------------------------*/
247 static void
248 ico_mgr_add_input_app(struct wl_client *client, struct wl_resource *resource,
249                       const char *appid, const char *device, int32_t input,
250                       int32_t fix, int32_t keycode)
251 {
252     struct uifw_client      *uclient;
253     struct ico_ictl_mgr     *pIctlMgr;
254     struct ico_ictl_input   *pInput;
255     struct ico_app_mgr      *pAppMgr;
256
257     uifw_trace("ico_mgr_add_input_app: Enter(appid=%s,dev=%s,input=%d,fix=%d,key=%d)",
258                appid, device, input, fix, keycode);
259
260     /* check for access control         */
261     if (resource != NULL)   {
262         /* resource is NULL, internal use   */
263         uclient = ico_window_mgr_find_uclient(client);
264         if (! uclient)  {
265             wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
266                                    "ico_input_mgr_control_add_input_app: unknown client");
267             uifw_trace("ico_mgr_add_input_app: Leave(unknown client=%08x)", (int)client);
268             return;
269         }
270         if ((uclient->api_access_control & ICO_UIFW_INPUT_MGR_CONTROL_ADD_INPUT_APP) == 0) {
271             wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
272                                    "ico_input_mgr_control_add_input_app: not permitted");
273             uifw_trace("ico_mgr_add_input_app: Leave(%s not permitted)", uclient->appid);
274             return;
275         }
276     }
277     pIctlMgr = find_ictlmgr_by_device(device);
278     if (! pIctlMgr) {
279         /* not configure input controller, create   */
280         ico_device_configure_input(NULL, NULL, device, 0, NULL, input, NULL, 0);
281         pIctlMgr = find_ictlmgr_by_device(device);
282         if (! pIctlMgr) {
283             uifw_error("ico_mgr_add_input_app: Leave(No Memory)");
284             return;
285         }
286     }
287     pInput = find_ictlinput_by_input(pIctlMgr, input);
288     if (! pInput)   {
289         /* not configure input switch, create   */
290         ico_device_configure_input(NULL, NULL, device, 0, NULL, input, NULL, 0);
291         pInput = find_ictlinput_by_input(pIctlMgr, input);
292         if (! pInput)   {
293             uifw_error("ico_mgr_add_input_app: Leave(No Memory)");
294             return;
295         }
296     }
297
298     /* find application         */
299     pAppMgr = find_app_by_appid(appid);
300     if (! pAppMgr)  {
301         /* create Application Management Table  */
302         pAppMgr = (struct ico_app_mgr *)malloc(sizeof(struct ico_app_mgr));
303         if (! pAppMgr)  {
304             uifw_error("ico_mgr_add_input_app: Leave(No Memory)");
305             return;
306         }
307         memset(pAppMgr, 0, sizeof(struct ico_app_mgr));
308         strncpy(pAppMgr->appid, appid, sizeof(pAppMgr->appid)-1);
309         wl_list_insert(pInputMgr->app_list.prev, &pAppMgr->link);
310     }
311
312     pInput->app = pAppMgr;
313     pInput->fix = fix;
314     uifw_trace("ico_mgr_add_input_app: Leave(%s.%s[%d] assign to %s)",
315                pIctlMgr->device, pInput->swname ? pInput->swname : "(NULL)", input,
316                pAppMgr->appid);
317 }
318
319 /*--------------------------------------------------------------------------*/
320 /**
321  * @brief   ico_mgr_del_input_app: delete input event at application from HomeScreen.
322  *
323  * @param[in]   client          client(HomeScreen)
324  * @param[in]   resource        resource of request
325  * @param[in]   appid           target application id,
326  *                              if NULL, all applictions without fixed assign switch
327  * @param[in]   device          device name
328  *                              if NULL, all device without fixed assign switch
329  * @param[in]   input           input switch number
330  *                              if -1, all input without fixed assign switch
331  * @return      none
332  */
333 /*--------------------------------------------------------------------------*/
334 static void
335 ico_mgr_del_input_app(struct wl_client *client, struct wl_resource *resource,
336                       const char *appid, const char *device, int32_t input)
337 {
338     struct uifw_client      *uclient;
339     int     alldev = 0;
340     struct ico_ictl_mgr     *pIctlMgr = NULL;
341     struct ico_ictl_input   *pInput = NULL;
342     struct ico_app_mgr      *pAppMgr;
343
344     uifw_trace("ico_mgr_del_input_app: Enter(appid=%s,dev=%s,input=%d)",
345                appid ? appid : "(NULL)", device ? device : "(NULL)", input);
346
347     /* check for access control         */
348     if (resource != NULL)   {
349         /* resource is NULL, internal use   */
350         uclient = ico_window_mgr_find_uclient(client);
351         if (! uclient)  {
352             wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
353                                    "ico_input_mgr_control_del_input_app: unknown client");
354             uifw_trace("ico_mgr_del_input_app: Leave(unknown client=%08x)", (int)client);
355             return;
356         }
357         if ((uclient->api_access_control & ICO_UIFW_INPUT_MGR_CONTROL_DEL_INPUT_APP) == 0) {
358             wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
359                                    "ico_input_mgr_control_del_input_app: not permitted");
360             uifw_trace("ico_mgr_del_input_app: Leave(%s not permitted)", uclient->appid);
361             return;
362         }
363     }
364     if ((device != NULL) && (*device != 0)) {
365         pIctlMgr = find_ictlmgr_by_device(device);
366         if (! pIctlMgr) {
367             /* not configure input controller, NOP  */
368             uifw_trace("ico_mgr_del_input_app: Leave(%s dose not exist)", device);
369             return;
370         }
371         if (input >= 0) {
372             pInput = find_ictlinput_by_input(pIctlMgr, input);
373             if (! pInput)   {
374                 /* not configure input switch, NOP  */
375                 uifw_trace("ico_mgr_del_input_app: Leave(%s.%d dose not exist)",
376                            device, input);
377                 return;
378             }
379         }
380     }
381     else    {
382         alldev = 1;
383     }
384
385     /* find application         */
386     if ((appid != NULL) && (*appid != 0))   {
387         pAppMgr = find_app_by_appid(appid);
388         if (! pAppMgr)  {
389             /* application dose not exist, NOP  */
390             uifw_trace("ico_mgr_del_input_app: Leave(app.%s dose not exist)", appid);
391             return;
392         }
393         if (alldev == 0)    {
394             if (input >= 0) {
395                 if (pInput->app != pAppMgr) {
396                     /* not same application, NOP        */
397                     uifw_trace("ico_mgr_del_input_app: Leave(%s.%d not app.%s, current %s)",
398                                device, input, appid,
399                                pInput->app ? pInput->app->appid : "(NULL)");
400                     return;
401                 }
402                 uifw_trace("ico_mgr_del_input_app: Leave(%s.%d app.%s deleted)",
403                            device, input, appid);
404                 pInput->app = NULL;
405                 return;
406             }
407             else    {
408                 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
409                     if ((pInput->fix == 0) && (pInput->app == pAppMgr))   {
410                         uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
411                                    pIctlMgr->device, pInput->input, appid);
412                         pInput->app = NULL;
413                     }
414                 }
415             }
416         }
417         else    {
418             /* reset all device without fixed assign    */
419             wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)    {
420                 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
421                     if ((pInput->fix == 0) && (pInput->app == pAppMgr))   {
422                         uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
423                                    pIctlMgr->device, pInput->input, pInput->app->appid);
424                         pInput->app = NULL;
425                     }
426                 }
427             }
428         }
429     }
430     else    {
431         if (alldev == 0)    {
432             if (input >= 0) {
433                 if ((pInput->fix == 0) && (pInput->app != NULL))    {
434                     uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
435                                pIctlMgr->device, pInput->input, pInput->app->appid);
436                     pInput->app = NULL;
437                 }
438             }
439             else    {
440                 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
441                     if ((pInput->fix == 0) && (pInput->app != NULL))    {
442                         uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
443                                pIctlMgr->device, pInput->input, pInput->app->appid);
444                         pInput->app = NULL;
445                     }
446                 }
447             }
448         }
449         else    {
450             /* reset all application without fixed assign       */
451             wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)    {
452                 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
453                     if ((pInput->fix == 0) && (pInput->app != NULL))    {
454                         uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
455                                    pIctlMgr->device, pInput->input, pInput->app->appid);
456                         pInput->app = NULL;
457                     }
458                 }
459             }
460         }
461     }
462     uifw_trace("ico_mgr_del_input_app: Leave");
463 }
464
465 /*--------------------------------------------------------------------------*/
466 /**
467  * @brief   ico_mgr_send_input_event: send input event from manager
468  *
469  * @param[in]   client          client(HomeScreen)
470  * @param[in]   resource        resource of request
471  * @param[in]   target          target window name and application id
472  * @param[in]   surfaceid       target surface id
473  * @param[in]   type            event device type
474  * @param[in]   deviceno        device number
475  * @param[in]   time            event time (if 0, generate)
476  * @param[in]   code            event code
477  * @param[in]   value           event value
478  * @return      none
479  */
480 /*--------------------------------------------------------------------------*/
481 static void
482 ico_mgr_send_input_event(struct wl_client *client, struct wl_resource *resource,
483                          const char *target, uint32_t surfaceid, int32_t type,
484                          int32_t deviceno, uint32_t time, int32_t code, int32_t value)
485 {
486     struct uifw_client      *uclient;
487     struct uifw_win_surface *usurf;         /* UIFW surface                 */
488     struct uifw_input_device *dev;          /* device control table         */
489     struct wl_resource      *cres;          /* event send client resource   */
490     struct wl_array dummy_array;            /* dummy array for wayland API  */
491     uint32_t    ctime;                      /* current time(ms)             */
492     uint32_t    serial;                     /* event serial number          */
493     int         event;                      /* event flag                   */
494     wl_fixed_t  fix_x;                      /* wayland X coordinate         */
495     wl_fixed_t  fix_y;                      /* wayland Y coordinate         */
496     wl_fixed_t  dx, dy;                     /* relative coordinate (dummy)  */
497     struct weston_surface   *grabsave;      /* real grab surface            */
498     int         keyboard_active;            /* keyborad active surface flag */
499
500 #if 0           /* too many log */
501     uifw_debug("ico_mgr_send_input_event: Enter(target=%s surf=%x dev=%d.%d "
502                "time=%d code=%x value=%d)",
503                target ? target : "(NULL)", surfaceid, type, deviceno,
504                time, code, value);
505 #endif
506
507     /* check for access control         */
508     if (resource != NULL)   {
509         /* resource is NULL, internal use   */
510         uclient = ico_window_mgr_find_uclient(client);
511         if (! uclient)  {
512             wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
513                                    "ico_input_mgr_control_send_input_event: unknown client");
514             uifw_trace("ico_mgr_send_input_event: Leave(unknown client=%08x)", (int)client);
515             return;
516         }
517         if ((uclient->api_access_control & ICO_UIFW_INPUT_MGR_CONTROL_ADD_INPUT_APP) == 0) {
518             wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
519                                    "ico_input_mgr_control_send_input_event: not permitted");
520             uifw_trace("ico_mgr_send_input_event: Leave(%s not permitted)", uclient->appid);
521             return;
522         }
523     }
524     /* search pseudo input device           */
525     wl_list_for_each (dev, &pInputMgr->dev_list, link)  {
526         if ((dev->type == type) && (dev->no == deviceno))   break;
527     }
528     if (&dev->link == &pInputMgr->dev_list) {
529         /* device not exist, create new device  */
530         uifw_trace("ico_mgr_send_input_event: new device=%d no=%d", type, deviceno);
531         dev = malloc(sizeof(struct uifw_input_device));
532         if (! dev)  {
533             uifw_error("ico_mgr_send_input_event: Leave(No Memory)");
534             return;
535         }
536         memset(dev, 0, sizeof(struct uifw_input_device));
537         dev->type = type;
538         dev->no = deviceno;
539         if ((type == ICO_INPUT_MGR_DEVICE_TYPE_POINTER) ||
540             (type == ICO_INPUT_MGR_DEVICE_TYPE_TOUCH) ||
541             (type == ICO_INPUT_MGR_DEVICE_TYPE_HAPTIC)) {
542             ico_window_mgr_get_display_coordinate(deviceno, &dev->disp_x, &dev->disp_y);
543         }
544         wl_list_insert(pInputMgr->dev_list.prev, &dev->link);
545     }
546
547     /* convert pending event            */
548     event = 0;
549     if ((code & 0xffff0000) != (EV_REL << 16))  {
550         code &= 0x0000ffff;
551     }
552     switch (type)   {
553     case ICO_INPUT_MGR_DEVICE_TYPE_POINTER:         /* mouse        */
554     case ICO_INPUT_MGR_DEVICE_TYPE_TOUCH:           /* touch panel  */
555     case ICO_INPUT_MGR_DEVICE_TYPE_HAPTIC:          /* haptic       */
556         switch (code)   {
557         case ABS_X:
558             if (dev->pending & PENDING_Y)   {
559                 dev->x = value;
560                 dev->y = dev->pend_y;
561                 dev->pending = 0;
562                 dev->pend_x = 0;
563                 dev->pend_y = 0;
564                 event = EVENT_MOTION;
565             }
566             else    {
567                 dev->pend_x = value;
568                 dev->pending |= PENDING_X;
569                 event = EVENT_PENDING;
570             }
571             break;
572         case ABS_Y:
573             if (dev->pending & PENDING_X)   {
574                 dev->x = dev->pend_x;
575                 dev->y = value;
576                 dev->pending = 0;
577                 dev->pend_x = 0;
578                 dev->pend_y = 0;
579                 event = EVENT_MOTION;
580             }
581             else    {
582                 dev->pend_y = value;
583                 dev->pending |= PENDING_Y;
584                 event = EVENT_PENDING;
585             }
586             break;
587         case ABS_Z:
588             dev->x = (short)(value >> 16);
589             dev->y = (short)(value & 0x0ffff);
590             dev->pending = 0;
591             dev->pend_x = 0;
592             dev->pend_y = 0;
593             event = EVENT_MOTION;
594             break;
595         case ((EV_REL << 16) | REL_X):
596             if (dev->pending & PENDING_Y)   {
597                 dev->x += value;
598                 dev->y = dev->pend_y;
599                 dev->pending = 0;
600                 dev->pend_x = 0;
601                 dev->pend_y = 0;
602                 event = EVENT_MOTION;
603             }
604             else    {
605                 dev->pend_x = dev->x + value;
606                 dev->pending |= PENDING_X;
607                 event = EVENT_PENDING;
608             }
609             break;
610         case ((EV_REL << 16) | REL_Y):
611             if (dev->pending & PENDING_X)   {
612                 dev->x = dev->pend_x;
613                 dev->y += value;
614                 dev->pending = 0;
615                 dev->pend_x = 0;
616                 dev->pend_y = 0;
617                 event = EVENT_MOTION;
618             }
619             else    {
620                 dev->pend_x = dev->y + value;
621                 dev->pending |= PENDING_Y;
622                 event = EVENT_PENDING;
623             }
624             break;
625         case ((EV_REL << 16) | REL_Z):
626             dev->x += (short)(value >> 16);
627             dev->y += (short)(value & 0x0ffff);
628             dev->pending = 0;
629             dev->pend_x = 0;
630             dev->pend_y = 0;
631             event = EVENT_MOTION;
632             break;
633         default:
634             if (type == ICO_INPUT_MGR_DEVICE_TYPE_TOUCH)    {
635                 event = EVENT_TOUCH;
636             }
637             else    {
638                 event = EVENT_BUTTON;
639             }
640             break;
641         }
642         break;
643     default:
644         event = EVENT_KEY;
645         break;
646     }
647
648     if (event == EVENT_PENDING)   {
649 #if 0           /* too many log */
650         uifw_debug("ico_mgr_send_input_event: Leave(event pending)");
651 #endif
652         return;
653     }
654
655     if (time)   {
656         ctime = time;
657     }
658     else    {
659         ctime = weston_compositor_get_time();
660     }
661     fix_x = wl_fixed_from_int(dev->x + dev->disp_x);
662     fix_y = wl_fixed_from_int(dev->y + dev->disp_y);
663
664     if ((surfaceid == 0) && ((target == NULL) || (*target == 0) || (*target == ' ')))  {
665         /* send event to surface via weston */
666
667         /* disable the event transmission to a input layer  */
668         if (type == ICO_INPUT_MGR_DEVICE_TYPE_TOUCH)    {
669             ico_window_mgr_touch_layer(TRUE);
670         }
671
672         if ((event == EVENT_TOUCH) && (pInputMgr->seat->touch == NULL)) {
673             /* system has no touch, change to pointer event */
674             if (pInputMgr->seat->pointer == NULL)   {
675                 uifw_trace("ico_mgr_send_input_event: Leave(no touch & no pointerr)");
676                 return;
677             }
678             event = EVENT_BUTTON;
679             code = BTN_LEFT;
680         }
681         else if ((event == EVENT_BUTTON) && (pInputMgr->seat->pointer == NULL)) {
682             /* system has no pointer, change to touch event */
683             if (pInputMgr->seat->touch == NULL) {
684                 uifw_trace("ico_mgr_send_input_event: Leave(no touch & no pointerr)");
685                 return;
686             }
687             event = EVENT_TOUCH;
688         }
689
690         switch (event)    {
691         case EVENT_MOTION:
692             if ((type == ICO_INPUT_MGR_DEVICE_TYPE_TOUCH) &&
693                 (pInputMgr->seat->touch))   {
694                 if (pInputMgr->seat->num_tp > 10)   {
695                     uifw_debug("ico_mgr_send_input_event: num=%d reset",
696                                pInputMgr->seat->num_tp);
697                     pInputMgr->seat->num_tp = 0;        /* safty gard   */
698                 }
699                 grabsave = pInputMgr->seat->touch->focus;
700                 uifw_debug("ico_mgr_send_input_event: MOTION(%d/%d) grab %08x org %08x",
701                            fix_x/256, fix_y/256, (int)dev->grab, (int)grabsave);
702                 if ((grabsave != dev->grab) && (dev->grab != NULL)) {
703                     weston_touch_set_focus(pInputMgr->seat, dev->grab);
704                 }
705                 notify_touch(pInputMgr->seat, ctime, 0, fix_x, fix_y, WL_TOUCH_MOTION);
706                 if ((grabsave != dev->grab) && (dev->grab != NULL)) {
707                     weston_touch_set_focus(pInputMgr->seat, grabsave);
708                 }
709             }
710             else if (pInputMgr->seat->pointer)  {
711 #if 0           /* too many log */
712                 uifw_debug("ico_mgr_send_input_event: notify_motion_absolute(%d/%d)",
713                            fix_x/256, fix_y/256);
714 #endif
715                 notify_motion_absolute(pInputMgr->seat, ctime, fix_x, fix_y);
716             }
717             break;
718         case EVENT_BUTTON:
719             uifw_trace("ico_mgr_send_input_event: notify_button(%d,%d)", code, value);
720             if (pInputMgr->seat->pointer)   {
721                 if (value)  {
722                     dev->grab = weston_compositor_pick_surface(
723                                     pInputMgr->compositor, fix_x, fix_y, &dx, &dy);
724                     weston_pointer_set_focus(pInputMgr->seat->pointer, dev->grab, dx, dy);
725                     ico_window_mgr_active_surface(dev->grab);
726                 }
727                 else    {
728                     dev->grab = NULL;
729                 }
730                 notify_button(pInputMgr->seat, ctime, code,
731                               value ? WL_POINTER_BUTTON_STATE_PRESSED :
732                                       WL_POINTER_BUTTON_STATE_RELEASED);
733             }
734             break;
735         case EVENT_TOUCH:
736             if (value == ICO_INPUT_MGR_CONTROL_TOUCH_EVENT_RESET)   {
737                 /* reset touch focus    */
738                 grabsave = pInputMgr->seat->touch->focus;
739                 uifw_trace("ico_mgr_send_input_event: notify_touch(UnGrab dev=%08x sys=%08x)",
740                            (int)dev->grab, (int)grabsave);
741                 dev->grab = NULL;
742                 if (grabsave)   {
743                     weston_touch_set_focus(pInputMgr->seat, NULL);
744                     if (pInputMgr->seat->num_tp > 0)   {
745                         uifw_debug("ico_mgr_send_input_event: num=%d reset for reset focuse",
746                                    pInputMgr->seat->num_tp);
747                         pInputMgr->seat->num_tp = 0;
748                     }
749                 }
750             }
751             else if (value == ICO_INPUT_MGR_CONTROL_TOUCH_EVENT_DOWN)   {
752                 grabsave = pInputMgr->seat->touch->focus;
753                 dev->grab = weston_compositor_pick_surface(
754                                 pInputMgr->compositor, fix_x, fix_y, &dx, &dy);
755                 uifw_trace("ico_mgr_send_input_event: notify_touch(DOWN=%d/%d) "
756                            "grab=%08x org=%08x", fix_x/256, fix_y/256,
757                            (int)dev->grab, (int)grabsave);
758                 if (grabsave != dev->grab)  {
759                     weston_touch_set_focus(pInputMgr->seat, dev->grab);
760                 }
761                 if (pInputMgr->seat->num_tp > 0)    {
762                     uifw_debug("ico_mgr_send_input_event: touch_down illegal num, modify");
763                     weston_touch_set_focus(pInputMgr->seat, NULL);
764                     pInputMgr->seat->num_tp = 0;
765                 }
766                 notify_touch(pInputMgr->seat, ctime, 0, fix_x, fix_y, WL_TOUCH_DOWN);
767                 ico_window_mgr_active_surface(dev->grab);
768             }
769             else    {
770                 grabsave = pInputMgr->seat->touch->focus;
771                 uifw_trace("ico_mgr_send_input_event: notify_touch(UP) org=%08x",
772                            (int)grabsave);
773                 if ((grabsave != dev->grab) && (dev->grab != NULL)) {
774                     weston_touch_set_focus(pInputMgr->seat, dev->grab);
775                 }
776                 if ((pInputMgr->seat->num_tp == 0) || (pInputMgr->seat->num_tp > 10))   {
777                     uifw_debug("ico_mgr_send_input_event: num=%d reset",
778                                pInputMgr->seat->num_tp);
779                     pInputMgr->seat->num_tp = 1;
780                 }
781                 notify_touch(pInputMgr->seat, ctime, 0, 0, 0, WL_TOUCH_UP);
782                 if (grabsave == dev->grab)  grabsave = NULL;
783                 weston_touch_set_focus(pInputMgr->seat, grabsave);
784                 dev->grab = NULL;
785             }
786             break;
787         case EVENT_KEY:
788             uifw_trace("ico_mgr_send_input_event: notify_key(%d,%d)", code, value);
789             notify_key(pInputMgr->seat, ctime, code,
790                        value ? WL_KEYBOARD_KEY_STATE_PRESSED :
791                                WL_KEYBOARD_KEY_STATE_RELEASED, STATE_UPDATE_NONE);
792             break;
793         default:
794             uifw_trace("ico_mgr_send_input_event: unknown event=%d", event);
795             break;
796         }
797         /* enable the event transmission to a input layer   */
798         if (type == ICO_INPUT_MGR_DEVICE_TYPE_TOUCH)    {
799             ico_window_mgr_touch_layer(FALSE);
800         }
801     }
802     else    {
803         if ((target != NULL) && (*target != 0) && (*target != ' '))    {
804             /* send event to fixed application  */
805
806             /* get application surface       */
807             usurf = ico_window_mgr_get_client_usurf(target);
808             if (! usurf)  {
809                 uifw_trace("ico_mgr_send_input_event: Leave(window=%s dose not exist)",
810                            target);
811                 return;
812             }
813         }
814         else    {
815             /* get UIFW surface             */
816             usurf = ico_window_mgr_get_usurf(surfaceid);
817             if (! usurf)    {
818                 uifw_trace("ico_mgr_send_input_event: Leave(surface dose not exist)");
819                 return;
820             }
821         }
822
823         /* send event                   */
824         switch (event)    {
825         case EVENT_MOTION:
826             if (type == ICO_INPUT_MGR_DEVICE_TYPE_TOUCH)    {
827                 cres = wl_resource_find_for_client(
828                                     &pInputMgr->seat->touch->resource_list,
829                                     wl_resource_get_client(usurf->surface->resource));
830                 if (cres)   {
831                     wl_touch_send_motion(cres, ctime, 0, fix_x, fix_y);
832                 }
833             }
834             else    {
835                 cres = wl_resource_find_for_client(
836                                     &pInputMgr->seat->pointer->resource_list,
837                                     wl_resource_get_client(usurf->surface->resource));
838                 if (cres)   {
839                     wl_pointer_send_motion(cres, ctime, fix_x, fix_y);
840                 }
841             }
842             break;
843         case EVENT_BUTTON:
844             cres = wl_resource_find_for_client(
845                                 &pInputMgr->seat->pointer->resource_list,
846                                 wl_resource_get_client(usurf->surface->resource));
847             if (cres)   {
848                 serial = wl_display_next_serial(pInputMgr->compositor->wl_display);
849                 wl_pointer_send_button(cres, serial, ctime, code,
850                                        value ? WL_POINTER_BUTTON_STATE_PRESSED :
851                                                WL_POINTER_BUTTON_STATE_RELEASED);
852             }
853             break;
854         case EVENT_TOUCH:
855             cres = wl_resource_find_for_client(
856                                 &pInputMgr->seat->touch->resource_list,
857                                 wl_resource_get_client(usurf->surface->resource));
858             if (cres)   {
859                 serial = wl_display_next_serial(pInputMgr->compositor->wl_display);
860                 if (value)  {
861                     wl_touch_send_down(cres, serial, ctime, usurf->surface->resource, 0,
862                                        fix_x, fix_y);
863                 }
864                 else    {
865                     wl_touch_send_up(cres, serial, ctime, 0);
866                 }
867             }
868             break;
869         case EVENT_KEY:
870             cres = wl_resource_find_for_client(
871                                 &pInputMgr->seat->keyboard->resource_list,
872                                 wl_resource_get_client(usurf->surface->resource));
873             if (cres)   {
874                 keyboard_active = ico_window_mgr_ismykeyboard(usurf);
875                 if (! keyboard_active)  {
876                     wl_array_init(&dummy_array);
877                     serial = wl_display_next_serial(pInputMgr->compositor->wl_display);
878                     wl_keyboard_send_enter(cres, serial,
879                                            usurf->surface->resource, &dummy_array);
880                 }
881                 serial = wl_display_next_serial(pInputMgr->compositor->wl_display);
882                 uifw_trace("ico_mgr_send_input_event: send Key (%d, %d) to %08x",
883                            code, value, usurf->surfaceid);
884                 wl_keyboard_send_key(cres, serial, ctime, code,
885                                      value ? WL_KEYBOARD_KEY_STATE_PRESSED :
886                                              WL_KEYBOARD_KEY_STATE_RELEASED);
887                 if (! keyboard_active)  {
888                     serial = wl_display_next_serial(pInputMgr->compositor->wl_display);
889                     wl_keyboard_send_leave(cres, serial, usurf->surface->resource);
890                 }
891             }
892             else    {
893                 uifw_trace("ico_mgr_send_input_event: Key client %08x dose not exist",
894                            (int)usurf->surface->resource);
895             }
896             break;
897         default:
898             break;
899         }
900     }
901 #if 0           /* too many log */
902     uifw_debug("ico_mgr_send_input_event: Leave");
903 #endif
904 }
905
906 /*--------------------------------------------------------------------------*/
907 /**
908  * @brief   ico_mgr_set_input_region: set input region for haptic devcie
909  *
910  * @param[in]   client          client(Device Input Controller)
911  * @param[in]   resource        resource of request
912  * @param[in]   target          target window (winname@appid)
913  * @param[in]   x               input region X coordinate
914  * @param[in]   y               input region X coordinate
915  * @param[in]   width           input region width
916  * @param[in]   height          input region height
917  * @param[in]   hotspot_x       hotspot of X relative coordinate
918  * @param[in]   hotspot_y       hotspot of Y relative coordinate
919  * @param[in]   cursor_x        cursor region X coordinate
920  * @param[in]   cursor_y        cursor region X coordinate
921  * @param[in]   cursor_width    cursor region width
922  * @param[in]   cursor_height   cursor region height
923  * @param[in]   attr            region attributes(currently unused)
924  * @return      none
925  */
926 /*--------------------------------------------------------------------------*/
927 static void
928 ico_mgr_set_input_region(struct wl_client *client, struct wl_resource *resource,
929                          const char *target, int32_t x, int32_t y,
930                          int32_t width, int32_t height, int32_t hotspot_x,
931                          int32_t hotspot_y, int32_t cursor_x, int32_t cursor_y,
932                          int32_t cursor_width, int32_t cursor_height, uint32_t attr)
933 {
934     struct uifw_client      *uclient;
935     struct uifw_win_surface *usurf;         /* UIFW surface                 */
936
937     uifw_trace("ico_mgr_set_input_region: Enter(%s %d/%d-%d/%d(%d/%d) %d/%d-%d/%d)",
938                target, x, y, width, height, hotspot_x, hotspot_y,
939                cursor_x, cursor_y, cursor_width, cursor_height);
940
941     /* check for access control         */
942     if (resource != NULL)   {
943         /* resource is NULL, internal use   */
944         uclient = ico_window_mgr_find_uclient(client);
945         if (! uclient)  {
946             wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
947                                    "ico_exapi_input_set_input_region: unknown client");
948             uifw_trace("ico_mgr_set_input_region: Leave(unknown client=%08x)", (int)client);
949             return;
950         }
951         if ((uclient->api_access_control & ICO_UIFW_EXINPUT_SET_INPUT_REGION) == 0) {
952             wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
953                                    "ico_exapi_input_set_input_region: not permitted");
954             uifw_trace("ico_mgr_set_input_region: Leave(%s not permitted)", uclient->appid);
955             return;
956         }
957     }
958     /* get target surface           */
959     usurf = ico_window_mgr_get_client_usurf(target);
960     if (! usurf)    {
961         uifw_warn("ico_mgr_set_input_region: Leave(target<%s> dose not exist)", target);
962         return;
963     }
964
965     ico_set_input_region(1, usurf, x, y, width, height, hotspot_x, hotspot_y,
966                          cursor_x, cursor_y, cursor_width, cursor_height, attr);
967
968     uifw_trace("ico_mgr_set_input_region: Leave");
969 }
970
971 /*--------------------------------------------------------------------------*/
972 /**
973  * @brief   ico_mgr_unset_input_region: unset input region for haptic devcie
974  *
975  * @param[in]   client          client(Device Input Controller)
976  * @param[in]   resource        resource of request
977  * @param[in]   target          target window (winname@appid)
978  * @param[in]   x               input region X coordinate
979  * @param[in]   y               input region X coordinate
980  * @param[in]   width           input region width
981  * @param[in]   height          input region height
982  * @return      none
983  */
984 /*--------------------------------------------------------------------------*/
985 static void
986 ico_mgr_unset_input_region(struct wl_client *client, struct wl_resource *resource,
987                            const char *target, int32_t x, int32_t y,
988                            int32_t width, int32_t height)
989 {
990     struct uifw_client      *uclient;
991     struct uifw_win_surface *usurf;         /* UIFW surface                 */
992
993     uifw_trace("ico_mgr_unset_input_region: Enter(%s %d/%d-%d/%d)",
994                target, x, y, width, height);
995
996     /* check for access control         */
997     if (resource != NULL)   {
998         /* resource is NULL, internal use   */
999         uclient = ico_window_mgr_find_uclient(client);
1000         if (! uclient)  {
1001             wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
1002                                    "ico_exapi_input_unset_input_region: unknown client");
1003             uifw_trace("ico_mgr_unset_input_region: Leave(unknown client=%08x)", (int)client);
1004             return;
1005         }
1006         if ((uclient->api_access_control & ICO_UIFW_EXINPUT_UNSET_INPUT_REGION) == 0)   {
1007             wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
1008                                    "ico_exapi_input_unset_input_region: not permitted");
1009             uifw_trace("ico_mgr_unset_input_region: Leave(%s not permitted)", uclient->appid);
1010             return;
1011         }
1012     }
1013     /* get target surface           */
1014     usurf = ico_window_mgr_get_client_usurf(target);
1015     if (! usurf)    {
1016         uifw_warn("ico_mgr_unset_input_region: Leave(target<%s> dose not exist)", target);
1017         return;
1018     }
1019
1020     ico_set_input_region(0, usurf, x, y, width, height, 0, 0, 0, 0, 0, 0, 0);
1021
1022     uifw_trace("ico_mgr_unset_input_region: Leave");
1023 }
1024
1025 /*--------------------------------------------------------------------------*/
1026 /**
1027  * @brief   ico_input_hook_region_change: change surface attribute
1028  *
1029  * @param[in]   usurf           UIFW surface
1030  * @return      none
1031  */
1032 /*--------------------------------------------------------------------------*/
1033 static void
1034 ico_input_hook_region_change(struct uifw_win_surface *usurf)
1035 {
1036     struct uifw_region_mng      *p;         /* input region mamagement table*/
1037     struct ico_uifw_input_region *rp;       /* input region                 */
1038     struct wl_array             array;
1039     int                         chgcount = 0;
1040     int                         visible;
1041
1042     visible = ico_window_mgr_is_visible(usurf);
1043
1044     uifw_trace("ico_input_hook_region_change: Entery(surf=%08x, visible=%d)",
1045                usurf->surfaceid, visible);
1046
1047     wl_array_init(&array);
1048
1049     wl_list_for_each(p, &usurf->input_region, link) {
1050         if (((p->region.change > 0) && (visible <= 0)) ||
1051             ((p->region.change <= 0) && (visible > 0))) {
1052             /* visible change, send add/remove event    */
1053             rp = (struct ico_uifw_input_region *)
1054                  wl_array_add(&array, sizeof(struct ico_uifw_input_region));
1055             if (rp) {
1056                 chgcount ++;
1057                 memcpy(rp, &p->region, sizeof(struct ico_uifw_input_region));
1058                 if (visible > 0)    {
1059                     rp->change = ICO_INPUT_MGR_DEVICE_REGION_ADD;
1060                 }
1061                 else    {
1062                     rp->change = ICO_INPUT_MGR_DEVICE_REGION_REMOVE;
1063                 }
1064             }
1065             p->region.change = visible;
1066             p->region.node = usurf->node_tbl->node;
1067             p->region.surface_x = usurf->x;
1068             p->region.surface_y = usurf->y;
1069         }
1070         else if ((p->region.node != usurf->node_tbl->node) ||
1071                  (p->region.surface_x != usurf->x) ||
1072                  (p->region.surface_y != usurf->y)) {
1073             /* surface position change, send change event   */
1074             p->region.node = usurf->node_tbl->node;
1075             p->region.surface_x = usurf->x;
1076             p->region.surface_y = usurf->y;
1077
1078             rp = (struct ico_uifw_input_region *)
1079                  wl_array_add(&array, sizeof(struct ico_uifw_input_region));
1080             if (rp) {
1081                 chgcount ++;
1082                 memcpy(rp, &p->region, sizeof(struct ico_uifw_input_region));
1083                 rp->change = ICO_INPUT_MGR_DEVICE_REGION_CHANGE;
1084             }
1085         }
1086     }
1087     if (chgcount > 0)   {
1088         /* send region delete to haptic device input controller */
1089         ico_input_send_region_event(&array);
1090     }
1091     uifw_trace("ico_input_hook_region_change: Leave");
1092 }
1093
1094 /*--------------------------------------------------------------------------*/
1095 /**
1096  * @brief   ico_input_hook_region_destroy: destory surface
1097  *
1098  * @param[in]   usurf           UIFW surface
1099  * @return      none
1100  */
1101 /*--------------------------------------------------------------------------*/
1102 static void
1103 ico_input_hook_region_destroy(struct uifw_win_surface *usurf)
1104 {
1105     struct uifw_region_mng      *p;         /* input region mamagement table*/
1106     struct uifw_region_mng      *np;        /* next region mamagement table */
1107     struct ico_uifw_input_region *rp;       /* input region                 */
1108     struct wl_array             array;
1109     int                         delcount = 0;
1110
1111     uifw_trace("ico_input_hook_region_destroy: Entery(surf=%08x)", usurf->surfaceid);
1112
1113     wl_array_init(&array);
1114
1115     wl_list_for_each_safe(p, np, &usurf->input_region, link)    {
1116         if (p->region.change > 0)   {
1117             /* visible, send remove event   */
1118             rp = (struct ico_uifw_input_region *)
1119                  wl_array_add(&array, sizeof(struct ico_uifw_input_region));
1120             if (rp) {
1121                 delcount ++;
1122                 memcpy(rp, &p->region, sizeof(struct ico_uifw_input_region));
1123                 rp->change = ICO_INPUT_MGR_DEVICE_REGION_REMOVE;
1124             }
1125         }
1126         wl_list_remove(&p->link);
1127         wl_list_insert(pInputMgr->free_region.prev, &p->link);
1128     }
1129     if (delcount > 0)   {
1130         /* send region delete to haptic device input controller */
1131         ico_input_send_region_event(&array);
1132     }
1133     uifw_trace("ico_input_hook_region_destroy: Leave");
1134 }
1135
1136 /*--------------------------------------------------------------------------*/
1137 /**
1138  * @brief   ico_set_input_region: input region set/unset
1139  *
1140  * @param[in]   set             set(1)/unset(0)
1141  * @param[in]   usurf           UIFW surface
1142  * @param[in]   x               input region X coordinate
1143  * @param[in]   y               input region X coordinate
1144  * @param[in]   width           input region width
1145  * @param[in]   height          input region height
1146  * @param[in]   hotspot_x       hotspot of X relative coordinate
1147  * @param[in]   hotspot_y       hotspot of Y relative coordinate
1148  * @param[in]   cursor_x        cursor region X coordinate
1149  * @param[in]   cursor_y        cursor region X coordinate
1150  * @param[in]   cursor_width    cursor region width
1151  * @param[in]   cursor_height   cursor region height
1152  * @param[in]   attr            region attributes(currently unused)
1153  * @return      none
1154  */
1155 /*--------------------------------------------------------------------------*/
1156 static void
1157 ico_set_input_region(int set, struct uifw_win_surface *usurf,
1158                      int32_t x, int32_t y, int32_t width, int32_t height,
1159                      int32_t hotspot_x, int32_t hotspot_y, int32_t cursor_x, int32_t cursor_y,
1160                      int32_t cursor_width, int32_t cursor_height, uint32_t attr)
1161 {
1162     struct uifw_region_mng      *p;         /* input region mamagement table*/
1163     struct uifw_region_mng      *np;        /* next region mamagement table */
1164     struct ico_uifw_input_region *rp;       /* input region                 */
1165     struct wl_array             array;
1166     int                         i;
1167     int                         alldel;
1168     int                         delcount;
1169
1170     uifw_trace("ico_set_input_region: Enter(%s %d/%d-%d/%d(%d/%d) %d/%d-%d/%d)",
1171                set ? "Set" : "Unset", x, y, width, height, hotspot_x, hotspot_y,
1172                cursor_x, cursor_y, cursor_width, cursor_height);
1173
1174     if (set)    {
1175         if (wl_list_empty(&pInputMgr->free_region)) {
1176             p = malloc(sizeof(struct uifw_region_mng) * 50);
1177             if (! p)    {
1178                 uifw_error("ico_set_input_region: No Memory");
1179                 return;
1180             }
1181             memset(p, 0, sizeof(struct uifw_region_mng)*50);
1182             for (i = 0; i < 50; i++, p++)  {
1183                 wl_list_insert(pInputMgr->free_region.prev, &p->link);
1184             }
1185         }
1186         p = container_of(pInputMgr->free_region.next, struct uifw_region_mng, link);
1187         wl_list_remove(&p->link);
1188         p->region.node = usurf->node_tbl->node;
1189         p->region.surfaceid = usurf->surfaceid;
1190         p->region.surface_x = usurf->x;
1191         p->region.surface_y = usurf->y;
1192         p->region.x = x;
1193         p->region.y = y;
1194         p->region.width = width;
1195         p->region.height = height;
1196         if ((hotspot_x <= 0) && (hotspot_y <= 0))   {
1197             p->region.hotspot_x = width / 2;
1198             p->region.hotspot_y = height / 2;
1199         }
1200         else    {
1201             p->region.hotspot_x = hotspot_x;
1202             p->region.hotspot_y = hotspot_y;
1203         }
1204         if ((cursor_width <= 0) && (cursor_height <= 0))    {
1205             p->region.cursor_x = x;
1206             p->region.cursor_y = y;
1207             p->region.cursor_width = width;
1208             p->region.cursor_height = height;
1209         }
1210         else    {
1211             p->region.cursor_x = cursor_x;
1212             p->region.cursor_y = cursor_y;
1213             p->region.cursor_width = cursor_width;
1214             p->region.cursor_height = cursor_height;
1215         }
1216         p->region.change = ico_window_mgr_is_visible(usurf);
1217         wl_list_insert(usurf->input_region.prev, &p->link);
1218
1219         /* send input region to haptic device input controller  */
1220         if (p->region.change > 0)   {
1221             wl_array_init(&array);
1222             rp = (struct ico_uifw_input_region *)
1223                      wl_array_add(&array, sizeof(struct ico_uifw_input_region));
1224             if (rp) {
1225                 memcpy(rp, &p->region, sizeof(struct ico_uifw_input_region));
1226                 rp->change = ICO_INPUT_MGR_DEVICE_REGION_ADD;
1227                 ico_input_send_region_event(&array);
1228             }
1229             uifw_trace("ico_set_input_region: Leave(Set)");
1230         }
1231         else    {
1232             uifw_trace("ico_set_input_region: Leave(Set but Unvisible)");
1233         }
1234     }
1235     else    {
1236         delcount = 0;
1237
1238         if ((x <= 0) && (y <= 0) && (width <= 0) && (height <= 0))  {
1239             alldel = 1;
1240         }
1241         else    {
1242             alldel = 0;
1243         }
1244
1245         wl_array_init(&array);
1246
1247         wl_list_for_each_safe(p, np, &usurf->input_region, link)    {
1248             if ((alldel != 0) ||
1249                 ((x == p->region.x) && (y == p->region.y) &&
1250                  (width == p->region.width) && (height == p->region.height)))   {
1251                 if (p->region.change > 0)   {
1252                     /* visible, send remove event   */
1253                     rp = (struct ico_uifw_input_region *)
1254                          wl_array_add(&array, sizeof(struct ico_uifw_input_region));
1255                     if (rp) {
1256                         delcount ++;
1257                         memcpy(rp, &p->region, sizeof(struct ico_uifw_input_region));
1258                         rp->change = ICO_INPUT_MGR_DEVICE_REGION_REMOVE;
1259                     }
1260                 }
1261                 wl_list_remove(&p->link);
1262                 wl_list_insert(pInputMgr->free_region.prev, &p->link);
1263             }
1264         }
1265         if (delcount > 0)   {
1266             /* send region delete to haptic device input controller */
1267             ico_input_send_region_event(&array);
1268         }
1269         uifw_trace("ico_set_input_region: Leave(Unset)");
1270     }
1271 }
1272
1273 /*--------------------------------------------------------------------------*/
1274 /**
1275  * @brief   ico_input_send_region_event: send region event to Haptic dic
1276  *
1277  * @param[in]   usurf           UIFW surface
1278  * @return      none
1279  */
1280 /*--------------------------------------------------------------------------*/
1281 static void
1282 ico_input_send_region_event(struct wl_array *array)
1283 {
1284     struct ico_ictl_mgr     *pIctlMgr;
1285
1286     wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)   {
1287         if ((pIctlMgr->type == ICO_INPUT_MGR_DEVICE_TYPE_HAPTIC) &&
1288             (pIctlMgr->mgr_resource != NULL))   {
1289             uifw_trace("ico_input_send_region_event: send event to Hapfic");
1290             ico_input_mgr_device_send_input_regions(pIctlMgr->mgr_resource, array);
1291         }
1292     }
1293 }
1294
1295 /*--------------------------------------------------------------------------*/
1296 /**
1297  * @brief   ico_device_configure_input: configure input device and input switch
1298  *          from Device Input Controller.
1299  *
1300  * @param[in]   client          client(Device Input Controller)
1301  * @param[in]   resource        resource of request
1302  * @param[in]   device          device name
1303  * @param[in]   type            device type(saved but unused)
1304  * @param[in]   swname          input switch name
1305  * @param[in]   input           input switch number
1306  * @param[in]   codename        input code name
1307  * @param[in]   code            input code number
1308  * @return      none
1309  */
1310 /*--------------------------------------------------------------------------*/
1311 static void
1312 ico_device_configure_input(struct wl_client *client, struct wl_resource *resource,
1313                            const char *device, int32_t type, const char *swname,
1314                            int32_t input, const char *codename, int32_t code)
1315 {
1316     struct uifw_client      *uclient;
1317     struct ico_ictl_mgr     *pIctlMgr;
1318     struct ico_ictl_mgr     *psameIctlMgr;
1319     struct ico_ictl_input   *pInput;
1320     struct ico_app_mgr      *pAppMgr;
1321
1322     uifw_trace("ico_device_configure_input: Enter(client=%08x,dev=%s,type=%d,swname=%s,"
1323                "input=%d,code=%d[%s])", (int)client, device, type,
1324                swname ? swname : "(NULL)", input, code, codename ? codename : " ");
1325
1326     /* check for access control         */
1327     if (resource != NULL)   {
1328         /* resource is NULL, internal use   */
1329         uclient = ico_window_mgr_find_uclient(client);
1330         if (! uclient)  {
1331             wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
1332                                    "ico_input_mgr_device_configure_input: unknown client");
1333             uifw_trace("ico_device_configure_input: Leave(unknown client=%08x)", (int)client);
1334             return;
1335         }
1336         if ((uclient->api_access_control & ICO_UIFW_INPUT_MGR_DEVICE_CONFIGURE_INPUT) == 0) {
1337             wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
1338                                    "ico_input_mgr_device_configure_input: not permitted");
1339             uifw_trace("ico_device_configure_input: Leave(%s not permitted)", uclient->appid);
1340             return;
1341         }
1342     }
1343     pIctlMgr = find_ictlmgr_by_device(device);
1344     if (! pIctlMgr) {
1345         /* search binded table      */
1346         psameIctlMgr = NULL;
1347         wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)    {
1348             if (pIctlMgr->client == client) {
1349                 uifw_trace("ico_device_configure_input: set pIctlMgr"
1350                            "(mgr=%08x,input=%d,dev=%s)", (int)pIctlMgr,
1351                            input, pIctlMgr->device);
1352                 if (pIctlMgr->device[0] != 0)   {
1353                     /* save same device         */
1354                     psameIctlMgr = pIctlMgr;
1355                 }
1356                 else    {
1357                     /* first device             */
1358                     strncpy(pIctlMgr->device, device, sizeof(pIctlMgr->device)-1);
1359                     psameIctlMgr = NULL;
1360                     break;
1361                 }
1362             }
1363         }
1364         if (psameIctlMgr)   {
1365             /* client(device input controller) exist, but other device  */
1366             pIctlMgr = (struct ico_ictl_mgr *)malloc(sizeof(struct ico_ictl_mgr));
1367             if (pIctlMgr == NULL) {
1368                 uifw_error("ico_device_bind: Leave(No Memory)");
1369                 return;
1370             }
1371             memset(pIctlMgr, 0, sizeof(struct ico_ictl_mgr));
1372             wl_list_init(&pIctlMgr->ico_ictl_input);
1373             pIctlMgr->client = psameIctlMgr->client;
1374             pIctlMgr->mgr_resource = psameIctlMgr->mgr_resource;
1375
1376             wl_list_insert(pInputMgr->ictl_list.prev, &pIctlMgr->link);
1377         }
1378     }
1379
1380     if (type)   {
1381         pIctlMgr->type = type;
1382     }
1383
1384     /* search and add input switch  */
1385     wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
1386         if (pInput->input == input)     break;
1387     }
1388     if (&pInput->link == &pIctlMgr->ico_ictl_input)    {
1389         uifw_trace("ico_device_configure_input: create %s.%s(%d) switch",
1390                    device, swname, input);
1391         pInput = (struct ico_ictl_input *)malloc(sizeof(struct ico_ictl_input));
1392         if (pInput == NULL) {
1393             uifw_error("ico_device_configure_input: Leave(No Memory)");
1394             return;
1395         }
1396         memset(pInput, 0, sizeof(struct ico_ictl_input));
1397         if (swname) {
1398             strncpy(pInput->swname, swname, sizeof(pInput->swname)-1);
1399         }
1400         else    {
1401             strcpy(pInput->swname, "(Unknown)");
1402         }
1403         wl_list_insert(pIctlMgr->ico_ictl_input.prev, &pInput->link);
1404     }
1405     if (swname) {
1406         strncpy(pInput->swname, swname, sizeof(pInput->swname)-1);
1407     }
1408     pInput->input = input;
1409     memset(pInput->code, 0, sizeof(pInput->code));
1410     pInput->ncode = 1;
1411     pInput->code[0].code = code;
1412     if (codename)   {
1413         strncpy(pInput->code[0].name, codename, sizeof(pInput->code[0].name)-1);
1414     }
1415
1416     if (client == NULL) {
1417         /* internal call for table create   */
1418         uifw_trace("ico_device_configure_input: Leave(table create)");
1419         return;
1420     }
1421     pIctlMgr->client = client;
1422
1423     /* send to application and manager(ex.HomeScreen)   */
1424     wl_list_for_each (pAppMgr, &pInputMgr->app_list, link)  {
1425         if (pAppMgr->resource == NULL)  continue;
1426         if ((pInput->app != NULL) && (pInput->app != pAppMgr) && (pInput->fix)) continue;
1427
1428         uifw_trace("ico_device_configure_input: send capabilities to app(%s) %s.%s[%d]",
1429                    pAppMgr->appid, device, pInput->swname, input);
1430         ico_exinput_send_capabilities(pAppMgr->resource, device, pIctlMgr->type,
1431                                       pInput->swname, input,
1432                                       pInput->code[0].name, pInput->code[0].code);
1433     }
1434     uifw_trace("ico_device_configure_input: Leave");
1435 }
1436
1437 /*--------------------------------------------------------------------------*/
1438 /**
1439  * @brief   ico_device_configure_code: add input switch from Device Input Controller.
1440  *
1441  * @param[in]   client          client(Device Input Controller)
1442  * @param[in]   resource        resource of request
1443  * @param[in]   device          device name
1444  * @param[in]   input           input switch number
1445  * @param[in]   codename        input code name
1446  * @param[in]   code            input code number
1447  * @return      none
1448  */
1449 /*--------------------------------------------------------------------------*/
1450 static void
1451 ico_device_configure_code(struct wl_client *client, struct wl_resource *resource,
1452                           const char *device, int32_t input,
1453                           const char *codename, int32_t code)
1454 {
1455     struct uifw_client      *uclient;
1456     int     i;
1457     struct ico_ictl_mgr     *pIctlMgr;
1458     struct ico_ictl_input   *pInput;
1459     struct ico_app_mgr      *pAppMgr;
1460
1461     uifw_trace("ico_device_configure_code: Enter(client=%08x,dev=%s,input=%d,code=%d[%s])",
1462                (int)client, device, input, code, codename ? codename : " ");
1463
1464     /* check for access control         */
1465     if (resource != NULL)   {
1466         /* resource is NULL, internal use   */
1467         uclient = ico_window_mgr_find_uclient(client);
1468         if (! uclient)  {
1469             wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
1470                                    "ico_input_mgr_device_configure_code: unknown client");
1471             uifw_trace("ico_device_configure_code: Leave(unknown client=%08x)", (int)client);
1472             return;
1473         }
1474         if ((uclient->api_access_control & ICO_UIFW_INPUT_MGR_DEVICE_CONFIGURE_CODE) == 0) {
1475             wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
1476                                    "ico_input_mgr_device_configure_code: not permitted");
1477             uifw_trace("ico_device_configure_code: Leave(%s not permitted)", uclient->appid);
1478             return;
1479         }
1480     }
1481     pIctlMgr = find_ictlmgr_by_device(device);
1482     if (! pIctlMgr) {
1483         uifw_warn("ico_device_configure_code: Leave(dev=%s dose not exist)", device);
1484         return;
1485     }
1486     /* search input switch      */
1487     wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
1488         if (pInput->input == input)     break;
1489     }
1490     if (&pInput->link == &pIctlMgr->ico_ictl_input)    {
1491         uifw_warn("ico_device_configure_code: Leave(input=%s.%d dose not exist)",
1492                   device, input);
1493         return;
1494     }
1495
1496     /* search input code        */
1497     for (i = 0; i < pInput->ncode; i++) {
1498         if (pInput->code[i].code == code)   break;
1499     }
1500     if (i >= pInput->ncode) {
1501         /* code dose not exist, add */
1502         if (pInput->ncode >= ICO_MINPUT_MAX_CODES) {
1503             uifw_warn("ico_device_configure_code: Leave(input=%s.%d code overflow)",
1504                       device, input);
1505             return;
1506         }
1507         i = pInput->ncode;
1508         pInput->ncode ++;
1509         pInput->code[i].code = code;
1510     }
1511     memset(pInput->code[i].name, 0, sizeof(pInput->code[i].name));
1512     strncpy(pInput->code[i].name, codename, sizeof(pInput->code[i].name)-1);
1513
1514     /* send to application and manager(ex.HomeScreen)   */
1515     wl_list_for_each (pAppMgr, &pInputMgr->app_list, link)  {
1516         if (pAppMgr->resource == NULL)  continue;
1517         if ((pInput->app != NULL) && (pInput->app != pAppMgr) && (pInput->fix)) continue;
1518         uifw_trace("ico_device_configure_input: send code to app(%s) %s.%s[%d]",
1519                    pAppMgr->appid, device, pInput->swname, input);
1520         ico_exinput_send_code(pAppMgr->resource, device, input,
1521                               pInput->code[i].name, pInput->code[i].code);
1522     }
1523     uifw_trace("ico_device_configure_code: Leave");
1524 }
1525
1526 /*--------------------------------------------------------------------------*/
1527 /**
1528  * @brief   ico_device_input_event: device input event from Device Input Controller.
1529  *
1530  * @param[in]   client          client(Device Input Controller)
1531  * @param[in]   resource        resource of request
1532  * @param[in]   time            device input time(miri-sec)
1533  * @param[in]   device          device name
1534  * @param[in]   input           input switch number
1535  * @param[in]   code            input code number
1536  * @param[in]   state           input state(1=On, 0=Off)
1537  * @return      none
1538  */
1539 /*--------------------------------------------------------------------------*/
1540 static void
1541 ico_device_input_event(struct wl_client *client, struct wl_resource *resource,
1542                        uint32_t time, const char *device,
1543                        int32_t input, int32_t code, int32_t state)
1544 {
1545     struct uifw_client      *uclient;
1546     struct ico_ictl_mgr     *pIctlMgr;
1547     struct ico_ictl_input   *pInput;
1548
1549     uifw_trace("ico_device_input_event: Enter(time=%d,dev=%s,input=%d,code=%d,state=%d)",
1550                time, device, input, code, state);
1551
1552     /* check for access control         */
1553     if (resource != NULL)   {
1554         /* resource is NULL, internal use   */
1555         uclient = ico_window_mgr_find_uclient(client);
1556         if (! uclient)  {
1557             wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
1558                                    "ico_input_mgr_device_input_event: unknown client");
1559             uifw_trace("ico_device_input_event: Leave(unknown client=%08x)", (int)client);
1560             return;
1561         }
1562         if ((uclient->api_access_control & ICO_UIFW_INPUT_MGR_DEVICE_INPUT_EVENT) == 0) {
1563             wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
1564                                    "ico_input_mgr_device_input_event: not permitted");
1565             uifw_trace("ico_device_input_event: Leave(%s not permitted)", uclient->appid);
1566             return;
1567         }
1568     }
1569     /* find input devcie by client      */
1570     pIctlMgr = find_ictlmgr_by_device(device);
1571     if (! pIctlMgr) {
1572         uifw_error("ico_device_input_event: Leave(Unknown device(%s))", device);
1573         return;
1574     }
1575     /* find input switch by input Id    */
1576     pInput = find_ictlinput_by_input(pIctlMgr, input);
1577     if (! pInput) {
1578         uifw_warn("ico_device_input_event: Leave(Unknown input(%s,%d))",
1579                   pIctlMgr->device, input);
1580         return;
1581     }
1582
1583     if (! pInput->app)  {
1584         uifw_trace("ico_device_input_event: Leave(%s.%s not assign)",
1585                   pIctlMgr->device, pInput->swname);
1586         return;
1587     }
1588     if (! pInput->app->resource) {
1589         uifw_trace("ico_device_input_event: Leave(%s.%s assigned App.%s "
1590                    "is not running or not interested)",
1591                    pIctlMgr->device, pInput->swname, pInput->app->appid);
1592         return;
1593     }
1594
1595     /* send event to application        */
1596     uifw_trace("ico_device_input_event: send event=%s.%s[%d],%d,%d to App.%s",
1597                pIctlMgr->device, pInput->swname, input, code, state, pInput->app->appid);
1598     ico_exinput_send_input(pInput->app->resource, time, pIctlMgr->device,
1599                            input, code, state);
1600
1601     uifw_trace("ico_device_input_event: Leave");
1602 }
1603
1604 /*--------------------------------------------------------------------------*/
1605 /**
1606  * @brief   ico_control_bind: ico_input_mgr_control bind from HomeScreen
1607  *
1608  * @param[in]   client          client(HomeScreen)
1609  * @param[in]   data            data(unused)
1610  * @param[in]   version         protocol version(unused)
1611  * @param[in]   id              client object id
1612  * @return      none
1613  */
1614 /*--------------------------------------------------------------------------*/
1615 static void
1616 ico_control_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
1617 {
1618     char                    *appid;
1619     struct ico_app_mgr      *pAppMgr;
1620
1621     uifw_trace("ico_control_bind: Enter(client=%08x)", (int)client);
1622     appid = ico_window_mgr_get_appid(client);
1623
1624     if (! appid)    {
1625         /* client dose not exist        */
1626         uifw_warn("ico_control_bind: Leave(client=%08x dose not exist)", (int)client);
1627         return;
1628     }
1629
1630     /* find application         */
1631     pAppMgr = find_app_by_appid(appid);
1632     if (! pAppMgr)  {
1633         /* create Application Management Table  */
1634         pAppMgr = (struct ico_app_mgr *)malloc(sizeof(struct ico_app_mgr));
1635         if (! pAppMgr)  {
1636             uifw_error("ico_control_bind: Leave(No Memory)");
1637             return;
1638         }
1639         memset(pAppMgr, 0, sizeof(struct ico_app_mgr));
1640         strncpy(pAppMgr->appid, appid, sizeof(pAppMgr->appid)-1);
1641         wl_list_insert(pInputMgr->app_list.prev, &pAppMgr->link);
1642     }
1643     pAppMgr->client = client;
1644     if (! pAppMgr->mgr_resource)    {
1645         pAppMgr->mgr_resource = wl_resource_create(client,
1646                                                    &ico_input_mgr_control_interface, 1, id);
1647         if (pAppMgr->mgr_resource)  {
1648             wl_resource_set_implementation(pAppMgr->mgr_resource,
1649                                            &ico_input_mgr_implementation,
1650                                            pInputMgr, ico_control_unbind);
1651         }
1652     }
1653     uifw_trace("ico_control_bind: Leave");
1654 }
1655
1656 /*--------------------------------------------------------------------------*/
1657 /**
1658  * @brief   ico_control_unbind: ico_input_mgr_control unbind from HomeScreen
1659  *
1660  * @param[in]   resource        client resource(HomeScreen)
1661  * @return      none
1662  */
1663 /*--------------------------------------------------------------------------*/
1664 static void
1665 ico_control_unbind(struct wl_resource *resource)
1666 {
1667     struct ico_app_mgr  *pAppMgr;
1668
1669     uifw_trace("ico_control_unbind: Enter(resource=%08x)", (int)resource);
1670
1671     wl_list_for_each (pAppMgr, &pInputMgr->app_list, link)  {
1672         if (pAppMgr->mgr_resource == resource)  {
1673             uifw_trace("ico_control_unbind: find app.%s", pAppMgr->appid);
1674             pAppMgr->mgr_resource = NULL;
1675             break;
1676         }
1677     }
1678     uifw_trace("ico_control_unbind: Leave");
1679 }
1680
1681 /*--------------------------------------------------------------------------*/
1682 /**
1683  * @brief   ico_device_bind: ico_input_mgr_device bind from Device Input Controller
1684  *
1685  * @param[in]   client          client(Device Input Controller)
1686  * @param[in]   data            data(unused)
1687  * @param[in]   version         protocol version
1688  * @param[in]   id              client object id
1689  * @return      none
1690  */
1691 /*--------------------------------------------------------------------------*/
1692 static void
1693 ico_device_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
1694 {
1695     struct ico_ictl_mgr *pIctlMgr;
1696     struct wl_resource  *mgr_resource;
1697
1698     uifw_trace("ico_device_bind: Enter(client=%08x)", (int)client);
1699
1700     /* create ictl mgr table */
1701     pIctlMgr = (struct ico_ictl_mgr *)malloc(sizeof(struct ico_ictl_mgr));
1702     if (pIctlMgr == NULL) {
1703         uifw_error("ico_device_bind: Leave(No Memory)");
1704         return;
1705     }
1706     memset(pIctlMgr, 0, sizeof(struct ico_ictl_mgr));
1707     wl_list_init(&pIctlMgr->ico_ictl_input);
1708     pIctlMgr->client = client;
1709
1710     /* add list */
1711     wl_list_insert(pInputMgr->ictl_list.prev, &pIctlMgr->link);
1712
1713     mgr_resource = wl_resource_create(client, &ico_input_mgr_device_interface, 1, id);
1714     if (mgr_resource)   {
1715         pIctlMgr->mgr_resource = mgr_resource;
1716         wl_resource_set_implementation(mgr_resource, &input_mgr_ictl_implementation,
1717                                        pIctlMgr, ico_device_unbind);
1718     }
1719     uifw_trace("ico_device_bind: Leave");
1720 }
1721
1722 /*--------------------------------------------------------------------------*/
1723 /**
1724  * @brief   ico_device_unbind: ico_input_mgr_device unbind from Device Input Controller
1725  *
1726  * @param[in]   resource        client resource(Device Input Controller)
1727  * @return      none
1728  */
1729 /*--------------------------------------------------------------------------*/
1730 static void
1731 ico_device_unbind(struct wl_resource *resource)
1732 {
1733     uifw_trace("ico_device_unbind: Enter(resource=%08x)", (int)resource);
1734     uifw_trace("ico_device_unbind: Leave");
1735 }
1736
1737 /*--------------------------------------------------------------------------*/
1738 /**
1739  * @brief   ico_exinput_bind: ico_exinput bind from Application
1740  *
1741  * @param[in]   client          client(Application)
1742  * @param[in]   data            data(unused)
1743  * @param[in]   version         protocol version(unused)
1744  * @param[in]   id              client object id
1745  * @return      none
1746  */
1747 /*--------------------------------------------------------------------------*/
1748 static void
1749 ico_exinput_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
1750 {
1751     int                     i;
1752     char                    *appid;
1753     struct ico_app_mgr      *pAppMgr;
1754     struct ico_ictl_mgr     *pIctlMgr;
1755     struct ico_ictl_input   *pInput;
1756
1757     appid = ico_window_mgr_get_appid(client);
1758     uifw_trace("ico_exinput_bind: Enter(client=%08x,%s)", (int)client,
1759                appid ? appid : "(NULL)");
1760
1761     if (! appid)    {
1762         /* client dose not exist        */
1763         uifw_warn("ico_exinput_bind: Leave(client=%08x dose not exist)", (int)client);
1764         return;
1765     }
1766
1767     /* find application         */
1768     pAppMgr = find_app_by_appid(appid);
1769     if (! pAppMgr)  {
1770         /* create Application Management Table  */
1771         pAppMgr = (struct ico_app_mgr *)malloc(sizeof(struct ico_app_mgr));
1772         if (! pAppMgr)  {
1773             uifw_error("ico_exinput_bind: Leave(No Memory)");
1774             return;
1775         }
1776         memset(pAppMgr, 0, sizeof(struct ico_app_mgr));
1777         strncpy(pAppMgr->appid, appid, sizeof(pAppMgr->appid)-1);
1778         wl_list_insert(pInputMgr->app_list.prev, &pAppMgr->link);
1779         uifw_trace("ico_exinput_bind: Create App.%s table", appid);
1780     }
1781     pAppMgr->client = client;
1782     if (! pAppMgr->resource)    {
1783         pAppMgr->resource = wl_resource_create(client, &ico_exinput_interface, 1, id);
1784         if (pAppMgr->resource)  {
1785             wl_resource_set_implementation(pAppMgr->resource, &ico_exinput_implementation,
1786                                            pInputMgr, ico_exinput_unbind);
1787         }
1788     }
1789
1790     /* send all capabilities    */
1791     wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)    {
1792         if (pIctlMgr->client == NULL)   {
1793             uifw_trace("ico_exinput_bind: Input controller.%s not initialized",
1794                        pIctlMgr->device);
1795             continue;
1796         }
1797
1798         wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
1799             if (pInput->swname[0] == 0) {
1800                 uifw_trace("ico_exinput_bind: Input %s not initialized", pIctlMgr->device);
1801                 continue;
1802             }
1803             if ((pInput->app != NULL) && (pInput->app != pAppMgr) && (pInput->fix)) {
1804                 uifw_trace("ico_exinput_bind: Input %s.%s fixed assign to App.%s",
1805                            pIctlMgr->device, pInput->swname, pInput->app->appid);
1806                 continue;
1807             }
1808             uifw_trace("ico_exinput_bind: send capabilities to app(%s) %s.%s[%d]",
1809                        pAppMgr->appid, pIctlMgr->device, pInput->swname, pInput->input);
1810             ico_exinput_send_capabilities(pAppMgr->resource, pIctlMgr->device,
1811                                           pIctlMgr->type, pInput->swname, pInput->input,
1812                                           pInput->code[0].name, pInput->code[0].code);
1813             for (i = 1; i < pInput->ncode; i++) {
1814                 ico_exinput_send_code(pAppMgr->resource, pIctlMgr->device, pInput->input,
1815                                       pInput->code[i].name, pInput->code[i].code);
1816             }
1817         }
1818     }
1819     uifw_trace("ico_exinput_bind: Leave");
1820 }
1821
1822 /*--------------------------------------------------------------------------*/
1823 /**
1824  * @brief   ico_exinput_unbind: ico_exinput unbind from Application
1825  *
1826  * @param[in]   resource        client resource(Application)
1827  * @return      none
1828  */
1829 /*--------------------------------------------------------------------------*/
1830 static void
1831 ico_exinput_unbind(struct wl_resource *resource)
1832 {
1833     struct ico_app_mgr      *pAppMgr;
1834     struct ico_app_mgr      *pAppMgrTmp;
1835     struct ico_ictl_mgr     *pIctlMgr;
1836     struct ico_ictl_input   *pInput;
1837     int                     fix = 0;
1838
1839     uifw_trace("ico_exinput_unbind: Enter(resource=%08x)", (int)resource);
1840
1841     wl_list_for_each_safe (pAppMgr, pAppMgrTmp, &pInputMgr->app_list, link) {
1842         if (pAppMgr->resource == resource)  {
1843             uifw_trace("ico_exinput_unbind: find app.%s", pAppMgr->appid);
1844
1845             /* release application from input switch    */
1846             wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)    {
1847                 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
1848                     if (pInput->app == pAppMgr) {
1849                         if (pInput->fix == 0)   {
1850                             uifw_trace("ico_exinput_unbind: app.%s remove %s.%s",
1851                                        pAppMgr->appid, pIctlMgr->device, pInput->swname);
1852                             pInput->app = NULL;
1853                         }
1854                         else    {
1855                             uifw_trace("ico_exinput_unbind: app.%s fix assign %s.%s",
1856                                        pAppMgr->appid, pIctlMgr->device, pInput->swname);
1857                             fix ++;
1858                         }
1859                     }
1860                 }
1861             }
1862             if (fix == 0)   {
1863                 wl_list_remove(&pAppMgr->link);
1864                 free(pAppMgr);
1865             }
1866             else    {
1867                 pAppMgr->client = NULL;
1868                 pAppMgr->resource = NULL;
1869             }
1870         }
1871     }
1872     uifw_trace("ico_exinput_unbind: Leave");
1873 }
1874
1875 /*--------------------------------------------------------------------------*/
1876 /**
1877  * @brief   find_ictlmgr_by_device: find Input Controller by device name
1878  *
1879  * @param[in]   device          device name
1880  * @return      Input Controller Manager table address
1881  * @retval      !=NULL          address
1882  * @retval      ==NULL          not exist
1883  */
1884 /*--------------------------------------------------------------------------*/
1885 static struct ico_ictl_mgr *
1886 find_ictlmgr_by_device(const char *device)
1887 {
1888     struct ico_ictl_mgr     *pIctlMgr;
1889
1890     wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)    {
1891         uifw_debug("find_ictlmgr_by_device: <%s> vs <%s>", device, pIctlMgr->device);
1892         if (strcmp(pIctlMgr->device, device) == 0)  {
1893             return pIctlMgr;
1894         }
1895     }
1896     return NULL;
1897 }
1898
1899 /*--------------------------------------------------------------------------*/
1900 /**
1901  * @brief   find_ictlinput_by_input: find Input Switch by input Id
1902  *
1903  * @param[in]   pIctlMgr        Input Controller device
1904  * @param[in]   input           Input Id
1905  * @return      Input Switch table address
1906  * @retval      !=NULL          address
1907  * @retval      ==NULL          not exist
1908  */
1909 /*--------------------------------------------------------------------------*/
1910 static struct ico_ictl_input *
1911 find_ictlinput_by_input(struct ico_ictl_mgr *pIctlMgr, const int32_t input)
1912 {
1913     struct ico_ictl_input   *pInput;
1914
1915     wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
1916         if (pInput->input == input) {
1917             return pInput;
1918         }
1919     }
1920     return NULL;
1921 }
1922
1923 /*--------------------------------------------------------------------------*/
1924 /**
1925  * @brief   find_app_by_appid: find Application by application Id
1926  *
1927  * @param[in]   appid           application Id
1928  * @return      Application Management table address
1929  * @retval      !=NULL          address
1930  * @retval      ==NULL          not exist
1931  */
1932 /*--------------------------------------------------------------------------*/
1933 static struct ico_app_mgr *
1934 find_app_by_appid(const char *appid)
1935 {
1936     struct ico_app_mgr      *pAppMgr;
1937
1938     wl_list_for_each (pAppMgr, &pInputMgr->app_list, link)  {
1939         if (strcmp(pAppMgr->appid, appid) == 0) {
1940             return pAppMgr;
1941         }
1942     }
1943     return NULL;
1944 }
1945
1946 /*--------------------------------------------------------------------------*/
1947 /**
1948  * @brief   module_init: initialization of this plugin
1949  *
1950  * @param[in]   ec          weston compositor
1951  * @param[in]   argc        number of arguments(unused)
1952  * @param[in]   argv        argument list(unused)
1953  * @return      result
1954  * @retval      0           OK
1955  * @retval      -1          error
1956  */
1957 /*--------------------------------------------------------------------------*/
1958 WL_EXPORT int
1959 module_init(struct weston_compositor *ec, int *argc, char *argv[])
1960 {
1961     struct uifw_region_mng  *p;
1962     int     i;
1963
1964     uifw_info("ico_input_mgr: Enter(module_init)");
1965
1966     /* initialize management table */
1967     pInputMgr = (struct ico_input_mgr *)malloc(sizeof(struct ico_input_mgr));
1968     if (pInputMgr == NULL) {
1969         uifw_trace("ico_input_mgr: malloc failed");
1970         return -1;
1971     }
1972     memset(pInputMgr, 0, sizeof(struct ico_input_mgr));
1973     pInputMgr->compositor = ec;
1974
1975     /* interface to desktop manager(ex.HomeScreen)  */
1976     if (wl_global_create(ec->wl_display, &ico_input_mgr_control_interface, 1,
1977                          pInputMgr, ico_control_bind) == NULL) {
1978         uifw_trace("ico_input_mgr: wl_global_create mgr failed");
1979         return -1;
1980     }
1981
1982     /* interface to Input Controller(ictl) */
1983     if (wl_global_create(ec->wl_display, &ico_input_mgr_device_interface, 1,
1984                          pInputMgr, ico_device_bind) == NULL) {
1985         uifw_trace("ico_input_mgr: wl_global_create ictl failed");
1986         return -1;
1987     }
1988
1989     /* interface to App(exinput) */
1990     if (wl_global_create(ec->wl_display, &ico_exinput_interface, 1,
1991                          pInputMgr, ico_exinput_bind) == NULL) {
1992         uifw_trace("ico_input_mgr: wl_global_create exseat failed");
1993         return -1;
1994     }
1995
1996     /* initialize list */
1997     wl_list_init(&pInputMgr->ictl_list);
1998     wl_list_init(&pInputMgr->app_list);
1999     wl_list_init(&pInputMgr->dev_list);
2000     wl_list_init(&pInputMgr->free_region);
2001     p = malloc(sizeof(struct uifw_region_mng)*100);
2002     if (p)  {
2003         memset(p, 0, sizeof(struct uifw_region_mng)*100);
2004         for (i = 0; i < 100; i++, p++)  {
2005             wl_list_insert(pInputMgr->free_region.prev, &p->link);
2006         }
2007     }
2008
2009     /* found input seat */
2010     pInputMgr->seat = container_of(ec->seat_list.next, struct weston_seat, link);
2011
2012     /* set hook for input region control    */
2013     ico_window_mgr_set_hook_change(ico_input_hook_region_change);
2014     ico_window_mgr_set_hook_destory(ico_input_hook_region_destroy);
2015     ico_window_mgr_set_hook_inputregion(ico_set_input_region);
2016
2017     uifw_info("ico_input_mgr: Leave(module_init)");
2018     return 0;
2019 }
2020