Add the tool ico_pseudo_input_device which generates those pseudo devices for a syste...
[profile/ivi/ico-uxf-weston-plugin.git] / tools / ico_pseudo_input_device.c
1 /*
2  * Copyright © 2014 TOYOTA MOTOR CORPORATION.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and
5  * its documentation for any purpose is hereby granted without fee, provided
6  * that the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of the copyright holders not be used in
9  * advertising or publicity pertaining to distribution of the software
10  * without specific, written prior permission.  The copyright holders make
11  * no representations about the suitability of this software for any
12  * purpose.  It is provided "as is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22 /**
23  * @brief   Create pseudo input device for Multi Input Manager
24  *
25  * @date    Feb-21-2014
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <stdint.h>
31 #include <stdbool.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <signal.h>
35 #include <time.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <fcntl.h>
39 #include <linux/input.h>
40 #include <linux/uinput.h>
41 #include <errno.h>
42
43 #include "ico_input_mgr.h"
44 #include "ico_input_mgr-client-protocol.h"
45
46                                             /* create pseudo input device       */
47 static int ico_create_pseudo_device(const char *device, int type);
48
49 static int  uifd_pointer = -1;              /* file descriptor of pointer       */
50 static int  uifd_touch = -1;                /* file descriptor of touch-panel   */
51 static int  uifd_keyboard = -1;             /* file descriptor of keyboard      */
52 static int  mWidth = 1920;                  /* screen width                     */
53 static int  mHeight = 1080;                 /* screen height                    */
54 static int  mRun = 0;                       /* running flag                     */
55
56 /*--------------------------------------------------------------------------*/
57 /**
58  * @brief   ico_create_pseudo_device: create pseudo input device
59  *
60  * @param[in]   device          event device name
61  * @param[in]   type            device type
62  *                              (ICO_INPUT_MGR_DEVICE_TYPE_POINTER/KEYBOARD/TOUCH)
63  * @return      uinput device file descriptor
64  * @retval      >= 0            file descriptor
65  * @retval      -1              error
66  */
67 /*--------------------------------------------------------------------------*/
68 static int
69 ico_create_pseudo_device(const char *device, int type)
70 {
71     int     fd;
72     int     key;
73     char    devFile[64];
74     struct uinput_user_dev  uinputDevice;
75
76     /* check if exist           */
77     for (key = 0; key < 32; key++)  {
78         snprintf(devFile, sizeof(devFile)-1, "/dev/input/event%d", key);
79         fd = open(devFile, O_RDONLY);
80         if (fd < 0)     continue;
81
82         memset(uinputDevice.name, 0, sizeof(uinputDevice.name));
83         ioctl(fd, EVIOCGNAME(sizeof(uinputDevice.name)), uinputDevice.name);
84         close(fd);
85         if (strcmp(uinputDevice.name, device) == 0) {
86             printf("ico_create_pseudo_device: <%s> already exist.\n", device);
87             fflush(stdout);
88             return -1;
89         }
90     }
91
92     fd = open("/dev/uinput", O_RDWR);
93     if (fd < 0)   {
94         printf("ico_create_pseudo_device: <%s> uinput device open Error<%d>\n",
95                device, errno);
96         fflush(stdout);
97         return -1;
98     }
99     memset(&uinputDevice, 0, sizeof(uinputDevice));
100     strncpy(uinputDevice.name, device, UINPUT_MAX_NAME_SIZE-1);
101     uinputDevice.absmax[ABS_X] = mWidth;
102     uinputDevice.absmax[ABS_Y] = mHeight;
103
104     /* uinput device configuration  */
105     if (write(fd, &uinputDevice, sizeof(uinputDevice)) < (int)sizeof(uinputDevice))   {
106         printf("ico_create_pseudo_device: <%s> uinput device regist Error<%d>\n",
107                device, errno);
108         fflush(stdout);
109         close(fd);
110         return -1;
111     }
112
113     /* uinput set event bits        */
114     ioctl(fd, UI_SET_EVBIT, EV_SYN);
115
116     if (type != ICO_INPUT_MGR_DEVICE_TYPE_KEYBOARD) {
117         ioctl(fd, UI_SET_EVBIT, EV_ABS);
118         ioctl(fd, UI_SET_ABSBIT, ABS_X);
119         ioctl(fd, UI_SET_ABSBIT, ABS_Y);
120         if (type == ICO_INPUT_MGR_DEVICE_TYPE_POINTER)  {
121             ioctl(fd, UI_SET_EVBIT, EV_REL);
122             ioctl(fd, UI_SET_ABSBIT, REL_X);
123             ioctl(fd, UI_SET_ABSBIT, REL_Y);
124             ioctl(fd, UI_SET_EVBIT, EV_KEY);
125             ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
126             ioctl(fd, UI_SET_KEYBIT, BTN_RIGHT);
127             ioctl(fd, UI_SET_KEYBIT, BTN_MIDDLE);
128         }
129         else    {
130             ioctl(fd, UI_SET_EVBIT, EV_KEY);
131             ioctl(fd, UI_SET_KEYBIT, BTN_TOUCH);
132             ioctl(fd, UI_SET_KEYBIT, BTN_TOOL_PEN);
133         }
134     }
135     else    {
136         ioctl(fd, UI_SET_EVBIT, EV_KEY);
137         for (key = 0; key < 255; key++)  {
138             ioctl(fd, UI_SET_KEYBIT, key);
139         }
140         ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
141         ioctl(fd, UI_SET_KEYBIT, BTN_RIGHT);
142         ioctl(fd, UI_SET_KEYBIT, BTN_MIDDLE);
143         ioctl(fd, UI_SET_KEYBIT, BTN_TOUCH);
144     }
145     ioctl(fd, UI_SET_EVBIT, EV_MSC);
146     ioctl(fd, UI_SET_MSCBIT, MSC_SCAN);
147
148     if (ioctl(fd, UI_DEV_CREATE, NULL) < 0)   {
149         printf("ico_create_pseudo_device: <%s> uinput device create Error<%d>\n",
150                device, errno);
151         fflush(stdout);
152         close(fd);
153         return -1;
154     }
155     return fd;
156 }
157
158 /*--------------------------------------------------------------------------*/
159 /**
160  * @brief   signal_int: signal handler
161  *
162  * @param[in]   signum      signal number(unused)
163  * @return      nothing
164  */
165 /*--------------------------------------------------------------------------*/
166 static void
167 signal_int(int signum)
168 {
169     printf("ico_pseudo_input_device: terminate signal(%d)\n", signum);
170     fflush(stdout);
171     mRun = 0;
172 }
173
174 /*--------------------------------------------------------------------------*/
175 /**
176  * @brief   main: main routine of ico_create_pseudo_device
177  *
178  * @param[in]   argc            number of arguments
179  * @param[in]   argv            rgument list
180  * @return      result
181  * @retval      0               success
182  * @retval      1               error
183  */
184 /*--------------------------------------------------------------------------*/
185 int
186 main(int argc, char *argv[])
187 {
188     int     i;
189
190     printf("ico_pseudo_input_device: Start\n");
191     fflush(stdout);
192
193     /* get screen width/height          */
194     for (i = 1; i < argc; i++)  {
195         if (strncasecmp(argv[i], "-w=", 3) == 0)    {
196             mWidth = (int)strtol(&argv[i][3], (char **)0, 0);
197             if (mWidth <= 0)    mWidth = 1920;
198         }
199         else if (strncasecmp(argv[i], "-h=", 3) == 0)   {
200             mHeight = (int)strtol(&argv[i][3], (char **)0, 0);
201             if (mHeight <= 0)   mHeight = 1080;
202         }
203         else    {
204             printf("usage: ico_pseudo_input_device [-w=width] [-h=height]\n");
205             fflush(stdout);
206             return 1;
207         }
208     }
209
210 #if 0           /* A daemon cannot do in starting by systemd.   */
211     /* change to daemon                 */
212     if (daemon(0, 1) < 0) {
213         printf("ico_pseudo_input_device: can not create daemon\n");
214         fflush(stdout);
215         return 1;
216     }
217 #endif
218
219     mRun = 1;
220     signal(SIGINT, &signal_int);
221     signal(SIGTERM, &signal_int);
222     signal(SIGHUP, &signal_int);
223
224     /* create pointer(mouse) device     */
225     uifd_pointer = ico_create_pseudo_device(ICO_PSEUDO_INPUT_POINTER,
226                                             ICO_INPUT_MGR_DEVICE_TYPE_POINTER);
227     /* create touch-panel device        */
228     uifd_touch = ico_create_pseudo_device(ICO_PSEUDO_INPUT_TOUCH,
229                                           ICO_INPUT_MGR_DEVICE_TYPE_TOUCH);
230     /* create keyboard device           */
231     uifd_keyboard = ico_create_pseudo_device(ICO_PSEUDO_INPUT_KEY,
232                                              ICO_INPUT_MGR_DEVICE_TYPE_KEYBOARD);
233
234     if ((uifd_pointer < 0) && (uifd_touch < 0) && (uifd_keyboard < 0))  {
235         printf("ico_pseudo_input_device: can not create pseude input devices\n");
236         fflush(stdout);
237         return 1;
238     }
239
240     while (mRun)    {
241         sleep(3600);
242     }
243
244     printf("ico_pseudo_input_device: Exit\n");
245     fflush(stdout);
246     return 0;
247 }