609e226b030d8e5b765f9dab17628db0a2ed1392
[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_input_mgr-server-protocol.h"
49
50 /* degine maximum length                */
51 #define ICO_MINPUT_DEVICE_LEN           32
52 #define ICO_MINPUT_SW_LEN               20
53 #define ICO_MINPUT_MAX_CODES            20
54
55 /* structure definition */
56 /* working table of Multi Input Manager */
57 struct ico_input_mgr {
58     struct weston_compositor *compositor;   /* Weston Compositor                    */
59     struct wl_list  ictl_list;              /* Input Controller List                */
60     struct wl_list  app_list;               /* application List                     */
61     struct wl_resource *inputmgr;
62 };
63
64 /* Input Switch Table                   */
65 struct ico_ictl_code {
66     uint16_t    code;                       /* input code numner                    */
67     char        name[ICO_MINPUT_SW_LEN];    /* input code name                      */
68 };
69
70 struct ico_ictl_input {
71     struct wl_list link;                    /* link                                 */
72     char        swname[ICO_MINPUT_SW_LEN];  /* input switch name                    */
73     int32_t     input;                      /* input Id                             */
74     uint16_t    fix;                        /* fixed assign to application          */
75     uint16_t    ncode;                      /* number of codes                      */
76     struct ico_ictl_code code[ICO_MINPUT_MAX_CODES];   /* codes                     */
77     struct ico_app_mgr  *app;               /* send event tagret application        */
78 };
79
80 /* Input Controller Management Table    */
81 struct ico_ictl_mgr {
82     struct wl_list link;                    /* link                                 */
83     struct wl_client    *client;            /* client                               */
84     struct wl_resource  *resource;          /* resource                             */
85     char    device[ICO_MINPUT_DEVICE_LEN];  /* device name                          */
86     int     type;                           /* device type                          */
87     struct wl_list ico_ictl_input;          /* list of input switchs                */
88 };
89
90 /* Application Management Table */
91 struct ico_app_mgr {
92     struct wl_list link;                    /* link                                 */
93     struct wl_client    *client;            /* client                               */
94     struct wl_resource  *resource;          /* resource for send event              */
95     struct wl_resource  *mgr_resource;      /* resource as manager(if NULL, client) */
96     char    appid[ICO_IVI_APPID_LENGTH];    /* application id                       */
97 };
98
99 /* prototype of static function */
100                                             /* bind input manager form manager      */
101 static void ico_control_bind(struct wl_client *client, void *data,
102                              uint32_t version, uint32_t id);
103                                             /* unbind input manager form manager    */
104 static void ico_control_unbind(struct wl_resource *resource);
105                                             /* bind input manager form input controller*/
106 static void ico_device_bind(struct wl_client *client, void *data,
107                             uint32_t version, uint32_t id);
108                                             /* unbind input manager form input controller*/
109 static void ico_device_unbind(struct wl_resource *resource);
110                                             /* bind input manager(form application) */
111 static void ico_exinput_bind(struct wl_client *client, void *data,
112                              uint32_t version, uint32_t id);
113                                             /* unbind input manager(form application)*/
114 static void ico_exinput_unbind(struct wl_resource *resource);
115
116                                             /* find ictl manager by device name     */
117 static struct ico_ictl_mgr *find_ictlmgr_by_device(const char *device);
118                                             /* find ictl input switch by input Id   */
119 static struct ico_ictl_input *find_ictlinput_by_input(struct ico_ictl_mgr *pIctlMgr,
120                                                       const int32_t input);
121                                             /* find app manager by application Id   */
122 static struct ico_app_mgr *find_app_by_appid(const char *appid);
123                                             /* add input event to application       */
124 static void ico_mgr_add_input_app(struct wl_client *client, struct wl_resource *resource,
125                                   const char *appid, const char *device, int32_t input,
126                                   int32_t fix, int32_t keycode);
127                                             /* delete input event to application    */
128 static void ico_mgr_del_input_app(struct wl_client *client, struct wl_resource *resource,
129                                   const char *appid, const char *device, int32_t input);
130                                             /* send input event from manager        */
131 static void ico_mgr_send_input_event(struct wl_client *client, struct wl_resource *resource,
132                                      const char *appid, uint32_t surfaceid, int32_t type,
133                                      int32_t deviceno, int32_t code, int32_t value);
134                                             /* create and regist Input Controller table*/
135 static void ico_device_configure_input(struct wl_client *client,
136                                        struct wl_resource *resource, const char *device,
137                                        int32_t type, const char *swname, int32_t input,
138                                        const char *codename, int32_t code);
139                                             /* add input to from Input Controller table*/
140 static void ico_device_configure_code(struct wl_client *client,
141                                       struct wl_resource *resource, const char *device,
142                                       int32_t input, const char *codename, int32_t code);
143                                             /* device input event                   */
144 static void ico_device_input_event(struct wl_client *client, struct wl_resource *resource,
145                                    uint32_t time, const char *device,
146                                    int32_t input, int32_t code, int32_t state);
147
148 /* definition of Wayland protocol       */
149 /* mgr interface                */
150 static const struct ico_input_mgr_control_interface ico_input_mgr_implementation = {
151     ico_mgr_add_input_app,
152     ico_mgr_del_input_app,
153     ico_mgr_send_input_event
154 };
155
156 /* Input Controller interface */
157 static const struct ico_input_mgr_device_interface input_mgr_ictl_implementation = {
158     ico_device_configure_input,
159     ico_device_configure_code,
160     ico_device_input_event
161 };
162
163 /* definition of class variable */
164 struct ico_input_mgr    *pInputMgr = NULL;
165
166 /* implementation */
167 /*--------------------------------------------------------------------------*/
168 /**
169  * @brief   ico_mgr_add_input_app: add input event to application from HomeScreen.
170  *
171  * @param[in]   client          client(HomeScreen)
172  * @param[in]   resource        resource of request
173  * @param[in]   appid           target application id
174  * @param[in]   device          device name
175  * @param[in]   input           input switch number
176  * @param[in]   fix             fix to application(1=fix,0=general)
177  * @param[in]   keycode         switch map to keyboard operation(0=not map to keyboard)
178  * @return      none
179  */
180 /*--------------------------------------------------------------------------*/
181 static void
182 ico_mgr_add_input_app(struct wl_client *client, struct wl_resource *resource,
183                       const char *appid, const char *device, int32_t input,
184                       int32_t fix, int32_t keycode)
185 {
186     uifw_trace("ico_mgr_add_input_app: Enter(appid=%s,dev=%s,input=%d,fix=%d,key=%d)",
187                appid, device, input, fix, keycode);
188
189     struct ico_ictl_mgr     *pIctlMgr;
190     struct ico_ictl_input   *pInput;
191     struct ico_app_mgr      *pAppMgr;
192
193     pIctlMgr = find_ictlmgr_by_device(device);
194     if (! pIctlMgr) {
195         /* not configure input controller, create   */
196         ico_device_configure_input(NULL, NULL, device, 0, NULL, input, NULL, 0);
197         pIctlMgr = find_ictlmgr_by_device(device);
198         if (! pIctlMgr) {
199             uifw_error("ico_mgr_add_input_app: Leave(No Memory)");
200             return;
201         }
202     }
203     pInput = find_ictlinput_by_input(pIctlMgr, input);
204     if (! pInput)   {
205         /* not configure input switch, create   */
206         ico_device_configure_input(NULL, NULL, device, 0, NULL, input, NULL, 0);
207         pInput = find_ictlinput_by_input(pIctlMgr, input);
208         if (! pInput)   {
209             uifw_error("ico_mgr_add_input_app: Leave(No Memory)");
210             return;
211         }
212     }
213
214     /* find application         */
215     pAppMgr = find_app_by_appid(appid);
216     if (! pAppMgr)  {
217         /* create Application Management Table  */
218         pAppMgr = (struct ico_app_mgr *)malloc(sizeof(struct ico_app_mgr));
219         if (! pAppMgr)  {
220             uifw_error("ico_mgr_add_input_app: Leave(No Memory)");
221             return;
222         }
223         memset(pAppMgr, 0, sizeof(struct ico_app_mgr));
224         strncpy(pAppMgr->appid, appid, sizeof(pAppMgr->appid)-1);
225         wl_list_insert(pInputMgr->app_list.prev, &pAppMgr->link);
226     }
227
228     pInput->app = pAppMgr;
229     pInput->fix = fix;
230     uifw_trace("ico_mgr_add_input_app: Leave(%s.%s[%d] assign to %s)",
231                pIctlMgr->device, pInput->swname ? pInput->swname : "(NULL)", input,
232                pAppMgr->appid);
233 }
234
235 /*--------------------------------------------------------------------------*/
236 /**
237  * @brief   ico_mgr_del_input_app: delete input event at application from HomeScreen.
238  *
239  * @param[in]   client          client(HomeScreen)
240  * @param[in]   resource        resource of request
241  * @param[in]   appid           target application id,
242  *                              if NULL, all applictions without fixed assign switch
243  * @param[in]   device          device name
244  *                              if NULL, all device without fixed assign switch
245  * @param[in]   input           input switch number
246  *                              if -1, all input without fixed assign switch
247  * @return      none
248  */
249 /*--------------------------------------------------------------------------*/
250 static void
251 ico_mgr_del_input_app(struct wl_client *client, struct wl_resource *resource,
252                       const char *appid, const char *device, int32_t input)
253 {
254     uifw_trace("ico_mgr_del_input_app: Enter(appid=%s,dev=%s,input=%d)",
255                appid ? appid : "(NULL)", device ? device : "(NULL)", input);
256
257     int     alldev = 0;
258     struct ico_ictl_mgr     *pIctlMgr = NULL;
259     struct ico_ictl_input   *pInput = NULL;
260     struct ico_app_mgr      *pAppMgr;
261
262     if ((device != NULL) && (*device != 0)) {
263         pIctlMgr = find_ictlmgr_by_device(device);
264         if (! pIctlMgr) {
265             /* not configure input controller, NOP  */
266             uifw_trace("ico_mgr_del_input_app: Leave(%s dose not exist)", device);
267             return;
268         }
269         if (input >= 0) {
270             pInput = find_ictlinput_by_input(pIctlMgr, input);
271             if (! pInput)   {
272                 /* not configure input switch, NOP  */
273                 uifw_trace("ico_mgr_del_input_app: Leave(%s.%d dose not exist)",
274                            device, input);
275                 return;
276             }
277         }
278     }
279     else    {
280         alldev = 1;
281     }
282
283     /* find application         */
284     if ((appid != NULL) && (*appid != 0))   {
285         pAppMgr = find_app_by_appid(appid);
286         if (! pAppMgr)  {
287             /* application dose not exist, NOP  */
288             uifw_trace("ico_mgr_del_input_app: Leave(app.%s dose not exist)", appid);
289             return;
290         }
291         if (alldev == 0)    {
292             if (input >= 0) {
293                 if (pInput->app != pAppMgr) {
294                     /* not same application, NOP        */
295                     uifw_trace("ico_mgr_del_input_app: Leave(%s.%d not app.%s, current %s)",
296                                device, input, appid,
297                                pInput->app ? pInput->app->appid : "(NULL)");
298                     return;
299                 }
300                 uifw_trace("ico_mgr_del_input_app: Leave(%s.%d app.%s deleted)",
301                            device, input, appid);
302                 pInput->app = NULL;
303                 return;
304             }
305             else    {
306                 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
307                     if ((pInput->fix == 0) && (pInput->app == pAppMgr))   {
308                         uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
309                                    pIctlMgr->device, pInput->input, appid);
310                         pInput->app = NULL;
311                     }
312                 }
313             }
314         }
315         else    {
316             /* reset all device without fixed assign    */
317             wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)    {
318                 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
319                     if ((pInput->fix == 0) && (pInput->app == pAppMgr))   {
320                         uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
321                                    pIctlMgr->device, pInput->input, pInput->app->appid);
322                         pInput->app = NULL;
323                     }
324                 }
325             }
326         }
327     }
328     else    {
329         if (alldev == 0)    {
330             if (input >= 0) {
331                 if ((pInput->fix == 0) && (pInput->app != NULL))    {
332                     uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
333                                pIctlMgr->device, pInput->input, pInput->app->appid);
334                     pInput->app = NULL;
335                 }
336             }
337             else    {
338                 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
339                     if ((pInput->fix == 0) && (pInput->app != NULL))    {
340                         uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
341                                pIctlMgr->device, pInput->input, pInput->app->appid);
342                         pInput->app = NULL;
343                     }
344                 }
345             }
346         }
347         else    {
348             /* reset all application without fixed assign       */
349             wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)    {
350                 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
351                     if ((pInput->fix == 0) && (pInput->app != NULL))    {
352                         uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
353                                    pIctlMgr->device, pInput->input, pInput->app->appid);
354                         pInput->app = NULL;
355                     }
356                 }
357             }
358         }
359     }
360     uifw_trace("ico_mgr_del_input_app: Leave");
361 }
362
363 /*--------------------------------------------------------------------------*/
364 /**
365  * @brief   ico_mgr_send_input_event: send input event from manager
366  *
367  * @param[in]   client          client(HomeScreen)
368  * @param[in]   resource        resource of request
369  * @param[in]   appid           target application id
370  * @param[in]   surfaceid       target surface id
371  * @param[in]   type            event device type
372  * @param[in]   deviceno        device number
373  * @param[in]   code            event code
374  * @param[in]   value           event value
375  * @return      none
376  */
377 /*--------------------------------------------------------------------------*/
378 static void
379 ico_mgr_send_input_event(struct wl_client *client, struct wl_resource *resource,
380                          const char *appid, uint32_t surfaceid, int32_t type,
381                          int32_t deviceno, int32_t code, int32_t value)
382 {
383     uifw_trace("ico_mgr_send_input_event: Enter(app=%s surf=%08x dev=%d code=%x value=%d)",
384                appid ? appid : "(NULL)", surfaceid, deviceno, code, value);
385
386     uifw_trace("ico_mgr_send_input_event: Leave");
387 }
388
389 /*--------------------------------------------------------------------------*/
390 /**
391  * @brief   ico_device_configure_input: configure input device and input switch
392  *          from Device Input Controller.
393  *
394  * @param[in]   client          client(Device Input Controller)
395  * @param[in]   resource        resource of request
396  * @param[in]   device          device name
397  * @param[in]   type            device type(saved but unused)
398  * @param[in]   swname          input switch name
399  * @param[in]   input           input switch number
400  * @param[in]   codename        input code name
401  * @param[in]   code            input code number
402  * @return      none
403  */
404 /*--------------------------------------------------------------------------*/
405 static void
406 ico_device_configure_input(struct wl_client *client, struct wl_resource *resource,
407                            const char *device, int32_t type, const char *swname,
408                            int32_t input, const char *codename, int32_t code)
409 {
410     uifw_trace("ico_device_configure_input: Enter(client=%08x,dev=%s,type=%d,swname=%s,"
411                "input=%d,code=%d[%s])", (int)client, device, type,
412                swname ? swname : "(NULL)", input, code, codename ? codename : " ");
413
414     struct ico_ictl_mgr     *pIctlMgr;
415     struct ico_ictl_input   *pInput;
416     struct ico_app_mgr      *pAppMgr;
417
418     pIctlMgr = find_ictlmgr_by_device(device);
419     if (! pIctlMgr) {
420         /* create ictl mgr table */
421         pIctlMgr = (struct ico_ictl_mgr *)malloc(sizeof(struct ico_ictl_mgr));
422         if (pIctlMgr == NULL) {
423             uifw_error("ico_device_configure_input: Leave(No Memory)");
424             return;
425         }
426         uifw_trace("ico_device_configure_input: create pIctlMgr(mgr=%08x,input=%d)",
427                    (int)pIctlMgr, input);
428         memset(pIctlMgr, 0, sizeof(struct ico_ictl_mgr));
429         wl_list_init(&pIctlMgr->ico_ictl_input);
430         strncpy(pIctlMgr->device, device, sizeof(pIctlMgr->device)-1);
431
432         /* add list */
433         wl_list_insert(pInputMgr->ictl_list.prev, &pIctlMgr->link);
434     }
435     pIctlMgr->client = client;
436     pIctlMgr->resource = resource;
437     if (type)   {
438         pIctlMgr->type = type;
439     }
440
441     /* search and add input switch  */
442     wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
443         if (pInput->input == input)     break;
444     }
445     if (&pInput->link == &pIctlMgr->ico_ictl_input)    {
446         uifw_trace("ico_device_configure_input: create %s.%s(%d) switch",
447                    device, swname, input);
448         pInput = (struct ico_ictl_input *)malloc(sizeof(struct ico_ictl_input));
449         if (pInput == NULL) {
450             uifw_error("ico_device_configure_input: Leave(No Memory)");
451             return;
452         }
453         memset(pInput, 0, sizeof(struct ico_ictl_input));
454         if (swname) {
455             strncpy(pInput->swname, swname, sizeof(pInput->swname)-1);
456         }
457         else    {
458             strcpy(pInput->swname, "(Unknown)");
459         }
460         wl_list_insert(pIctlMgr->ico_ictl_input.prev, &pInput->link);
461     }
462     if (swname) {
463         strncpy(pInput->swname, swname, sizeof(pInput->swname)-1);
464     }
465     pInput->input = input;
466     memset(pInput->code, 0, sizeof(pInput->code));
467     pInput->ncode = 1;
468     pInput->code[0].code = code;
469     if (codename)   {
470         strncpy(pInput->code[0].name, codename, sizeof(pInput->code[0].name)-1);
471     }
472
473     if (client == NULL) {
474         /* internal call for table create   */
475         uifw_trace("ico_device_configure_input: Leave(table create)");
476         return;
477     }
478
479     /* send to application and manager(ex.HomeScreen)   */
480     wl_list_for_each (pAppMgr, &pInputMgr->app_list, link)  {
481         if (pAppMgr->resource == NULL)  continue;
482         if ((pInput->app != NULL) && (pInput->app != pAppMgr) && (pInput->fix)) continue;
483
484         uifw_trace("ico_device_configure_input: send capabilities to app(%s) %s.%s[%d]",
485                    pAppMgr->appid, device, pInput->swname, input);
486         ico_exinput_send_capabilities(pAppMgr->resource, device, pIctlMgr->type,
487                                       pInput->swname, input,
488                                       pInput->code[0].name, pInput->code[0].code);
489     }
490     uifw_trace("ico_device_configure_input: Leave");
491 }
492
493 /*--------------------------------------------------------------------------*/
494 /**
495  * @brief   ico_device_configure_code: add input switch from Device Input Controller.
496  *
497  * @param[in]   client          client(Device Input Controller)
498  * @param[in]   resource        resource of request
499  * @param[in]   device          device name
500  * @param[in]   input           input switch number
501  * @param[in]   codename        input code name
502  * @param[in]   code            input code number
503  * @return      none
504  */
505 /*--------------------------------------------------------------------------*/
506 static void
507 ico_device_configure_code(struct wl_client *client, struct wl_resource *resource,
508                           const char *device, int32_t input,
509                           const char *codename, int32_t code)
510 {
511     uifw_trace("ico_device_configure_code: Enter(client=%08x,dev=%s,input=%d,code=%d[%s])",
512                (int)client, device, input, code, codename ? codename : " ");
513
514     int     i;
515     struct ico_ictl_mgr     *pIctlMgr;
516     struct ico_ictl_input   *pInput;
517     struct ico_app_mgr      *pAppMgr;
518
519     pIctlMgr = find_ictlmgr_by_device(device);
520     if (! pIctlMgr) {
521         uifw_warn("ico_device_configure_code: Leave(dev=%s dose not exist)", device);
522         return;
523     }
524     /* search input switch      */
525     wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
526         if (pInput->input == input)     break;
527     }
528     if (&pInput->link == &pIctlMgr->ico_ictl_input)    {
529         uifw_warn("ico_device_configure_code: Leave(input=%s.%d dose not exist)",
530                   device, input);
531         return;
532     }
533
534     /* search input code        */
535     for (i = 0; i < pInput->ncode; i++) {
536         if (pInput->code[i].code == code)   break;
537     }
538     if (i >= pInput->ncode) {
539         /* code dose not exist, add */
540         if (pInput->ncode >= ICO_MINPUT_MAX_CODES) {
541             uifw_warn("ico_device_configure_code: Leave(input=%s.%d code overflow)",
542                       device, input);
543             return;
544         }
545         i = pInput->ncode;
546         pInput->ncode ++;
547         pInput->code[i].code = code;
548     }
549     memset(pInput->code[i].name, 0, sizeof(pInput->code[i].name));
550     strncpy(pInput->code[i].name, codename, sizeof(pInput->code[i].name)-1);
551
552     /* send to application and manager(ex.HomeScreen)   */
553     wl_list_for_each (pAppMgr, &pInputMgr->app_list, link)  {
554         if (pAppMgr->resource == NULL)  continue;
555         if ((pInput->app != NULL) && (pInput->app != pAppMgr) && (pInput->fix)) continue;
556         uifw_trace("ico_device_configure_input: send code to app(%s) %s.%s[%d]",
557                    pAppMgr->appid, device, pInput->swname, input);
558         ico_exinput_send_code(pAppMgr->resource, device, input,
559                               pInput->code[i].name, pInput->code[i].code);
560     }
561     uifw_trace("ico_device_configure_code: Leave");
562 }
563
564 /*--------------------------------------------------------------------------*/
565 /**
566  * @brief   ico_device_input_event: device input event from Device Input Controller.
567  *
568  * @param[in]   client          client(Device Input Controller)
569  * @param[in]   resource        resource of request
570  * @param[in]   time            device input time(miri-sec)
571  * @param[in]   device          device name
572  * @param[in]   input           input switch number
573  * @param[in]   code            input code number
574  * @param[in]   state           input state(1=On, 0=Off)
575  * @return      none
576  */
577 /*--------------------------------------------------------------------------*/
578 static void
579 ico_device_input_event(struct wl_client *client, struct wl_resource *resource,
580                        uint32_t time, const char *device,
581                        int32_t input, int32_t code, int32_t state)
582 {
583     uifw_trace("ico_device_input_event: Enter(time=%d,dev=%s,input=%d,code=%d,state=%d)",
584                time, device, input, code, state);
585
586     struct ico_ictl_mgr     *pIctlMgr;
587     struct ico_ictl_input   *pInput;
588
589     /* find input devcie by client      */
590     pIctlMgr = find_ictlmgr_by_device(device);
591     if (! pIctlMgr) {
592         uifw_error("ico_device_input_event: Leave(Unknown client(%08x))", (int)client);
593         return;
594     }
595     /* find input switch by input Id    */
596     pInput = find_ictlinput_by_input(pIctlMgr, input);
597     if (! pInput) {
598         uifw_warn("ico_device_input_event: Leave(Unknown input(%s,%d))",
599                   pIctlMgr->device, input);
600         return;
601     }
602
603     if (! pInput->app)  {
604         uifw_trace("ico_device_input_event: Leave(%s.%s not assign)",
605                   pIctlMgr->device, pInput->swname);
606         return;
607     }
608
609     /* send event to application        */
610     uifw_trace("ico_device_input_event: send event=%s.%s[%d],%d,%d to App.%s",
611                pIctlMgr->device, pInput->swname, input, code, state, pInput->app->appid);
612     ico_exinput_send_input(pInput->app->resource, time, pIctlMgr->device,
613                            input, code, state);
614
615     uifw_trace("ico_device_input_event: Leave");
616 }
617
618 /*--------------------------------------------------------------------------*/
619 /**
620  * @brief   ico_control_bind: ico_input_mgr_control bind from HomeScreen
621  *
622  * @param[in]   client          client(HomeScreen)
623  * @param[in]   data            data(unused)
624  * @param[in]   version         protocol version(unused)
625  * @param[in]   id              client object id
626  * @return      none
627  */
628 /*--------------------------------------------------------------------------*/
629 static void
630 ico_control_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
631 {
632     char                    *appid;
633     struct ico_app_mgr      *pAppMgr;
634
635     uifw_trace("ico_control_bind: Enter(client=%08x)", (int)client);
636     appid = ico_window_mgr_get_appid(client);
637
638     if (! appid)    {
639         /* client dose not exist        */
640         uifw_warn("ico_control_bind: Leave(client=%08x dose not exist)", (int)client);
641         return;
642     }
643
644     /* find application         */
645     pAppMgr = find_app_by_appid(appid);
646     if (! pAppMgr)  {
647         /* create Application Management Table  */
648         pAppMgr = (struct ico_app_mgr *)malloc(sizeof(struct ico_app_mgr));
649         if (! pAppMgr)  {
650             uifw_error("ico_control_bind: Leave(No Memory)");
651             return;
652         }
653         memset(pAppMgr, 0, sizeof(struct ico_app_mgr));
654         strncpy(pAppMgr->appid, appid, sizeof(pAppMgr->appid)-1);
655         wl_list_insert(pInputMgr->app_list.prev, &pAppMgr->link);
656     }
657     pAppMgr->client = client;
658     if (! pAppMgr->mgr_resource)    {
659         pAppMgr->mgr_resource = wl_resource_create(client,
660                                                    &ico_input_mgr_control_interface, 1, id);
661         if (pAppMgr->mgr_resource)  {
662             wl_resource_set_implementation(pAppMgr->mgr_resource,
663                                            &ico_input_mgr_implementation,
664                                            pInputMgr, ico_control_unbind);
665         }
666     }
667     uifw_trace("ico_control_bind: Leave");
668 }
669
670 /*--------------------------------------------------------------------------*/
671 /**
672  * @brief   ico_control_unbind: ico_input_mgr_control unbind from HomeScreen
673  *
674  * @param[in]   resource        client resource(HomeScreen)
675  * @return      none
676  */
677 /*--------------------------------------------------------------------------*/
678 static void
679 ico_control_unbind(struct wl_resource *resource)
680 {
681     struct ico_app_mgr      *pAppMgr;
682
683     uifw_trace("ico_control_unbind: Enter(resource=%08x)", (int)resource);
684
685     wl_list_for_each (pAppMgr, &pInputMgr->app_list, link)  {
686         if (pAppMgr->mgr_resource == resource)  {
687             uifw_trace("ico_control_unbind: find app.%s", pAppMgr->appid);
688             pAppMgr->mgr_resource = NULL;
689             break;
690         }
691     }
692     uifw_trace("ico_control_unbind: Leave");
693 }
694
695 /*--------------------------------------------------------------------------*/
696 /**
697  * @brief   ico_device_bind: ico_input_mgr_device bind from Device Input Controller
698  *
699  * @param[in]   client          client(Device Input Controller)
700  * @param[in]   data            data(unused)
701  * @param[in]   version         protocol version(unused)
702  * @param[in]   id              client object id
703  * @return      none
704  */
705 /*--------------------------------------------------------------------------*/
706 static void
707 ico_device_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
708 {
709     struct wl_resource *mgr_resource;
710
711     uifw_trace("ico_device_bind: Enter(client=%08x)", (int)client);
712
713     mgr_resource = wl_resource_create(client, &ico_input_mgr_device_interface, 1, id);
714     if (mgr_resource)   {
715         wl_resource_set_implementation(mgr_resource, &input_mgr_ictl_implementation,
716                                        NULL, ico_device_unbind);
717     }
718     uifw_trace("ico_device_bind: Leave");
719 }
720
721 /*--------------------------------------------------------------------------*/
722 /**
723  * @brief   ico_device_unbind: ico_input_mgr_device unbind from Device Input Controller
724  *
725  * @param[in]   resource        client resource(Device Input Controller)
726  * @return      none
727  */
728 /*--------------------------------------------------------------------------*/
729 static void
730 ico_device_unbind(struct wl_resource *resource)
731 {
732     uifw_trace("ico_device_unbind: Enter(resource=%08x)", (int)resource);
733     uifw_trace("ico_device_unbind: Leave");
734 }
735
736 /*--------------------------------------------------------------------------*/
737 /**
738  * @brief   ico_exinput_bind: ico_exinput bind from Application
739  *
740  * @param[in]   client          client(Application)
741  * @param[in]   data            data(unused)
742  * @param[in]   version         protocol version(unused)
743  * @param[in]   id              client object id
744  * @return      none
745  */
746 /*--------------------------------------------------------------------------*/
747 static void
748 ico_exinput_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
749 {
750     int                     i;
751     char                    *appid;
752     struct ico_app_mgr      *pAppMgr;
753     struct ico_ictl_mgr     *pIctlMgr;
754     struct ico_ictl_input   *pInput;
755
756     appid = ico_window_mgr_get_appid(client);
757     uifw_trace("ico_exinput_bind: Enter(client=%08x,%s)", (int)client,
758                appid ? appid : "(NULL)");
759
760     if (! appid)    {
761         /* client dose not exist        */
762         uifw_warn("ico_exinput_bind: Leave(client=%08x dose not exist)", (int)client);
763         return;
764     }
765
766     /* find application         */
767     pAppMgr = find_app_by_appid(appid);
768     if (! pAppMgr)  {
769         /* create Application Management Table  */
770         pAppMgr = (struct ico_app_mgr *)malloc(sizeof(struct ico_app_mgr));
771         if (! pAppMgr)  {
772             uifw_error("ico_exinput_bind: Leave(No Memory)");
773             return;
774         }
775         memset(pAppMgr, 0, sizeof(struct ico_app_mgr));
776         strncpy(pAppMgr->appid, appid, sizeof(pAppMgr->appid)-1);
777         wl_list_insert(pInputMgr->app_list.prev, &pAppMgr->link);
778         uifw_trace("ico_exinput_bind: Create App.%s table", appid);
779     }
780     pAppMgr->client = client;
781     if (! pAppMgr->resource)    {
782         pAppMgr->resource = wl_resource_create(client, &ico_exinput_interface, 1, id);
783         if (pAppMgr->resource)  {
784             wl_resource_set_implementation(pAppMgr->resource, NULL,
785                                            pInputMgr, ico_exinput_unbind);
786         }
787     }
788
789     /* send all capabilities    */
790     wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)    {
791         if (pIctlMgr->client == NULL)   {
792             uifw_trace("ico_exinput_bind: Input controller.%s not initialized",
793                        pIctlMgr->device);
794             continue;
795         }
796
797         wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
798             if (pInput->swname[0] == 0) {
799                 uifw_trace("ico_exinput_bind: Input %s not initialized", pIctlMgr->device);
800                 continue;
801             }
802             if ((pInput->app != NULL) && (pInput->app != pAppMgr) && (pInput->fix)) {
803                 uifw_trace("ico_exinput_bind: Input %s.%s fixed assign to App.%s",
804                            pIctlMgr->device, pInput->swname, pInput->app->appid);
805                 continue;
806             }
807             uifw_trace("ico_exinput_bind: send capabilities to app(%s) %s.%s[%d]",
808                        pAppMgr->appid, pIctlMgr->device, pInput->swname, pInput->input);
809             ico_exinput_send_capabilities(pAppMgr->resource, pIctlMgr->device,
810                                           pIctlMgr->type, pInput->swname, pInput->input,
811                                           pInput->code[0].name, pInput->code[0].code);
812             for (i = 1; i < pInput->ncode; i++) {
813                 ico_exinput_send_code(pAppMgr->resource, pIctlMgr->device, pInput->input,
814                                       pInput->code[i].name, pInput->code[i].code);
815             }
816         }
817     }
818     uifw_trace("ico_exinput_bind: Leave");
819 }
820
821 /*--------------------------------------------------------------------------*/
822 /**
823  * @brief   ico_exinput_unbind: ico_exinput unbind from Application
824  *
825  * @param[in]   resource        client resource(Application)
826  * @return      none
827  */
828 /*--------------------------------------------------------------------------*/
829 static void
830 ico_exinput_unbind(struct wl_resource *resource)
831 {
832     struct ico_app_mgr      *pAppMgr;
833     struct ico_app_mgr      *pAppMgrTmp;
834     struct ico_ictl_mgr     *pIctlMgr;
835     struct ico_ictl_input   *pInput;
836     int                     fix = 0;
837
838     uifw_trace("ico_exinput_unbind: Enter(resource=%08x)", (int)resource);
839
840     wl_list_for_each_safe (pAppMgr, pAppMgrTmp, &pInputMgr->app_list, link) {
841         if (pAppMgr->resource == resource)  {
842             uifw_trace("ico_exinput_unbind: find app.%s", pAppMgr->appid);
843
844             /* release application from input switch    */
845             wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)    {
846                 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
847                     if (pInput->app == pAppMgr) {
848                         if (pInput->fix == 0)   {
849                             uifw_trace("ico_exinput_unbind: app.%s remove %s.%s",
850                                        pAppMgr->appid, pIctlMgr->device, pInput->swname);
851                             pInput->app = NULL;
852                         }
853                         else    {
854                             uifw_trace("ico_exinput_unbind: app.%s fix assign %s.%s",
855                                        pAppMgr->appid, pIctlMgr->device, pInput->swname);
856                             fix ++;
857                         }
858                     }
859                 }
860             }
861             if (fix == 0)   {
862                 wl_list_remove(&pAppMgr->link);
863                 free(pAppMgr);
864             }
865             else    {
866                 pAppMgr->client = NULL;
867                 pAppMgr->resource = NULL;
868             }
869         }
870     }
871     uifw_trace("ico_exinput_unbind: Leave");
872 }
873
874 /*--------------------------------------------------------------------------*/
875 /**
876  * @brief   find_ictlmgr_by_device: find Input Controller by device name
877  *
878  * @param[in]   device          device name
879  * @return      Input Controller Manager table address
880  * @retval      !=NULL          address
881  * @retval      ==NULL          not exist
882  */
883 /*--------------------------------------------------------------------------*/
884 static struct ico_ictl_mgr *
885 find_ictlmgr_by_device(const char *device)
886 {
887     struct ico_ictl_mgr     *pIctlMgr;
888
889     wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link)    {
890         if (strcmp(pIctlMgr->device, device) == 0)  {
891             return pIctlMgr;
892         }
893     }
894     return NULL;
895 }
896
897 /*--------------------------------------------------------------------------*/
898 /**
899  * @brief   find_ictlinput_by_input: find Input Switch by input Id
900  *
901  * @param[in]   pIctlMgr        Input Controller device
902  * @param[in]   input           Input Id
903  * @return      Input Switch table address
904  * @retval      !=NULL          address
905  * @retval      ==NULL          not exist
906  */
907 /*--------------------------------------------------------------------------*/
908 static struct ico_ictl_input *
909 find_ictlinput_by_input(struct ico_ictl_mgr *pIctlMgr, const int32_t input)
910 {
911     struct ico_ictl_input   *pInput;
912
913     wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link)  {
914         if (pInput->input == input) {
915             return pInput;
916         }
917     }
918     return NULL;
919 }
920
921 /*--------------------------------------------------------------------------*/
922 /**
923  * @brief   find_app_by_appid: find Application by application Id
924  *
925  * @param[in]   appid           application Id
926  * @return      Application Management table address
927  * @retval      !=NULL          address
928  * @retval      ==NULL          not exist
929  */
930 /*--------------------------------------------------------------------------*/
931 static struct ico_app_mgr *
932 find_app_by_appid(const char *appid)
933 {
934     struct ico_app_mgr      *pAppMgr;
935
936     wl_list_for_each (pAppMgr, &pInputMgr->app_list, link)  {
937         if (strcmp(pAppMgr->appid, appid) == 0) {
938             return pAppMgr;
939         }
940     }
941     return NULL;
942 }
943
944 /*--------------------------------------------------------------------------*/
945 /**
946  * @brief   module_init: initialization of this plugin
947  *
948  * @param[in]   ec          weston compositor
949  * @param[in]   argc        number of arguments(unused)
950  * @param[in]   argv        argument list(unused)
951  * @return      result
952  * @retval      0           OK
953  * @retval      -1          error
954  */
955 /*--------------------------------------------------------------------------*/
956 WL_EXPORT int
957 module_init(struct weston_compositor *ec, int *argc, char *argv[])
958 {
959     uifw_info("ico_input_mgr: Enter(module_init)");
960
961     /* initialize management table */
962     pInputMgr = (struct ico_input_mgr *)malloc(sizeof(struct ico_input_mgr));
963     if (pInputMgr == NULL) {
964         uifw_trace("ico_input_mgr: malloc failed");
965         return -1;
966     }
967     memset(pInputMgr, 0, sizeof(struct ico_input_mgr));
968     pInputMgr->compositor = ec;
969
970     /* interface to desktop manager(ex.HomeScreen)  */
971     if (wl_global_create(ec->wl_display, &ico_input_mgr_control_interface, 1,
972                          pInputMgr, ico_control_bind) == NULL) {
973         uifw_trace("ico_input_mgr: wl_global_create mgr failed");
974         return -1;
975     }
976
977     /* interface to Input Controller(ictl) */
978     if (wl_global_create(ec->wl_display, &ico_input_mgr_device_interface, 1,
979                          pInputMgr, ico_device_bind) == NULL) {
980         uifw_trace("ico_input_mgr: wl_global_create ictl failed");
981         return -1;
982     }
983
984     /* interface to App(exinput) */
985     if (wl_global_create(ec->wl_display, &ico_exinput_interface, 1,
986                          pInputMgr, ico_exinput_bind) == NULL) {
987         uifw_trace("ico_input_mgr: wl_global_create exseat failed");
988         return -1;
989     }
990
991     /* initialize list */
992     wl_list_init(&pInputMgr->ictl_list);
993     wl_list_init(&pInputMgr->app_list);
994
995     uifw_info("ico_input_mgr: Leave(module_init)");
996     return 0;
997 }
998