bug fix: It will end, if many events come from Weston continuously.
[profile/ivi/ico-uxf-device-input-controller.git] / gtforce / ico_dic-wayland.c
1 /*
2  * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
3  *
4  * This program is licensed under the terms and conditions of the
5  * Apache License, version 2.0.  The full text of the Apache License is at
6  * http://www.apache.org/licenses/LICENSE-2.0
7  *
8  */
9 /**
10  * @brief   Device Input Controllers(wayland processing)
11  *          processing related wayland
12  *
13  * @date    Sep-08-2013
14  */
15
16 #include    <stdio.h>
17 #include    <stdlib.h>
18 #include    <unistd.h>
19 #include    <strings.h>
20 #include    <errno.h>
21 #include    <pthread.h>
22 #include    "ico_dic-gtforce.h"
23
24 /* prototype of static function             */
25 /* callback function from wayland global    */
26 static void ico_dic_wayland_globalcb(void *data, struct wl_registry *registry,
27                                      uint32_t wldispid, const char *event,
28                                      uint32_t version);
29
30 /* table/variable                           */
31 extern Ico_Dic_Mng      gIco_Dic_Mng;
32
33 static const struct wl_registry_listener registry_listener = {
34     ico_dic_wayland_globalcb
35 };
36
37 /*--------------------------------------------------------------------------*/
38 /**
39  * @brief   ico_dic_wayland_init
40  *          connect to wayland of specified Display. specified NULL to
41  *          connected Display, connect to the default Display.
42  *
43  * @param[in]   display             display to connect
44  * @param[in]   callback            callback function
45  * @return      result
46  * @retval      ICO_DIC_EOK         Success
47  * @retval      ICO_DIC_ERR         Failed
48  */
49 /*--------------------------------------------------------------------------*/
50 int
51 ico_dic_wayland_init(const char *display, Ico_Dic_Wayland_Cb callback)
52 {
53     ICO_TRA("ico_dic_wayland_init: Enter");
54
55     int ret;
56
57     /* regist callback funtion  */
58     gIco_Dic_Mng.Dic_CallBack = callback;
59
60     /* connect to wayland(retry max 5 sec)  */
61     for (ret = 0; ret < (5000/20); ret++) {
62         gIco_Dic_Mng.Wayland_Display = wl_display_connect(display);
63         if (gIco_Dic_Mng.Wayland_Display) {
64             break;
65         }
66         usleep(20*1000);
67     }
68     if (! gIco_Dic_Mng.Wayland_Display) {
69         ICO_ERR("ico_dic_wayland_init: Leave(ERR), Wayland Connect Error");
70         return ICO_DIC_ERR;
71     }
72
73     /* add listener of wayland registry */
74     gIco_Dic_Mng.Wayland_Registry =
75         wl_display_get_registry(gIco_Dic_Mng.Wayland_Display);
76     wl_registry_add_listener(gIco_Dic_Mng.Wayland_Registry,
77                              &registry_listener, &gIco_Dic_Mng);
78
79     /* display dispatch to wait     */
80     do  {
81         usleep(20*1000);
82         wl_display_dispatch(gIco_Dic_Mng.Wayland_Display);
83     } while ((gIco_Dic_Mng.Wayland_WindowMgr == NULL) ||
84              (gIco_Dic_Mng.Wayland_InputCtl == NULL) ||
85              (gIco_Dic_Mng.Wayland_InputMgr == NULL));
86
87     /* get the Wayland descriptor   */
88     gIco_Dic_Mng.WaylandFd = wl_display_get_fd(gIco_Dic_Mng.Wayland_Display);
89     ICO_DBG("ico_dic_wayland_init: Wayland FD = %d", gIco_Dic_Mng.WaylandFd);
90
91     /* create epoll file descriptor */
92     gIco_Dic_Mng.Dic_efd = epoll_create1(EPOLL_CLOEXEC);
93     if (gIco_Dic_Mng.Dic_efd < 0) {
94         ICO_ERR("ico_dic_wayland_init: Leave(ERR), Epoll Create Error");
95         return ICO_DIC_ERR;
96     }
97     struct epoll_event ev;
98     memset(&ev, 0, sizeof(ev));
99     ev.events = EPOLLIN;
100     ev.data.fd = gIco_Dic_Mng.WaylandFd;
101     if (epoll_ctl(gIco_Dic_Mng.Dic_efd, EPOLL_CTL_ADD,
102                   gIco_Dic_Mng.WaylandFd, &ev) != 0) {
103         ICO_ERR("ico_dic_wayland_init: Leave(ERR), Epoll ctl Error");
104         return ICO_DIC_ERR;
105     }
106     ICO_TRA("ico_dic_wayland_init: Leave(EOK)");
107     return ICO_DIC_OK;
108 }
109
110 /*--------------------------------------------------------------------------*/
111 /**
112  * @brief   ico_dic_wayland_globalcb
113  *
114  * @param[in]   data        the information that appointed at the time of
115  *                          callback registration
116  * @param[in]   registry    wayland registry
117  * @param[in]   wldispid    wayland displya id
118  * @param[in]   event       event name
119  * @param[in]   version     version of Wayland
120  * @return      nothing
121  */
122 /*--------------------------------------------------------------------------*/
123 static void
124 ico_dic_wayland_globalcb(void *data, struct wl_registry *registry, uint32_t wldispid,
125                           const char *event, uint32_t version)
126 {
127     ICO_DBG("ico_dic_wayland_globalcb: Event=%s DispId=%08x", event, wldispid);
128
129     if (strcmp(event, "ico_window_mgr") == 0)  {
130         gIco_Dic_Mng.Wayland_WindowMgr = wl_registry_bind(gIco_Dic_Mng.Wayland_Registry,
131                                                           wldispid,
132                                                           &ico_window_mgr_interface, 1);
133         ICO_DBG("ico_dic_wayland_globalcb: wl_registry_bind(ico_window_mgr)");
134     }
135     else if (strcmp(event, "ico_input_mgr_control") == 0)   {
136         /* conect to multi input manager control interface  */
137         gIco_Dic_Mng.Wayland_InputCtl = wl_registry_bind(gIco_Dic_Mng.Wayland_Registry,
138                                                          wldispid,
139                                                          &ico_input_mgr_control_interface, 1);
140         ICO_DBG("ico_dic_wayland_globalcb: wl_registry_bind(ico_input_mgr_control)");
141     }
142     else if (strcmp(event, "ico_input_mgr_device") == 0) {
143         /* conect to multi input manager device interface   */
144         gIco_Dic_Mng.Wayland_InputMgr = wl_registry_bind(gIco_Dic_Mng.Wayland_Registry,
145                                                          wldispid,
146                                                          &ico_input_mgr_device_interface, 1);
147         ICO_DBG("ico_dic_wayland_globalcb: wl_registry_bind(ico_input_mgr_device)");
148     }
149 }
150
151 /*--------------------------------------------------------------------------*/
152 /**
153  * @brief   ico_dic_wayland_iterate
154  *          iterate processing of wayland
155  *
156  * @param[in]   timeout     wait time miri-sec
157  * @return      nothing
158  */
159 /*--------------------------------------------------------------------------*/
160 int
161 ico_dic_wayland_iterate(struct epoll_event *ev_ret, int timeout)
162 {
163     int nfds;
164     int ii;
165     static uint32_t repert = 0;
166
167     memset(ev_ret, 0, sizeof(struct epoll_event) * ICO_DIC_EVENT_NUM);
168     wl_display_flush(gIco_Dic_Mng.Wayland_Display);
169
170     while (1) {
171         if ((nfds = epoll_wait(gIco_Dic_Mng.Dic_efd, ev_ret,
172                                ICO_DIC_EVENT_NUM, timeout)) > 0) {
173             for (ii = 0; ii < nfds; ii++) {
174                 if (ev_ret[ii].data.fd == gIco_Dic_Mng.WaylandFd) {
175                     wl_display_dispatch(gIco_Dic_Mng.Wayland_Display);
176                     repert ++;
177                     if ((repert % 5) == 0)  {
178                         if (repert % 100)   {
179                             ICO_DBG("ico_dic_wayland_iterate: Event wayland fd");
180                         }
181                         usleep(20*1000);
182                     }
183                 }
184                 else    {
185                     repert = 0;
186                 }
187             }
188             return nfds;
189         }
190         else if (nfds == 0) {
191             return 0;
192         }
193     }
194 }
195
196 /*--------------------------------------------------------------------------*/
197 /**
198  * @brief   ico_dic_add_fd
199  *          Add file descriptor to watch in pool.
200  *
201  * @param[in]   fd                  File descriptor
202  * @return      result
203  * @retval      ICO_DIC_EOK        Success
204  * @retval      ICO_DIC_ERR        Failed
205  */
206 /*--------------------------------------------------------------------------*/
207 int
208 ico_dic_add_fd(int fd)
209 {
210     ICO_DBG("ico_dic_add_fd: Enter(fd=%d)", fd);
211
212     struct epoll_event      ev;
213
214     if (gIco_Dic_Mng.Dic_efd <= 0) {
215         ICO_ERR("ico_dic_add_fd: Leave(ERR), Epoll Never Created");
216         return ICO_DIC_ERR;
217     }
218
219     memset(&ev, 0, sizeof(ev));
220     ev.events = EPOLLIN;
221     ev.data.fd = fd;
222     if (epoll_ctl(gIco_Dic_Mng.Dic_efd, EPOLL_CTL_ADD, fd, &ev) != 0) {
223         ICO_ERR("ico_dic_add_fd: Leave(ERR), Epoll ctl Error");
224         return ICO_DIC_ERR;
225     }
226     ICO_DBG("ico_dic_add_fd: Leave(EOK)");
227
228     return ICO_DIC_OK;
229 }
230
231 /*--------------------------------------------------------------------------*/
232 /**
233  * @brief   ico_dic_wayland_finish
234  *          Finish wayland connection
235  *
236  * @param       nothing
237  * @return      nothing
238  */
239 /*--------------------------------------------------------------------------*/
240 void
241 ico_dic_wayland_finish(void)
242 {
243     ICO_DBG("ico_dic_wayland_finish: Enter");
244
245     wl_display_flush(gIco_Dic_Mng.Wayland_Display);
246     wl_display_disconnect(gIco_Dic_Mng.Wayland_Display);
247
248     ICO_DBG("ico_dic_wayland_finish: Leave");
249 }