2 * Copyright © 2010-2011 Intel Corporation
3 * Copyright © 2008-2011 Kristian Høgsberg
4 * Copyright © 2013 TOYOTA MOTOR CORPORATION.
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.
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.
25 * @brief Multi Input Manager (Weston(Wayland) PlugIn)
35 #include <linux/input.h>
40 #include <sys/types.h>
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"
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
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_list dev_list; /* pseudo device List */
62 struct weston_seat *seat; /* input seat */
63 struct wl_resource *inputmgr;
66 /* Input Switch Table */
67 struct ico_ictl_code {
68 uint16_t code; /* input code numner */
69 char name[ICO_MINPUT_SW_LEN]; /* input code name */
72 struct ico_ictl_input {
73 struct wl_list link; /* link */
74 char swname[ICO_MINPUT_SW_LEN]; /* input switch name */
75 int32_t input; /* input Id */
76 uint16_t fix; /* fixed assign to application */
77 uint16_t ncode; /* number of codes */
78 struct ico_ictl_code code[ICO_MINPUT_MAX_CODES]; /* codes */
79 struct ico_app_mgr *app; /* send event tagret application */
82 /* Input Controller Management Table */
84 struct wl_list link; /* link */
85 struct wl_client *client; /* client */
86 struct wl_resource *resource; /* resource */
87 char device[ICO_MINPUT_DEVICE_LEN]; /* device name */
88 int type; /* device type */
89 struct wl_list ico_ictl_input; /* list of input switchs */
92 /* Application Management Table */
94 struct wl_list link; /* link */
95 struct wl_client *client; /* client */
96 struct wl_resource *resource; /* resource for send event */
97 struct wl_resource *mgr_resource; /* resource as manager(if NULL, client) */
98 char appid[ICO_IVI_APPID_LENGTH]; /* application id */
101 /* Pseudo Input Device Control Flags */
102 #define EVENT_MOTION 0x01 /* motion event */
103 #define EVENT_BUTTON 0x02 /* button event */
104 #define EVENT_TOUCH 0x03 /* touch event */
105 #define EVENT_KEY 0x04 /* key event */
106 #define EVENT_PENDING 0xff /* pending event input */
108 #define PENDING_X 0x01 /* pending X coordinate */
109 #define PENDING_Y 0x02 /* pending Y coordinate */
111 /* Pseudo Input Device Table */
112 struct uifw_input_device {
113 struct wl_list link; /* link to next device */
114 uint16_t type; /* device type */
115 uint16_t no; /* device number */
116 int x; /* current X coordinate */
117 int y; /* current Y coordinate */
118 int pend_x; /* pending X coordinate */
119 int pend_y; /* pending Y coordinate */
120 uint16_t pending; /* pending flag */
121 char res[2]; /* (unused) */
124 /* prototype of static function */
125 /* bind input manager form manager */
126 static void ico_control_bind(struct wl_client *client, void *data,
127 uint32_t version, uint32_t id);
128 /* unbind input manager form manager */
129 static void ico_control_unbind(struct wl_resource *resource);
130 /* bind input manager form input controller*/
131 static void ico_device_bind(struct wl_client *client, void *data,
132 uint32_t version, uint32_t id);
133 /* unbind input manager form input controller*/
134 static void ico_device_unbind(struct wl_resource *resource);
135 /* bind input manager(form application) */
136 static void ico_exinput_bind(struct wl_client *client, void *data,
137 uint32_t version, uint32_t id);
138 /* unbind input manager(form application)*/
139 static void ico_exinput_unbind(struct wl_resource *resource);
141 /* find ictl manager by device name */
142 static struct ico_ictl_mgr *find_ictlmgr_by_device(const char *device);
143 /* find ictl input switch by input Id */
144 static struct ico_ictl_input *find_ictlinput_by_input(struct ico_ictl_mgr *pIctlMgr,
145 const int32_t input);
146 /* find app manager by application Id */
147 static struct ico_app_mgr *find_app_by_appid(const char *appid);
148 /* add input event to application */
149 static void ico_mgr_add_input_app(struct wl_client *client, struct wl_resource *resource,
150 const char *appid, const char *device, int32_t input,
151 int32_t fix, int32_t keycode);
152 /* delete input event to application */
153 static void ico_mgr_del_input_app(struct wl_client *client, struct wl_resource *resource,
154 const char *appid, const char *device, int32_t input);
155 /* send input event from manager */
156 static void ico_mgr_send_input_event(struct wl_client *client, struct wl_resource *resource,
157 const char *appid, uint32_t surfaceid, int32_t type,
158 int32_t deviceno, int32_t code, int32_t value);
159 /* create and regist Input Controller table*/
160 static void ico_device_configure_input(struct wl_client *client,
161 struct wl_resource *resource, const char *device,
162 int32_t type, const char *swname, int32_t input,
163 const char *codename, int32_t code);
164 /* add input to from Input Controller table*/
165 static void ico_device_configure_code(struct wl_client *client,
166 struct wl_resource *resource, const char *device,
167 int32_t input, const char *codename, int32_t code);
168 /* device input event */
169 static void ico_device_input_event(struct wl_client *client, struct wl_resource *resource,
170 uint32_t time, const char *device,
171 int32_t input, int32_t code, int32_t state);
173 /* definition of Wayland protocol */
175 static const struct ico_input_mgr_control_interface ico_input_mgr_implementation = {
176 ico_mgr_add_input_app,
177 ico_mgr_del_input_app,
178 ico_mgr_send_input_event
181 /* Input Controller interface */
182 static const struct ico_input_mgr_device_interface input_mgr_ictl_implementation = {
183 ico_device_configure_input,
184 ico_device_configure_code,
185 ico_device_input_event
188 /* definition of class variable */
189 struct ico_input_mgr *pInputMgr = NULL;
192 /*--------------------------------------------------------------------------*/
194 * @brief ico_mgr_add_input_app: add input event to application from HomeScreen.
196 * @param[in] client client(HomeScreen)
197 * @param[in] resource resource of request
198 * @param[in] appid target application id
199 * @param[in] device device name
200 * @param[in] input input switch number
201 * @param[in] fix fix to application(1=fix,0=general)
202 * @param[in] keycode switch map to keyboard operation(0=not map to keyboard)
205 /*--------------------------------------------------------------------------*/
207 ico_mgr_add_input_app(struct wl_client *client, struct wl_resource *resource,
208 const char *appid, const char *device, int32_t input,
209 int32_t fix, int32_t keycode)
211 uifw_trace("ico_mgr_add_input_app: Enter(appid=%s,dev=%s,input=%d,fix=%d,key=%d)",
212 appid, device, input, fix, keycode);
214 struct ico_ictl_mgr *pIctlMgr;
215 struct ico_ictl_input *pInput;
216 struct ico_app_mgr *pAppMgr;
218 pIctlMgr = find_ictlmgr_by_device(device);
220 /* not configure input controller, create */
221 ico_device_configure_input(NULL, NULL, device, 0, NULL, input, NULL, 0);
222 pIctlMgr = find_ictlmgr_by_device(device);
224 uifw_error("ico_mgr_add_input_app: Leave(No Memory)");
228 pInput = find_ictlinput_by_input(pIctlMgr, input);
230 /* not configure input switch, create */
231 ico_device_configure_input(NULL, NULL, device, 0, NULL, input, NULL, 0);
232 pInput = find_ictlinput_by_input(pIctlMgr, input);
234 uifw_error("ico_mgr_add_input_app: Leave(No Memory)");
239 /* find application */
240 pAppMgr = find_app_by_appid(appid);
242 /* create Application Management Table */
243 pAppMgr = (struct ico_app_mgr *)malloc(sizeof(struct ico_app_mgr));
245 uifw_error("ico_mgr_add_input_app: Leave(No Memory)");
248 memset(pAppMgr, 0, sizeof(struct ico_app_mgr));
249 strncpy(pAppMgr->appid, appid, sizeof(pAppMgr->appid)-1);
250 wl_list_insert(pInputMgr->app_list.prev, &pAppMgr->link);
253 pInput->app = pAppMgr;
255 uifw_trace("ico_mgr_add_input_app: Leave(%s.%s[%d] assign to %s)",
256 pIctlMgr->device, pInput->swname ? pInput->swname : "(NULL)", input,
260 /*--------------------------------------------------------------------------*/
262 * @brief ico_mgr_del_input_app: delete input event at application from HomeScreen.
264 * @param[in] client client(HomeScreen)
265 * @param[in] resource resource of request
266 * @param[in] appid target application id,
267 * if NULL, all applictions without fixed assign switch
268 * @param[in] device device name
269 * if NULL, all device without fixed assign switch
270 * @param[in] input input switch number
271 * if -1, all input without fixed assign switch
274 /*--------------------------------------------------------------------------*/
276 ico_mgr_del_input_app(struct wl_client *client, struct wl_resource *resource,
277 const char *appid, const char *device, int32_t input)
279 uifw_trace("ico_mgr_del_input_app: Enter(appid=%s,dev=%s,input=%d)",
280 appid ? appid : "(NULL)", device ? device : "(NULL)", input);
283 struct ico_ictl_mgr *pIctlMgr = NULL;
284 struct ico_ictl_input *pInput = NULL;
285 struct ico_app_mgr *pAppMgr;
287 if ((device != NULL) && (*device != 0)) {
288 pIctlMgr = find_ictlmgr_by_device(device);
290 /* not configure input controller, NOP */
291 uifw_trace("ico_mgr_del_input_app: Leave(%s dose not exist)", device);
295 pInput = find_ictlinput_by_input(pIctlMgr, input);
297 /* not configure input switch, NOP */
298 uifw_trace("ico_mgr_del_input_app: Leave(%s.%d dose not exist)",
308 /* find application */
309 if ((appid != NULL) && (*appid != 0)) {
310 pAppMgr = find_app_by_appid(appid);
312 /* application dose not exist, NOP */
313 uifw_trace("ico_mgr_del_input_app: Leave(app.%s dose not exist)", appid);
318 if (pInput->app != pAppMgr) {
319 /* not same application, NOP */
320 uifw_trace("ico_mgr_del_input_app: Leave(%s.%d not app.%s, current %s)",
321 device, input, appid,
322 pInput->app ? pInput->app->appid : "(NULL)");
325 uifw_trace("ico_mgr_del_input_app: Leave(%s.%d app.%s deleted)",
326 device, input, appid);
331 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link) {
332 if ((pInput->fix == 0) && (pInput->app == pAppMgr)) {
333 uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
334 pIctlMgr->device, pInput->input, appid);
341 /* reset all device without fixed assign */
342 wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link) {
343 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link) {
344 if ((pInput->fix == 0) && (pInput->app == pAppMgr)) {
345 uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
346 pIctlMgr->device, pInput->input, pInput->app->appid);
356 if ((pInput->fix == 0) && (pInput->app != NULL)) {
357 uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
358 pIctlMgr->device, pInput->input, pInput->app->appid);
363 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link) {
364 if ((pInput->fix == 0) && (pInput->app != NULL)) {
365 uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
366 pIctlMgr->device, pInput->input, pInput->app->appid);
373 /* reset all application 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 != NULL)) {
377 uifw_trace("ico_mgr_del_input_app: %s.%d app.%s deleted",
378 pIctlMgr->device, pInput->input, pInput->app->appid);
385 uifw_trace("ico_mgr_del_input_app: Leave");
388 /*--------------------------------------------------------------------------*/
390 * @brief ico_mgr_send_input_event: send input event from manager
392 * @param[in] client client(HomeScreen)
393 * @param[in] resource resource of request
394 * @param[in] appid target application id
395 * @param[in] surfaceid target surface id
396 * @param[in] type event device type
397 * @param[in] deviceno device number
398 * @param[in] code event code
399 * @param[in] value event value
402 /*--------------------------------------------------------------------------*/
404 ico_mgr_send_input_event(struct wl_client *client, struct wl_resource *resource,
405 const char *appid, uint32_t surfaceid, int32_t type,
406 int32_t deviceno, int32_t code, int32_t value)
408 struct uifw_win_surface *usurf; /* UIFW surface */
409 struct uifw_input_device *dev; /* device control table */
410 struct wl_resource *cres; /* event send client resource */
411 uint32_t ctime; /* current time(ms) */
412 uint32_t serial; /* event serial number */
413 int event; /* event flag */
414 wl_fixed_t fix_x; /* wayland X coordinate */
415 wl_fixed_t fix_y; /* wayland Y coordinate */
417 uifw_trace("ico_mgr_send_input_event: Enter(app=%s surf=%08x dev=%d.%d code=%x value=%d)",
418 appid ? appid : "(NULL)", surfaceid, type, deviceno, code, value);
420 /* search pseudo input device */
421 wl_list_for_each (dev, &pInputMgr->dev_list, link) {
422 if ((dev->type == type) && (dev->no == deviceno)) break;
424 if (&dev->link == &pInputMgr->dev_list) {
425 /* device not exist, create new device */
426 uifw_trace("ico_mgr_send_input_event: new device=%d no=%d", type, deviceno);
427 dev = malloc(sizeof(struct uifw_input_device));
429 uifw_error("ico_mgr_send_input_event: Leave(No Memory)");
432 memset(dev, 0, sizeof(struct uifw_input_device));
435 wl_list_insert(pInputMgr->dev_list.prev, &dev->link);
438 /* convert pending event */
440 if ((code & 0xffff0000) != (EV_REL << 16)) {
444 case ICO_INPUT_MGR_DEVICE_TYPE_POINTER: /* mouse */
445 case ICO_INPUT_MGR_DEVICE_TYPE_TOUCH: /* touch panel */
446 case ICO_INPUT_MGR_DEVICE_TYPE_HAPTIC: /* haptic */
449 if (dev->pending & PENDING_Y) {
451 dev->y = dev->pend_y;
455 event = EVENT_MOTION;
459 dev->pending |= PENDING_X;
460 event = EVENT_PENDING;
464 if (dev->pending & PENDING_X) {
465 dev->x = dev->pend_x;
470 event = EVENT_MOTION;
474 dev->pending |= PENDING_Y;
475 event = EVENT_PENDING;
479 dev->x = (short)(value >> 16);
480 dev->y = (short)(value & 0x0ffff);
484 event = EVENT_MOTION;
486 case ((EV_REL << 16) | REL_X):
487 if (dev->pending & PENDING_Y) {
489 dev->y = dev->pend_y;
493 event = EVENT_MOTION;
496 dev->pend_x = dev->x + value;
497 dev->pending |= PENDING_X;
498 event = EVENT_PENDING;
501 case ((EV_REL << 16) | REL_Y):
502 if (dev->pending & PENDING_X) {
503 dev->x = dev->pend_x;
508 event = EVENT_MOTION;
511 dev->pend_x = dev->y + value;
512 dev->pending |= PENDING_Y;
513 event = EVENT_PENDING;
516 case ((EV_REL << 16) | REL_Z):
517 dev->x += (short)(value >> 16);
518 dev->y += (short)(value & 0x0ffff);
522 event = EVENT_MOTION;
525 if (type == ICO_INPUT_MGR_DEVICE_TYPE_TOUCH) {
529 event = EVENT_BUTTON;
539 if (event == EVENT_PENDING) {
540 uifw_trace("ico_mgr_send_input_event: Leave(event pending)");
544 ctime = weston_compositor_get_time();
545 fix_x = wl_fixed_from_int(dev->x);
546 fix_y = wl_fixed_from_int(dev->y);
548 if ((surfaceid == 0) && ((appid == NULL) || (*appid == 0) || (*appid == ' '))) {
549 /* send event to surface via weston */
551 /* disable the event transmission to a touch layer */
552 ico_window_mgr_restack_layer(NULL, TRUE);
556 if (type == ICO_INPUT_MGR_DEVICE_TYPE_TOUCH) {
557 uifw_trace("ico_mgr_send_input_event: notify_touch(%d,%d)", fix_x, fix_y);
558 notify_touch(pInputMgr->seat, ctime, 0, fix_x, fix_y, WL_TOUCH_MOTION);
561 uifw_trace("ico_mgr_send_input_event: notify_motion_absolute(%d,%d)",
563 notify_motion_absolute(pInputMgr->seat, ctime, fix_x, fix_y);
567 uifw_trace("ico_mgr_send_input_event: notify_button(%d,%d)", code, value);
568 notify_button(pInputMgr->seat, ctime, code,
569 value ? WL_POINTER_BUTTON_STATE_PRESSED :
570 WL_POINTER_BUTTON_STATE_RELEASED);
574 uifw_trace("ico_mgr_send_input_event: notify_touch(%d,%d,DOWN)",
576 notify_touch(pInputMgr->seat, ctime, 0, fix_x, fix_y, WL_TOUCH_DOWN);
579 uifw_trace("ico_mgr_send_input_event: notify_touch(UP)");
580 notify_touch(pInputMgr->seat, ctime, 0, 0, 0, WL_TOUCH_UP);
584 uifw_trace("ico_mgr_send_input_event: notify_key(%d,%d)", code, value);
585 notify_key(pInputMgr->seat, ctime, code,
586 value ? WL_KEYBOARD_KEY_STATE_PRESSED :
587 WL_KEYBOARD_KEY_STATE_RELEASED, STATE_UPDATE_NONE);
590 uifw_trace("ico_mgr_send_input_event: unknown event=%d", event);
593 /* enable the event transmission to a touch layer */
594 ico_window_mgr_restack_layer(NULL, FALSE);
597 if ((appid != NULL) && (*appid != 0) && (*appid != ' ')) {
598 /* send event to fixed application */
600 /* get application surface */
601 usurf = ico_window_mgr_get_client_usurf(appid, NULL);
603 uifw_trace("ico_mgr_send_input_event: Leave(app=%s dose not exist)", appid);
608 /* get UIFW surface */
609 usurf = ico_window_mgr_get_usurf(surfaceid);
611 uifw_trace("ico_mgr_send_input_event: Leave(surface dose not exist)");
619 if (type == ICO_INPUT_MGR_DEVICE_TYPE_TOUCH) {
620 cres = wl_resource_find_for_client(
621 &pInputMgr->seat->touch->resource_list,
622 wl_resource_get_client(usurf->surface->resource));
624 wl_touch_send_motion(cres, ctime, 0, fix_x, fix_y);
628 cres = wl_resource_find_for_client(
629 &pInputMgr->seat->pointer->resource_list,
630 wl_resource_get_client(usurf->surface->resource));
632 wl_pointer_send_motion(cres, ctime, fix_x, fix_y);
637 cres = wl_resource_find_for_client(
638 &pInputMgr->seat->pointer->resource_list,
639 wl_resource_get_client(usurf->surface->resource));
641 serial = wl_display_next_serial(pInputMgr->compositor->wl_display);
642 wl_pointer_send_button(cres, serial, ctime, code,
643 value ? WL_POINTER_BUTTON_STATE_PRESSED :
644 WL_POINTER_BUTTON_STATE_RELEASED);
648 cres = wl_resource_find_for_client(
649 &pInputMgr->seat->touch->resource_list,
650 wl_resource_get_client(usurf->surface->resource));
652 serial = wl_display_next_serial(pInputMgr->compositor->wl_display);
654 wl_touch_send_down(cres, serial, ctime, usurf->surface->resource, 0,
658 wl_touch_send_up(cres, serial, ctime, 0);
663 cres = wl_resource_find_for_client(
664 &pInputMgr->seat->keyboard->resource_list,
665 wl_resource_get_client(usurf->surface->resource));
667 serial = wl_display_next_serial(pInputMgr->compositor->wl_display);
668 wl_keyboard_send_key(cres, serial, ctime, code,
669 value ? WL_KEYBOARD_KEY_STATE_PRESSED :
670 WL_KEYBOARD_KEY_STATE_RELEASED);
677 uifw_trace("ico_mgr_send_input_event: Leave");
680 /*--------------------------------------------------------------------------*/
682 * @brief ico_device_configure_input: configure input device and input switch
683 * from Device Input Controller.
685 * @param[in] client client(Device Input Controller)
686 * @param[in] resource resource of request
687 * @param[in] device device name
688 * @param[in] type device type(saved but unused)
689 * @param[in] swname input switch name
690 * @param[in] input input switch number
691 * @param[in] codename input code name
692 * @param[in] code input code number
695 /*--------------------------------------------------------------------------*/
697 ico_device_configure_input(struct wl_client *client, struct wl_resource *resource,
698 const char *device, int32_t type, const char *swname,
699 int32_t input, const char *codename, int32_t code)
701 uifw_trace("ico_device_configure_input: Enter(client=%08x,dev=%s,type=%d,swname=%s,"
702 "input=%d,code=%d[%s])", (int)client, device, type,
703 swname ? swname : "(NULL)", input, code, codename ? codename : " ");
705 struct ico_ictl_mgr *pIctlMgr;
706 struct ico_ictl_input *pInput;
707 struct ico_app_mgr *pAppMgr;
709 pIctlMgr = find_ictlmgr_by_device(device);
711 /* create ictl mgr table */
712 pIctlMgr = (struct ico_ictl_mgr *)malloc(sizeof(struct ico_ictl_mgr));
713 if (pIctlMgr == NULL) {
714 uifw_error("ico_device_configure_input: Leave(No Memory)");
717 uifw_trace("ico_device_configure_input: create pIctlMgr(mgr=%08x,input=%d)",
718 (int)pIctlMgr, input);
719 memset(pIctlMgr, 0, sizeof(struct ico_ictl_mgr));
720 wl_list_init(&pIctlMgr->ico_ictl_input);
721 strncpy(pIctlMgr->device, device, sizeof(pIctlMgr->device)-1);
724 wl_list_insert(pInputMgr->ictl_list.prev, &pIctlMgr->link);
726 pIctlMgr->client = client;
727 pIctlMgr->resource = resource;
729 pIctlMgr->type = type;
732 /* search and add input switch */
733 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link) {
734 if (pInput->input == input) break;
736 if (&pInput->link == &pIctlMgr->ico_ictl_input) {
737 uifw_trace("ico_device_configure_input: create %s.%s(%d) switch",
738 device, swname, input);
739 pInput = (struct ico_ictl_input *)malloc(sizeof(struct ico_ictl_input));
740 if (pInput == NULL) {
741 uifw_error("ico_device_configure_input: Leave(No Memory)");
744 memset(pInput, 0, sizeof(struct ico_ictl_input));
746 strncpy(pInput->swname, swname, sizeof(pInput->swname)-1);
749 strcpy(pInput->swname, "(Unknown)");
751 wl_list_insert(pIctlMgr->ico_ictl_input.prev, &pInput->link);
754 strncpy(pInput->swname, swname, sizeof(pInput->swname)-1);
756 pInput->input = input;
757 memset(pInput->code, 0, sizeof(pInput->code));
759 pInput->code[0].code = code;
761 strncpy(pInput->code[0].name, codename, sizeof(pInput->code[0].name)-1);
764 if (client == NULL) {
765 /* internal call for table create */
766 uifw_trace("ico_device_configure_input: Leave(table create)");
770 /* send to application and manager(ex.HomeScreen) */
771 wl_list_for_each (pAppMgr, &pInputMgr->app_list, link) {
772 if (pAppMgr->resource == NULL) continue;
773 if ((pInput->app != NULL) && (pInput->app != pAppMgr) && (pInput->fix)) continue;
775 uifw_trace("ico_device_configure_input: send capabilities to app(%s) %s.%s[%d]",
776 pAppMgr->appid, device, pInput->swname, input);
777 ico_exinput_send_capabilities(pAppMgr->resource, device, pIctlMgr->type,
778 pInput->swname, input,
779 pInput->code[0].name, pInput->code[0].code);
781 uifw_trace("ico_device_configure_input: Leave");
784 /*--------------------------------------------------------------------------*/
786 * @brief ico_device_configure_code: add input switch from Device Input Controller.
788 * @param[in] client client(Device Input Controller)
789 * @param[in] resource resource of request
790 * @param[in] device device name
791 * @param[in] input input switch number
792 * @param[in] codename input code name
793 * @param[in] code input code number
796 /*--------------------------------------------------------------------------*/
798 ico_device_configure_code(struct wl_client *client, struct wl_resource *resource,
799 const char *device, int32_t input,
800 const char *codename, int32_t code)
802 uifw_trace("ico_device_configure_code: Enter(client=%08x,dev=%s,input=%d,code=%d[%s])",
803 (int)client, device, input, code, codename ? codename : " ");
806 struct ico_ictl_mgr *pIctlMgr;
807 struct ico_ictl_input *pInput;
808 struct ico_app_mgr *pAppMgr;
810 pIctlMgr = find_ictlmgr_by_device(device);
812 uifw_warn("ico_device_configure_code: Leave(dev=%s dose not exist)", device);
815 /* search input switch */
816 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link) {
817 if (pInput->input == input) break;
819 if (&pInput->link == &pIctlMgr->ico_ictl_input) {
820 uifw_warn("ico_device_configure_code: Leave(input=%s.%d dose not exist)",
825 /* search input code */
826 for (i = 0; i < pInput->ncode; i++) {
827 if (pInput->code[i].code == code) break;
829 if (i >= pInput->ncode) {
830 /* code dose not exist, add */
831 if (pInput->ncode >= ICO_MINPUT_MAX_CODES) {
832 uifw_warn("ico_device_configure_code: Leave(input=%s.%d code overflow)",
838 pInput->code[i].code = code;
840 memset(pInput->code[i].name, 0, sizeof(pInput->code[i].name));
841 strncpy(pInput->code[i].name, codename, sizeof(pInput->code[i].name)-1);
843 /* send to application and manager(ex.HomeScreen) */
844 wl_list_for_each (pAppMgr, &pInputMgr->app_list, link) {
845 if (pAppMgr->resource == NULL) continue;
846 if ((pInput->app != NULL) && (pInput->app != pAppMgr) && (pInput->fix)) continue;
847 uifw_trace("ico_device_configure_input: send code to app(%s) %s.%s[%d]",
848 pAppMgr->appid, device, pInput->swname, input);
849 ico_exinput_send_code(pAppMgr->resource, device, input,
850 pInput->code[i].name, pInput->code[i].code);
852 uifw_trace("ico_device_configure_code: Leave");
855 /*--------------------------------------------------------------------------*/
857 * @brief ico_device_input_event: device input event from Device Input Controller.
859 * @param[in] client client(Device Input Controller)
860 * @param[in] resource resource of request
861 * @param[in] time device input time(miri-sec)
862 * @param[in] device device name
863 * @param[in] input input switch number
864 * @param[in] code input code number
865 * @param[in] state input state(1=On, 0=Off)
868 /*--------------------------------------------------------------------------*/
870 ico_device_input_event(struct wl_client *client, struct wl_resource *resource,
871 uint32_t time, const char *device,
872 int32_t input, int32_t code, int32_t state)
874 uifw_trace("ico_device_input_event: Enter(time=%d,dev=%s,input=%d,code=%d,state=%d)",
875 time, device, input, code, state);
877 struct ico_ictl_mgr *pIctlMgr;
878 struct ico_ictl_input *pInput;
880 /* find input devcie by client */
881 pIctlMgr = find_ictlmgr_by_device(device);
883 uifw_error("ico_device_input_event: Leave(Unknown client(%08x))", (int)client);
886 /* find input switch by input Id */
887 pInput = find_ictlinput_by_input(pIctlMgr, input);
889 uifw_warn("ico_device_input_event: Leave(Unknown input(%s,%d))",
890 pIctlMgr->device, input);
895 uifw_trace("ico_device_input_event: Leave(%s.%s not assign)",
896 pIctlMgr->device, pInput->swname);
900 /* send event to application */
901 uifw_trace("ico_device_input_event: send event=%s.%s[%d],%d,%d to App.%s",
902 pIctlMgr->device, pInput->swname, input, code, state, pInput->app->appid);
903 ico_exinput_send_input(pInput->app->resource, time, pIctlMgr->device,
906 uifw_trace("ico_device_input_event: Leave");
909 /*--------------------------------------------------------------------------*/
911 * @brief ico_control_bind: ico_input_mgr_control bind from HomeScreen
913 * @param[in] client client(HomeScreen)
914 * @param[in] data data(unused)
915 * @param[in] version protocol version(unused)
916 * @param[in] id client object id
919 /*--------------------------------------------------------------------------*/
921 ico_control_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
924 struct ico_app_mgr *pAppMgr;
926 uifw_trace("ico_control_bind: Enter(client=%08x)", (int)client);
927 appid = ico_window_mgr_get_appid(client);
930 /* client dose not exist */
931 uifw_warn("ico_control_bind: Leave(client=%08x dose not exist)", (int)client);
935 /* find application */
936 pAppMgr = find_app_by_appid(appid);
938 /* create Application Management Table */
939 pAppMgr = (struct ico_app_mgr *)malloc(sizeof(struct ico_app_mgr));
941 uifw_error("ico_control_bind: Leave(No Memory)");
944 memset(pAppMgr, 0, sizeof(struct ico_app_mgr));
945 strncpy(pAppMgr->appid, appid, sizeof(pAppMgr->appid)-1);
946 wl_list_insert(pInputMgr->app_list.prev, &pAppMgr->link);
948 pAppMgr->client = client;
949 if (! pAppMgr->mgr_resource) {
950 pAppMgr->mgr_resource = wl_resource_create(client,
951 &ico_input_mgr_control_interface, 1, id);
952 if (pAppMgr->mgr_resource) {
953 wl_resource_set_implementation(pAppMgr->mgr_resource,
954 &ico_input_mgr_implementation,
955 pInputMgr, ico_control_unbind);
958 uifw_trace("ico_control_bind: Leave");
961 /*--------------------------------------------------------------------------*/
963 * @brief ico_control_unbind: ico_input_mgr_control unbind from HomeScreen
965 * @param[in] resource client resource(HomeScreen)
968 /*--------------------------------------------------------------------------*/
970 ico_control_unbind(struct wl_resource *resource)
972 struct ico_app_mgr *pAppMgr;
974 uifw_trace("ico_control_unbind: Enter(resource=%08x)", (int)resource);
976 wl_list_for_each (pAppMgr, &pInputMgr->app_list, link) {
977 if (pAppMgr->mgr_resource == resource) {
978 uifw_trace("ico_control_unbind: find app.%s", pAppMgr->appid);
979 pAppMgr->mgr_resource = NULL;
983 uifw_trace("ico_control_unbind: Leave");
986 /*--------------------------------------------------------------------------*/
988 * @brief ico_device_bind: ico_input_mgr_device bind from Device Input Controller
990 * @param[in] client client(Device Input Controller)
991 * @param[in] data data(unused)
992 * @param[in] version protocol version(unused)
993 * @param[in] id client object id
996 /*--------------------------------------------------------------------------*/
998 ico_device_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
1000 struct wl_resource *mgr_resource;
1002 uifw_trace("ico_device_bind: Enter(client=%08x)", (int)client);
1004 mgr_resource = wl_resource_create(client, &ico_input_mgr_device_interface, 1, id);
1006 wl_resource_set_implementation(mgr_resource, &input_mgr_ictl_implementation,
1007 NULL, ico_device_unbind);
1009 uifw_trace("ico_device_bind: Leave");
1012 /*--------------------------------------------------------------------------*/
1014 * @brief ico_device_unbind: ico_input_mgr_device unbind from Device Input Controller
1016 * @param[in] resource client resource(Device Input Controller)
1019 /*--------------------------------------------------------------------------*/
1021 ico_device_unbind(struct wl_resource *resource)
1023 uifw_trace("ico_device_unbind: Enter(resource=%08x)", (int)resource);
1024 uifw_trace("ico_device_unbind: Leave");
1027 /*--------------------------------------------------------------------------*/
1029 * @brief ico_exinput_bind: ico_exinput bind from Application
1031 * @param[in] client client(Application)
1032 * @param[in] data data(unused)
1033 * @param[in] version protocol version(unused)
1034 * @param[in] id client object id
1037 /*--------------------------------------------------------------------------*/
1039 ico_exinput_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
1043 struct ico_app_mgr *pAppMgr;
1044 struct ico_ictl_mgr *pIctlMgr;
1045 struct ico_ictl_input *pInput;
1047 appid = ico_window_mgr_get_appid(client);
1048 uifw_trace("ico_exinput_bind: Enter(client=%08x,%s)", (int)client,
1049 appid ? appid : "(NULL)");
1052 /* client dose not exist */
1053 uifw_warn("ico_exinput_bind: Leave(client=%08x dose not exist)", (int)client);
1057 /* find application */
1058 pAppMgr = find_app_by_appid(appid);
1060 /* create Application Management Table */
1061 pAppMgr = (struct ico_app_mgr *)malloc(sizeof(struct ico_app_mgr));
1063 uifw_error("ico_exinput_bind: Leave(No Memory)");
1066 memset(pAppMgr, 0, sizeof(struct ico_app_mgr));
1067 strncpy(pAppMgr->appid, appid, sizeof(pAppMgr->appid)-1);
1068 wl_list_insert(pInputMgr->app_list.prev, &pAppMgr->link);
1069 uifw_trace("ico_exinput_bind: Create App.%s table", appid);
1071 pAppMgr->client = client;
1072 if (! pAppMgr->resource) {
1073 pAppMgr->resource = wl_resource_create(client, &ico_exinput_interface, 1, id);
1074 if (pAppMgr->resource) {
1075 wl_resource_set_implementation(pAppMgr->resource, NULL,
1076 pInputMgr, ico_exinput_unbind);
1080 /* send all capabilities */
1081 wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link) {
1082 if (pIctlMgr->client == NULL) {
1083 uifw_trace("ico_exinput_bind: Input controller.%s not initialized",
1088 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link) {
1089 if (pInput->swname[0] == 0) {
1090 uifw_trace("ico_exinput_bind: Input %s not initialized", pIctlMgr->device);
1093 if ((pInput->app != NULL) && (pInput->app != pAppMgr) && (pInput->fix)) {
1094 uifw_trace("ico_exinput_bind: Input %s.%s fixed assign to App.%s",
1095 pIctlMgr->device, pInput->swname, pInput->app->appid);
1098 uifw_trace("ico_exinput_bind: send capabilities to app(%s) %s.%s[%d]",
1099 pAppMgr->appid, pIctlMgr->device, pInput->swname, pInput->input);
1100 ico_exinput_send_capabilities(pAppMgr->resource, pIctlMgr->device,
1101 pIctlMgr->type, pInput->swname, pInput->input,
1102 pInput->code[0].name, pInput->code[0].code);
1103 for (i = 1; i < pInput->ncode; i++) {
1104 ico_exinput_send_code(pAppMgr->resource, pIctlMgr->device, pInput->input,
1105 pInput->code[i].name, pInput->code[i].code);
1109 uifw_trace("ico_exinput_bind: Leave");
1112 /*--------------------------------------------------------------------------*/
1114 * @brief ico_exinput_unbind: ico_exinput unbind from Application
1116 * @param[in] resource client resource(Application)
1119 /*--------------------------------------------------------------------------*/
1121 ico_exinput_unbind(struct wl_resource *resource)
1123 struct ico_app_mgr *pAppMgr;
1124 struct ico_app_mgr *pAppMgrTmp;
1125 struct ico_ictl_mgr *pIctlMgr;
1126 struct ico_ictl_input *pInput;
1129 uifw_trace("ico_exinput_unbind: Enter(resource=%08x)", (int)resource);
1131 wl_list_for_each_safe (pAppMgr, pAppMgrTmp, &pInputMgr->app_list, link) {
1132 if (pAppMgr->resource == resource) {
1133 uifw_trace("ico_exinput_unbind: find app.%s", pAppMgr->appid);
1135 /* release application from input switch */
1136 wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link) {
1137 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link) {
1138 if (pInput->app == pAppMgr) {
1139 if (pInput->fix == 0) {
1140 uifw_trace("ico_exinput_unbind: app.%s remove %s.%s",
1141 pAppMgr->appid, pIctlMgr->device, pInput->swname);
1145 uifw_trace("ico_exinput_unbind: app.%s fix assign %s.%s",
1146 pAppMgr->appid, pIctlMgr->device, pInput->swname);
1153 wl_list_remove(&pAppMgr->link);
1157 pAppMgr->client = NULL;
1158 pAppMgr->resource = NULL;
1162 uifw_trace("ico_exinput_unbind: Leave");
1165 /*--------------------------------------------------------------------------*/
1167 * @brief find_ictlmgr_by_device: find Input Controller by device name
1169 * @param[in] device device name
1170 * @return Input Controller Manager table address
1171 * @retval !=NULL address
1172 * @retval ==NULL not exist
1174 /*--------------------------------------------------------------------------*/
1175 static struct ico_ictl_mgr *
1176 find_ictlmgr_by_device(const char *device)
1178 struct ico_ictl_mgr *pIctlMgr;
1180 wl_list_for_each (pIctlMgr, &pInputMgr->ictl_list, link) {
1181 if (strcmp(pIctlMgr->device, device) == 0) {
1188 /*--------------------------------------------------------------------------*/
1190 * @brief find_ictlinput_by_input: find Input Switch by input Id
1192 * @param[in] pIctlMgr Input Controller device
1193 * @param[in] input Input Id
1194 * @return Input Switch table address
1195 * @retval !=NULL address
1196 * @retval ==NULL not exist
1198 /*--------------------------------------------------------------------------*/
1199 static struct ico_ictl_input *
1200 find_ictlinput_by_input(struct ico_ictl_mgr *pIctlMgr, const int32_t input)
1202 struct ico_ictl_input *pInput;
1204 wl_list_for_each (pInput, &pIctlMgr->ico_ictl_input, link) {
1205 if (pInput->input == input) {
1212 /*--------------------------------------------------------------------------*/
1214 * @brief find_app_by_appid: find Application by application Id
1216 * @param[in] appid application Id
1217 * @return Application Management table address
1218 * @retval !=NULL address
1219 * @retval ==NULL not exist
1221 /*--------------------------------------------------------------------------*/
1222 static struct ico_app_mgr *
1223 find_app_by_appid(const char *appid)
1225 struct ico_app_mgr *pAppMgr;
1227 wl_list_for_each (pAppMgr, &pInputMgr->app_list, link) {
1228 if (strcmp(pAppMgr->appid, appid) == 0) {
1235 /*--------------------------------------------------------------------------*/
1237 * @brief module_init: initialization of this plugin
1239 * @param[in] ec weston compositor
1240 * @param[in] argc number of arguments(unused)
1241 * @param[in] argv argument list(unused)
1246 /*--------------------------------------------------------------------------*/
1248 module_init(struct weston_compositor *ec, int *argc, char *argv[])
1250 uifw_info("ico_input_mgr: Enter(module_init)");
1252 /* initialize management table */
1253 pInputMgr = (struct ico_input_mgr *)malloc(sizeof(struct ico_input_mgr));
1254 if (pInputMgr == NULL) {
1255 uifw_trace("ico_input_mgr: malloc failed");
1258 memset(pInputMgr, 0, sizeof(struct ico_input_mgr));
1259 pInputMgr->compositor = ec;
1261 /* interface to desktop manager(ex.HomeScreen) */
1262 if (wl_global_create(ec->wl_display, &ico_input_mgr_control_interface, 1,
1263 pInputMgr, ico_control_bind) == NULL) {
1264 uifw_trace("ico_input_mgr: wl_global_create mgr failed");
1268 /* interface to Input Controller(ictl) */
1269 if (wl_global_create(ec->wl_display, &ico_input_mgr_device_interface, 1,
1270 pInputMgr, ico_device_bind) == NULL) {
1271 uifw_trace("ico_input_mgr: wl_global_create ictl failed");
1275 /* interface to App(exinput) */
1276 if (wl_global_create(ec->wl_display, &ico_exinput_interface, 1,
1277 pInputMgr, ico_exinput_bind) == NULL) {
1278 uifw_trace("ico_input_mgr: wl_global_create exseat failed");
1282 /* initialize list */
1283 wl_list_init(&pInputMgr->ictl_list);
1284 wl_list_init(&pInputMgr->app_list);
1285 wl_list_init(&pInputMgr->dev_list);
1287 /* found input seat */
1288 pInputMgr->seat = container_of(ec->seat_list.next, struct weston_seat, link);
1290 uifw_info("ico_input_mgr: Leave(module_init)");