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