Updated package changelog.
authorShibata Makoto <shibata@mac.tec.toyota.co.jp>
Fri, 26 Apr 2013 11:39:06 +0000 (20:39 +0900)
committerShibata Makoto <shibata@mac.tec.toyota.co.jp>
Fri, 26 Apr 2013 11:39:41 +0000 (20:39 +0900)
Change-Id: I24b2c18efcc223a2abea06b317f0b54c976841d9
Signed-off-by: Shibata Makoto <shibata@mac.tec.toyota.co.jp>
27 files changed:
Makefile.am [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
configure.ac [new file with mode: 0644]
egalax_calibration.conf [new file with mode: 0644]
joystick_gtforce.conf [new file with mode: 0644]
joystick_gtforce/Makefile.am [new file with mode: 0644]
joystick_gtforce/dbg_curtime.c [new file with mode: 0644]
joystick_gtforce/ico_ictl-joystick.c [new file with mode: 0644]
joystick_gtforce/ico_ictl-local.h [new file with mode: 0644]
joystick_gtforce/ico_ictl-wayland.c [new file with mode: 0644]
packaging/ico-uxf-device-input-controller.changes [new file with mode: 0644]
packaging/ico-uxf-device-input-controller.spec [new file with mode: 0644]
tests/Makefile.am [new file with mode: 0644]
tests/input-controller-test [new file with mode: 0755]
tests/test-client.c [new file with mode: 0644]
tests/test-common.c [new file with mode: 0644]
tests/test-common.h [new file with mode: 0644]
tests/test-homescreen.c [new file with mode: 0644]
tests/test-send_event.c [new file with mode: 0644]
tests/testdata/cl_surface3.dat [new file with mode: 0644]
tests/testdata/hs_alltest.dat [new file with mode: 0644]
tests/weston.ini [new file with mode: 0644]
tests/weston_ivi_plugin.ini [new file with mode: 0644]
touch_egalax/Makefile.am [new file with mode: 0644]
touch_egalax/ico_ictl-egalax_calibration.c [new file with mode: 0644]
touch_egalax/ico_ictl-touch_egalax.c [new file with mode: 0644]
touch_egalax/ico_ictl-touch_egalax.h [new file with mode: 0644]

diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..a5ec0c8
--- /dev/null
@@ -0,0 +1,6 @@
+SUBDIRS = joystick_gtforce touch_egalax tests
+
+DIST_SUBDIRS = joystick_gtforce touch_egalax tests
+
+DISTCHECK_CONFIGURE_FLAGS = --disable-setuid-install
+
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..916169a
--- /dev/null
@@ -0,0 +1,9 @@
+#! /bin/sh
+
+test -n "$srcdir" || srcdir=`dirname "$0"`
+test -n "$srcdir" || srcdir=.
+(
+  cd "$srcdir" &&
+  autoreconf --force -v --install
+) || exit
+test -n "$NOCONFIGURE" || "$srcdir/configure" "$@"
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..61e9d3b
--- /dev/null
@@ -0,0 +1,57 @@
+AC_PREREQ([2.68])
+AC_INIT([ico-uxf-device-input-controller],
+        [0.4.91],
+        [https://BUG-REPORT-ADDRESS])
+
+AC_CONFIG_HEADERS([config.h])
+
+AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz])
+
+AM_SILENT_RULES([yes])
+
+# Check for programs
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_SED
+
+# Initialize libtool
+LT_PREREQ([2.2])
+LT_INIT([disable-static])
+
+PKG_PROG_PKG_CONFIG()
+
+AC_CHECK_HEADERS([execinfo.h])
+
+AC_CHECK_FUNCS([mkostemp strchrnul])
+
+AC_ARG_ENABLE(setuid-install, [  --enable-setuid-install],,
+             enable_setuid_install=yes)
+AM_CONDITIONAL(ENABLE_SETUID_INSTALL, test x$enable_setuid_install = xyes)
+
+SHARED_LIBS=
+SHARED_CFLAGS=
+AC_SUBST(SHARED_LIBS)
+AC_SUBST(SHARED_CFLAGS)
+
+COMPOSITOR_LIBS="$COMPOSITOR_LIBS"
+COMPOSITOR_CFLAGS="$COMPOSITOR_CFLAGS"
+
+AM_CONDITIONAL(ENABLE_DESKTOP_SHELL, true)
+
+if test "x$GCC" = "xyes"; then
+       my_common_gcc_flags="-Wall -Wextra -Wno-unused-parameter \
+               -Wno-missing-field-initializers -g -fvisibility=hidden"
+       GCC_CFLAGS="$my_common_gcc_flags \
+               -Wstrict-prototypes -Wmissing-prototypes"
+       GCC_CXXFLAGS="$my_common_gcc_flags"
+fi
+AC_SUBST(GCC_CFLAGS)
+AC_SUBST(GCC_CXXFLAGS)
+
+WAYLAND_SCANNER_RULES(['$(top_srcdir)/protocol'])
+
+AC_CONFIG_FILES([Makefile
+                joystick_gtforce/Makefile
+                touch_egalax/Makefile
+                tests/Makefile])
+AC_OUTPUT
diff --git a/egalax_calibration.conf b/egalax_calibration.conf
new file mode 100644 (file)
index 0000000..7fe61e2
--- /dev/null
@@ -0,0 +1,6 @@
+DWIDTH=1920
+DHEIGHT=1080
+POSITION1=1908*164
+POSITION2=127*175
+POSITION3=1874*1829
+POSITION4=149*1802
diff --git a/joystick_gtforce.conf b/joystick_gtforce.conf
new file mode 100644 (file)
index 0000000..9537ad1
--- /dev/null
@@ -0,0 +1,59 @@
+## Multi Input Controller Configurations for joystick_gtforce
+##  /opt/etc/ico-uxf-device-input-controller/joystick_gtforce.conf
+##     Feb-08-2013
+
+## Device
+[device]
+# Device Name
+name=DrivingForceGT
+# Device Input Controller
+ictl=ico_ictl-joystick
+# Device type('8' is input switch)
+type=8
+# ECU Id
+ecu=0
+
+## Input Switch
+[input]
+## UpDown key input
+0=JS_UPDOWN
+# input event from device(type;number)
+0.event=2;3
+# event code to Multi Input Manager(Up;Down)
+0.code=10:Up;11:Down
+
+## LeftRight key input
+1=JS_LR
+# input event from device(type;number)
+1.event=2;2
+# event code to Multi Input Manager(Left;Right)
+1.code=20:Left;21:Right
+
+## CROSS Button input
+2=JS_CROSS
+# input event from device(type;number)
+2.event=1;0
+# event code to Multi Input Manager
+2.code=30
+
+## SQUARE Button input
+3=JS_SQUARE
+# input event from device(type;number)
+3.event=1;1
+# event code to Multi Input Manager
+3.code=40
+
+## CIRCLE Button input
+4=JS_CIRCLE
+# input event from device(type;number)
+4.event=1;2
+# event code to Multi Input Manager
+4.code=50
+
+## TRIANGLE Button input
+5=JS_TRIANGLE
+# input event from device(type;number)
+5.event=1;3
+# event code to Multi Input Manager
+5.code=60
+
diff --git a/joystick_gtforce/Makefile.am b/joystick_gtforce/Makefile.am
new file mode 100644 (file)
index 0000000..6f3f8ed
--- /dev/null
@@ -0,0 +1,26 @@
+export abs_builddir
+
+glib_inc = -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/lib/i386-linux-gnu/glib-2.0/include
+glib_lib = -lgobject-2.0 -lgthread-2.0 -lrt -lglib-2.0
+
+wayland_client_lib = -lwayland-client
+wayland_ivi_client_lib = -lico-uxf-weston-plugin
+wayland_ivi_client_inc = -I/usr/include/ico-uxf-weston-plugin
+
+AM_CFLAGS = $(GCC_CFLAGS)
+AM_CPPFLAGS = -I$(top_srcdir)/src $(wayland_ivi_client_inc) $(glib_inc) $(COMPOSITOR_CFLAGS)
+
+bin_PROGRAMS =         \
+       ico_ictl-joystick_gtforce
+
+check_LTLIBRARIES = $(TESTS)
+check_PROGRAMS = ico_ictl-joystick
+
+AM_LDFLAGS = -module -avoid-version -rpath $(libdir) $(glib_lib)
+
+ico_ictl_joystick_gtforce_SOURCES = \
+       ico_ictl-joystick.c             \
+       ico_ictl-wayland.c              \
+       dbg_curtime.c
+ico_ictl_joystick_gtforce_LDADD = $(SIMPLE_CLIENT_LIBS) $(wayland_ivi_client_lib) $(wayland_client_lib)
+
diff --git a/joystick_gtforce/dbg_curtime.c b/joystick_gtforce/dbg_curtime.c
new file mode 100644 (file)
index 0000000..23063fb
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
+ *
+ * This program is licensed under the terms and conditions of the
+ * Apache License, version 2.0.  The full text of the Apache License is at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ */
+/**
+ * @brief   Current date & time string for log output
+ *
+ * @date    Feb-08-2013
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <sys/time.h>
+#include <time.h>
+
+const char *dbg_curtime(void);
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   dbg_curtime: Current time for Debug Write
+ *
+ * @param   None
+ * @return  String pointer for current time
+ */
+/*--------------------------------------------------------------------------*/
+const char *
+dbg_curtime(void)
+{
+    struct timeval  NowTime;            /* Current date & time              */
+    static int      NowZone = (99*60*60);/* Local time                      */
+    extern long     timezone;           /* System time zone                 */
+    static char     sBuf[28];
+
+    if (NowZone > (24*60*60))  {
+        tzset();
+        NowZone = timezone;
+    }
+    gettimeofday(&NowTime, (struct timezone *)0);
+    NowTime.tv_sec -= NowZone;
+
+    sprintf(sBuf, "[%02d:%02d:%02d.%03d]",
+            (int)((NowTime.tv_sec/3600) % 24),
+            (int)((NowTime.tv_sec/60) % 60),
+            (int)(NowTime.tv_sec % 60),
+            (int)NowTime.tv_usec/1000);
+
+    return(sBuf);
+}
+
diff --git a/joystick_gtforce/ico_ictl-joystick.c b/joystick_gtforce/ico_ictl-joystick.c
new file mode 100644 (file)
index 0000000..3e10160
--- /dev/null
@@ -0,0 +1,658 @@
+/*
+ * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
+ *
+ * This program is licensed under the terms and conditions of the
+ * Apache License, version 2.0.  The full text of the Apache License is at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ */
+/**
+ * @brief   Device Input Controller(GtForce joystick)
+ * @brief   joystick input event to Input Manager
+ *
+ * @date    Feb-08-2013
+ */
+
+#include    <stdio.h>
+#include    <stdlib.h>
+#include    <unistd.h>
+#include    <strings.h>
+#include    <errno.h>
+#include    <pthread.h>
+#include    <sys/ioctl.h>
+#include    <linux/joystick.h>
+#include    <glib.h>
+
+#include    "ico_ictl-local.h"
+
+/* type definition                                                                  */
+typedef struct  _Ico_ICtl_JS    {
+    int                     fd;                 /* device file fd                   */
+    char                    device[32];         /* device name                      */
+    char                    ictl[32];           /* input controller name            */
+    int                     type;               /* device type                      */
+    int                     hostid;             /* host Id(currently unused)        */
+}   Ico_ICtl_JS;
+
+typedef struct  _Ico_Ictl_Code  {
+    unsigned short          code;               /* code value                       */
+    char                    name[20];           /* code name                        */
+}   Ico_Ictl_Code;
+
+typedef struct  _Ico_ICtl_JS_Input  {
+    char                    name[20];           /* input switch name                */
+    int                     input;              /* input number                     */
+    int                     type;               /* input event type                 */
+    int                     number;             /* input event number               */
+    Ico_Ictl_Code           code[20];           /* key code                         */
+    int                     last;               /* last input code                  */
+}   Ico_ICtl_JS_Input;
+
+/* prototype of static function                                                     */
+static void PrintUsage(const char *pName);
+
+/* table/variable                                                                   */
+int                 mPseudo = 0;                /* pseudo input device for test     */
+int                 mDebug = 0;                 /* debug mode                       */
+int                 mEventLog = 0;              /* event input log                  */
+struct timeval      lastEvent = { 0, 0 };       /* last input event time            */
+int                 gRunning = 1;               /* run state(1:run, 0:finish)       */
+
+/* Input Contorller Table           */
+Ico_ICtl_Mng        gIco_ICtrl_Mng = { 0 };
+Ico_ICtl_JS         gIco_ICtrl_JS = { 0 };
+int                 nIco_ICtrl_JS_Input = 0;
+Ico_ICtl_JS_Input   *gIco_ICtrl_JS_Input = NULL;
+
+/* static functions                 */
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   ico_ictl_find_input_by_name: find Input Table by input switch name
+ *
+ * @param[in]   name        input switch name
+ * @return  result
+ * @retval  !=NULL      success(Input Table address)
+ * @retval  ==NULL      failed
+ */
+/*--------------------------------------------------------------------------*/
+static Ico_ICtl_JS_Input *
+ico_ictl_find_input_by_name(const char *name)
+{
+    Ico_ICtl_JS_Input   *iMng = NULL;
+    int                  ii;
+
+    for (ii = 0; ii < nIco_ICtrl_JS_Input; ii++)    {
+        if (strncasecmp(name, gIco_ICtrl_JS_Input[ii].name, 16) == 0) {
+            iMng = &gIco_ICtrl_JS_Input[ii];
+            break;
+        }
+    }
+    return iMng;
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   ico_ictl_find_input_by_param: find Input Table by input switch type and number
+ *
+ * @param[in]   type        input event type (of Linux Input subsystem)
+ * @param[in]   number      input event number (of Linux Input subsystem)
+ * @return  result
+ * @retval  !=NULL      success(Input Table address)
+ * @retval  ==NULL      failed
+ */
+/*--------------------------------------------------------------------------*/
+static Ico_ICtl_JS_Input *
+ico_ictl_find_input_by_param(int type, int number)
+{
+    Ico_ICtl_JS_Input   *iMng = NULL;
+    int                  ii;
+
+    for (ii = 0; ii < nIco_ICtrl_JS_Input; ii++)    {
+        if ((gIco_ICtrl_JS_Input[ii].type == type)
+            && (gIco_ICtrl_JS_Input[ii].number == number))  {
+            iMng = &gIco_ICtrl_JS_Input[ii];
+            break;
+        }
+    }
+    return iMng;
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   conf_getUint: convert integer string to value
+ *
+ * @param[in]   str         integer string
+ * @return  result
+ * @retval  >=0         success(converted vaule)
+ * @retval  -1          failed
+ */
+/*--------------------------------------------------------------------------*/
+static int
+conf_getUint(const char *str)
+{
+    int     key = -1;
+    char    *errpt;
+
+    if (str != NULL)    {
+        errpt = NULL;
+        key = strtol(str, &errpt, 0);
+        if ((errpt) && (*errpt != 0))  {
+            key = -1;
+        }
+    }
+    return key;
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   conf_countNumericalKey: get configuration list
+ *
+ * @param[in]   keyfile     configuration file
+ * @param[in]   group       configuration key group name
+ * @return  result
+ * @retval  !=NULL          success(configuration list)
+ * @retval  ==NULL          failed
+ */
+/*--------------------------------------------------------------------------*/
+static GList *
+conf_countNumericalKey(GKeyFile *keyfile, const char *group)
+{
+    GList* list=NULL;
+    char **result;
+    gsize length;
+    int i;
+
+    result = g_key_file_get_keys(keyfile, group, &length, NULL);
+
+    for (i = 0; i < (int)length; i++) {
+        int id = conf_getUint(result[i]);
+        if (id >= 0) {
+            list=g_list_append(list, g_strdup(result[i]));
+        }
+    }
+    g_strfreev(result);
+    return list;
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   conf_appendStr: connect strings
+ *
+ * @param[in]   str1        string 1
+ * @param[in]   str2        string 2
+ * @return  connected string
+ */
+/*--------------------------------------------------------------------------*/
+static char *
+conf_appendStr(const char *str1, const char *str2)
+{
+    static char buf[128];
+    snprintf(buf, sizeof(buf)-1, "%s%s", str1, str2);
+    return buf;
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   ico_ictl_read_conf: read configuration file
+ *
+ * @param[in]   file        configuration file path name
+ * @return  result
+ * @retval  ICO_ICTL_OK     sccess
+ * @retval  ICO_ICTL_ERR    failed
+ */
+/*--------------------------------------------------------------------------*/
+static int
+ico_ictl_read_conf(const char *file)
+{
+    DEBUG_PRINT("ico_ictl_read_conf: Enter(file=%s)", file);
+
+    GKeyFile            *keyfile;
+    GKeyFileFlags       flags;
+    GString             *filepath;
+    GList               *idlist;
+    GError              *error = NULL;
+    Ico_ICtl_JS_Input   *iMng;
+    char                *name;
+    gsize               length;
+    int                 ii, jj;
+
+    keyfile = g_key_file_new();
+    flags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS;
+
+    filepath = g_string_new(file);
+
+    if (! g_key_file_load_from_file(keyfile, filepath->str, flags, &error)) {
+        ERROR_PRINT("ico_ictl_read_conf: Leave(can not open conf file)");
+        g_string_free(filepath, TRUE);
+        return ICO_ICTL_ERR;
+    }
+    g_string_free(filepath, TRUE);
+
+    /* count number of key in [device] section   */
+    memset((char *)&gIco_ICtrl_JS, 0, sizeof(gIco_ICtrl_JS));
+    name = g_key_file_get_string(keyfile, "device", "name", &error);
+    if (name)   {
+        strncpy(gIco_ICtrl_JS.device, name, sizeof(gIco_ICtrl_JS.device)-1);
+    }
+    name = g_key_file_get_string(keyfile, "device", "ictl", &error);
+    if (name)   {
+        strncpy(gIco_ICtrl_JS.ictl, name, sizeof(gIco_ICtrl_JS.ictl)-1);
+    }
+    gIco_ICtrl_JS.type = g_key_file_get_integer(keyfile, "device", "type", &error);
+    gIco_ICtrl_JS.hostid = g_key_file_get_integer(keyfile, "device", "ecu", &error);
+
+    /* count number of key in [input] section   */
+    idlist = conf_countNumericalKey(keyfile, "input");
+    length = g_list_length(idlist);
+    if (length <= 0)    {
+        length = 1;
+    }
+    nIco_ICtrl_JS_Input = 0;
+    gIco_ICtrl_JS_Input = (Ico_ICtl_JS_Input *)malloc(sizeof(Ico_ICtl_JS_Input) * length);
+    if (! gIco_ICtrl_JS_Input)  {
+        ERROR_PRINT("joystick_gtforce: No Memory");
+        exit(1);
+    }
+    memset((char *)gIco_ICtrl_JS_Input, 0, sizeof(Ico_ICtl_JS_Input) * length);
+
+    for (ii = 0; ii < (int)length; ii++) {
+        const char  *g = "input";
+        char        *key = (char *)g_list_nth_data(idlist, ii);
+        gsize       listsize;
+        gint        *attr;
+        gchar       **code;
+
+        name = g_key_file_get_string(keyfile, g, key, &error);
+        if (name == NULL)   continue;
+
+        iMng = ico_ictl_find_input_by_name(name);
+        if (iMng != NULL)   {
+            /* multiple define  */
+            ERROR_PRINT("ico_ictl_read_conf: switch name(%s) re-define", name);
+            continue;
+        }
+        iMng = &gIco_ICtrl_JS_Input[nIco_ICtrl_JS_Input];
+
+        iMng->input = conf_getUint(key);
+        strncpy(iMng->name, name, sizeof(iMng->name)-1);
+
+        /* event            */
+        attr = g_key_file_get_integer_list(keyfile, g, conf_appendStr(key, ".event"),
+                                           &listsize, &error);
+        if (listsize < 2)   continue;
+        iMng->type = attr[0];
+        iMng->number = attr[1];
+
+        /* code             */
+        code = g_key_file_get_string_list(keyfile, g, conf_appendStr(key, ".code"),
+                                          &listsize, &error);
+        if ((code == NULL) || (listsize <= 0))  {
+            strcpy(iMng->code[0].name, iMng->name);
+        }
+        else    {
+            if ((int)listsize > 20) listsize = 20;
+            for (jj = 0; jj < (int)listsize; jj++) {
+                char    *p = (char *)code[jj];
+                while ((*p != 0) && (*p != ':'))    {
+                    iMng->code[jj].code = iMng->code[jj].code * 10 + *p - '0';
+                    p ++;
+                }
+                if (*p) {
+                    p ++;
+                    strncpy(iMng->code[jj].name, p, sizeof(iMng->code[jj].name)-1);
+                }
+                if (iMng->code[jj].name[0] == 0)    {
+                    strcpy(iMng->code[jj].name, iMng->name);
+                }
+            }
+        }
+        if (code)   g_strfreev(code);
+
+        nIco_ICtrl_JS_Input ++;
+
+        DEBUG_PRINT("%s input:%d(type=%d,number=%d,code=%d[%s],%d[%s])",
+                    iMng->name, iMng->input, iMng->type, iMng->number,
+                    iMng->code[0].code, iMng->code[0].name,
+                    iMng->code[1].code, iMng->code[1].name);
+    }
+    DEBUG_PRINT("ico_ictl_read_conf: Leave");
+
+    return ICO_ICTL_OK;
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   ico_ictl_js_open: open input jyostick input device
+ *
+ * @param[in]   ictlDevName     device name
+ * @return  result
+ * @retval  >= 0            sccess(device file descriptor)
+ * @retval  ICO_ICTL_ERR    failed
+ */
+/*--------------------------------------------------------------------------*/
+static int
+ico_ictl_js_open(const char *ictlDevName)
+{
+    DEBUG_PRINT("ico_ictl_js_open: Enter(device=%s)", ictlDevName)
+
+    int                 fd = -1;
+    char                devFile[64];
+    char                devName[64];
+    int                 ii, jj, kk;
+
+    if (ictlDevName == NULL) {
+        ERROR_PRINT("ico_ictl_js_open: Leave(failed devname NULL)");
+        return ICO_ICTL_ERR;
+    }
+
+    char *pdev = getenv(ICO_ICTL_INPUT_DEV);
+    if ((pdev != NULL) && (*pdev != 0)) {
+        DEBUG_PRINT("ico_ictl_js_open: Pseudo input device(%s)", pdev);
+        mPseudo = 1;
+    }
+    else    {
+        pdev = (char *)ictlDevName;
+    }
+    for (ii = 0; ii < 16; ii++) {
+        if (mPseudo)    {
+            snprintf(devFile, 64, "/dev/input/event%d", ii);
+        }
+        else    {
+            snprintf(devFile, 64, "/dev/input/js%d", ii);
+        }
+        fd = open(devFile, O_RDONLY | O_NONBLOCK);
+        if (fd < 0)     continue;
+
+        memset(devName, 0, sizeof(devName));
+        if (mPseudo)    {
+            ioctl(fd, EVIOCGNAME(sizeof(devName)), devName);
+        }
+        else    {
+            ioctl(fd, JSIOCGNAME(sizeof(devName)), devName);
+        }
+        kk = 0;
+        for (jj = 0; devName[jj]; jj++) {
+            if (devName[jj] != ' ') {
+                devName[kk++] = devName[jj];
+            }
+        }
+        devName[kk] = 0;
+        DEBUG_PRINT("ico_ictl_js_open: %d.%s", ii+1, devName);
+
+        if (strncasecmp(devName, pdev, sizeof(devName)) == 0)   break;
+        /* not match, close */
+        close(fd);
+        fd = -1;
+    }
+
+    if (fd < 0) {
+        ERROR_PRINT("ico_ictl_js_open: Leave(not find device file)");
+        return ICO_ICTL_ERR;
+    }
+    DEBUG_PRINT("ico_ictl_js_open: Leave(found %s[%s] as %s)", pdev, devFile, ictlDevName);
+    return fd;
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   ico_ictl_js_read: read input jyostick input device
+ *
+ * @param[in]   fd          file descriptor
+ * @return      nothing
+ */
+/*--------------------------------------------------------------------------*/
+static void
+ico_ictl_js_read(int fd)
+{
+    DEBUG_PRINT("ico_ictl_js_read: Enter(fd=%d)", fd)
+
+    struct js_event     events[8];
+    struct input_event  pevents[8];
+    int                 rSize;
+    int                 ii, jj;
+    int                 number, value, type, code, state;
+
+    if (mPseudo)    {
+        /* Pseudo event input for Debug */
+        rSize = read(fd, pevents, sizeof(pevents));
+        if (rSize > 0)  {
+            for (ii = 0; ii < rSize/((int)sizeof(struct input_event)); ii++)    {
+                events[ii].time = (pevents[ii].time.tv_sec % 1000) * 1000 +
+                                  pevents[ii].time.tv_usec / 1000;
+                events[ii].type = pevents[ii].type;
+                events[ii].number = pevents[ii].code;
+                events[ii].value = pevents[ii].value;
+                if ((events[ii].type == 2) && (events[ii].value == 9))  {
+                    events[ii].value = 0;
+                }
+                else if ((events[ii].type == 1) && (events[ii].number == 9))    {
+                    events[ii].number = 0;
+                }
+                DEBUG_PRINT("ico_ictl_js_read: pseude event.%d %d.%d.%d",
+                            ii, events[ii].type, events[ii].number, events[ii].value);
+            }
+            rSize = ii * sizeof(struct js_event);
+        }
+    }
+    else    {
+        rSize = read(fd, events, sizeof(events));
+    }
+    if (rSize < 0)  {
+        ii = errno;
+        if ((ii == EINTR) || (ii == EAGAIN))    {
+            return;
+        }
+        DEBUG_PRINT("ico_ictl_js_read: Leave(read error[%d])", ii)
+        exit(9);
+    }
+    for (ii = 0; ii < (rSize / (int)sizeof(struct js_event)); ii++) {
+        Ico_ICtl_JS_Input   *iMng = NULL;
+
+        type = events[ii].type;
+        number = events[ii].number;
+        value = events[ii].value;
+        DEBUG_PRINT("ico_ictl_js_read: Read(type=%d, number=%d, value=%d",
+                    type, number, value);
+
+        iMng = ico_ictl_find_input_by_param(type, number);
+        if (iMng == NULL) {
+            continue;
+        }
+
+        if (mEventLog)  {
+            struct timeval  curtime;
+            gettimeofday(&curtime, NULL);
+
+            if (lastEvent.tv_sec)   {
+                int     sec, usec;
+
+                sec = curtime.tv_sec - lastEvent.tv_sec;
+                usec = curtime.tv_usec - lastEvent.tv_usec;
+
+                if (usec < 0)   {
+                    sec -= 1;
+                    usec += 1000000;
+                }
+                usec += 500;
+                if( usec >= 1000000 )   {
+                    usec -= 1000000;
+                    sec += 1;
+                }
+                if ((sec > 0) || ((sec == 0) && (usec >= 10000)))   {
+                    lastEvent.tv_sec = curtime.tv_sec;
+                    lastEvent.tv_usec = curtime.tv_usec;
+                }
+            }
+            else    {
+                lastEvent.tv_sec = curtime.tv_sec;
+                lastEvent.tv_usec = curtime.tv_usec;
+            }
+            for (jj = 0;
+                 jj < (int)(sizeof(gIco_ICtrl_JS_Input)/sizeof(Ico_ICtl_JS_Input)); jj++) {
+                if ((type == gIco_ICtrl_JS_Input[jj].type) &&
+                    (number == gIco_ICtrl_JS_Input[jj].number))  {
+                    break;
+                }
+            }
+        }
+
+        if (iMng->code[1].code != 0)    {
+            if (value < 0) {
+                code = iMng->code[0].code;
+                state = WL_KEYBOARD_KEY_STATE_PRESSED;
+                iMng->last = code;
+            }
+            else if (value > 0) {
+                code = iMng->code[1].code;
+                state = WL_KEYBOARD_KEY_STATE_PRESSED;
+                iMng->last = code;
+            }
+            else {
+                if (iMng->last != iMng->code[0].code && iMng->last != iMng->code[1].code) {
+                    continue;
+                }
+                code = iMng->last;
+                state = WL_KEYBOARD_KEY_STATE_RELEASED;
+                iMng->last = -1;
+            }
+        }
+        else    {
+            if (value == 0) {
+                code = iMng->code[0].code;
+                state = WL_KEYBOARD_KEY_STATE_RELEASED;
+            }
+            else if (value == 1) {
+                code = iMng->code[0].code;
+                state = WL_KEYBOARD_KEY_STATE_PRESSED;
+            }
+            else {
+                continue;
+            }
+        }
+        ico_input_mgr_device_input_event(gIco_ICtrl_Mng.Wayland_InputMgr, events[ii].time,
+                                         gIco_ICtrl_JS.device, iMng->input, code, state);
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   signal_int: signal handler
+ *
+ * @param[in]   signum      signal number(unused)
+ * @return      nothing
+ */
+/*--------------------------------------------------------------------------*/
+static void
+signal_int(int signum)
+{
+    gRunning = 0;
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   Device Input Controllers: For Joy Stick
+ *          main routine
+ *
+ * @param   main() finction's standard parameter (argc,argv)
+ * @return  result
+ * @retval  0       success
+ * @retval  1       failed
+ */
+/*--------------------------------------------------------------------------*/
+int main(int argc, char *argv[])
+{
+    struct epoll_event  ev_ret[16];
+    char                *ictlDevName = "DrivingForceGT";
+    int                 JSfd;
+    int                 ii, jj;
+    int                 ret;
+    struct sigaction    sigint;
+
+    /* get device name from parameter   */
+    for (ii = 1; ii < argc; ii++) {
+        if (strcasecmp( argv[ii], "-h") == 0) {
+            PrintUsage(argv[0]);
+            exit( 0 );
+        }
+        else if (strcasecmp( argv[ii], "-d") == 0) {
+            /* debug    */
+            mDebug = 1;
+        }
+        else if (strcasecmp( argv[ii], "-l") == 0) {
+            /* event input log  */
+            mEventLog = 1;
+        }
+        else {
+            ictlDevName = argv[ii];
+        }
+    }
+
+    /* change to daemon */
+    if (! mDebug) {
+        if (daemon(0, 1) < 0) {
+            fprintf(stderr, "%s: Can not Create Daemon\n", argv[0]);
+            exit(1);
+        }
+    }
+
+    /* open joystick    */
+    JSfd = ico_ictl_js_open(ictlDevName);
+    if (JSfd < 0) {
+        ERROR_PRINT("main: Leave(Error device open)");
+        exit(1);
+    }
+    gIco_ICtrl_JS.fd = JSfd;
+
+    /* read conf file   */
+    char *confpath = getenv(ICO_ICTL_CONF_ENV);
+    if (!confpath)  {
+        confpath = ICO_ICTL_CONF_FILE;
+    }
+    ico_ictl_read_conf(confpath);
+
+    /* initialize wayland   */
+    ico_ictl_wayland_init(NULL, NULL);
+    ico_ictl_add_fd(JSfd);
+
+    /* send configuration informations to Multi Input Manager   */
+    for (ii = 0; ii < nIco_ICtrl_JS_Input; ii++)    {
+        ico_input_mgr_device_configure_input(
+                gIco_ICtrl_Mng.Wayland_InputMgr, gIco_ICtrl_JS.device, gIco_ICtrl_JS.type,
+                gIco_ICtrl_JS_Input[ii].name, gIco_ICtrl_JS_Input[ii].input,
+                gIco_ICtrl_JS_Input[ii].code[0].name, gIco_ICtrl_JS_Input[ii].code[0].code);
+        for (jj = 1; jj < 20; jj++)     {
+            if (gIco_ICtrl_JS_Input[ii].code[jj].code == 0) break;
+            ico_input_mgr_device_configure_code(
+                    gIco_ICtrl_Mng.Wayland_InputMgr, gIco_ICtrl_JS.device,
+                    gIco_ICtrl_JS_Input[ii].input, gIco_ICtrl_JS_Input[ii].code[jj].name,
+                    gIco_ICtrl_JS_Input[ii].code[jj].code);
+        }
+    }
+
+    /* signal init  */
+    sigint.sa_handler = signal_int;
+    sigemptyset(&sigint.sa_mask);
+    sigint.sa_flags = SA_RESETHAND;
+    sigaction(SIGINT, &sigint, NULL);
+
+    /* main loop    */
+    while (gRunning) {
+        ret = ico_ictl_wayland_iterate(ev_ret, 200);
+        for (ii = 0; ii < ret; ii++) {
+            if (ev_ret[ii].data.fd == JSfd) {
+                ico_ictl_js_read(JSfd);
+            }
+        }
+    }
+    ico_ictl_wayland_finish();
+
+    exit(0);
+}
+
+static void PrintUsage(const char *pName)
+{
+    fprintf( stderr, "Usage: %s [-h] [-d] DeviceName\n", pName );
+    fprintf( stderr, "       ex)\n");
+    fprintf( stderr, "          %s \"Driving Force GT\"\n", pName);
+}
+
diff --git a/joystick_gtforce/ico_ictl-local.h b/joystick_gtforce/ico_ictl-local.h
new file mode 100644 (file)
index 0000000..cc6265b
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
+ *
+ * This program is licensed under the terms and conditions of the
+ * Apache License, version 2.0.  The full text of the Apache License is at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ */
+/**
+ * @brief   header file of Input Controllers
+ *
+ * @date    Feb-20-2013
+ */
+
+#ifndef _ICO_ICTL_LOCAL_H_
+#define _ICO_ICTL_LOCAL_H_
+
+#include    <wayland-client-protocol.h>
+#include    <wayland-client.h>
+#include    <wayland-egl.h>
+#include    <wayland-util.h>
+#include    <sys/ioctl.h>
+#include    <sys/epoll.h>
+#include    <string.h>
+#include    <sys/types.h>
+#include    <sys/stat.h>
+#include    <fcntl.h>
+
+#include    <ico_input_mgr-client-protocol.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* call back function */
+typedef void (*Ico_ICtl_Wayland_Cb)( void );
+
+/* Deafult config file                      */
+#define ICO_ICTL_CONF_FILE  \
+                        "/opt/etc/ico-uxf-device-input-controller/joystick_gtforce.conf"
+/* Environment valible name for config file */
+#define ICO_ICTL_CONF_ENV   "ICTL_GTFORCE_CONF"
+/* Environment valible name for input device*/
+#define ICO_ICTL_INPUT_DEV  "ICTL_GTFORCE_DEV"
+
+#define ICO_ICTL_TOUCH_NONE     0           /* not exist touch event                */
+#define ICO_ICTL_TOUCH_KEYIN    1           /* touch event is reserved              */
+#define ICO_ICTL_TOUCH_PASSED   2           /* touch event is passed                */
+
+#define ICO_ICTL_EVENT_NUM      (16)
+/* return val */
+#define ICO_ICTL_OK             0           /* success                              */
+#define ICO_ICTL_ERR            (-1)        /* failedi                              */
+
+/* management table */
+typedef struct  _Ico_ICtl_Mng   {
+    /* Multi Input Controller   */
+    int                         ICTL_ID;            /* multi input controller ID    */
+    Ico_ICtl_Wayland_Cb         ICtl_CallBack;      /* call back function           */
+
+    /* wayland interfaces       */
+    struct wl_display           *Wayland_Display;   /* Wayland Display              */
+    struct wl_registry          *Wayland_Registry;  /* Wayland Registory            */
+    struct ico_input_mgr_device *Wayland_InputMgr;  /* Wayland multi input manager  */
+
+    int                         WaylandFd;          /* file descriptor of Wayland   */
+    int                         ICTL_EFD;           /* descriptor of epoll          */
+
+}   Ico_ICtl_Mng;
+
+/* function prototype           */
+                                                /* initialization to wayland        */
+int ico_ictl_wayland_init(const char *display ,Ico_ICtl_Wayland_Cb callback);
+void ico_ictl_wayland_finish(void);             /* finish wayland connection        */
+                                                /* iterate wayland connection       */
+int ico_ictl_wayland_iterate(struct epoll_event *ev_ret, int timeout);
+int ico_ictl_add_fd(int fd);                    /* add file descriptor              */
+
+/* macro for debug              */
+extern const char *dbg_curtime(void);
+extern int  mDebug;
+#define DEBUG_PRINT(fmt, ...)   \
+    {if (mDebug) {fprintf(stderr, "%sDBG> "fmt" (%s:%d)\n",dbg_curtime(),##__VA_ARGS__,__FILE__,__LINE__); fflush(stderr);}}
+#define ERROR_PRINT(fmt, ...)   \
+    {fprintf(stderr, "%sERR> "fmt" (%s:%d)\n",dbg_curtime(),##__VA_ARGS__,__FILE__,__LINE__); fflush(stderr);}
+
+#ifdef __cplusplus
+}
+#endif
+#endif  /* _ICO_ICTL_LOCAL_H_ */
+
diff --git a/joystick_gtforce/ico_ictl-wayland.c b/joystick_gtforce/ico_ictl-wayland.c
new file mode 100644 (file)
index 0000000..9665f2c
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
+ *
+ * This program is licensed under the terms and conditions of the
+ * Apache License, version 2.0.  The full text of the Apache License is at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ */
+/**
+ * @brief   Device Input Controllers(wayland processing)
+ *          processing related wayland
+ *
+ * @date    Feb-08-2013
+ */
+
+#include    <stdio.h>
+#include    <stdlib.h>
+#include    <unistd.h>
+#include    <strings.h>
+#include    <errno.h>
+#include    <pthread.h>
+
+#include    "ico_ictl-local.h"
+
+/* prototype of static function             */
+/* callback function from wayland global    */
+static void ico_ictl_wayland_globalcb(void *data, struct wl_registry *registry,
+                                      uint32_t wldispid, const char *event,
+                                      uint32_t version);
+
+/* table/variable                           */
+extern Ico_ICtl_Mng         gIco_ICtrl_Mng;
+
+static const struct wl_registry_listener registry_listener = {
+    ico_ictl_wayland_globalcb
+};
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   ico_ictl_wayland_init
+ *          connect to wayland of specified Display. specified NULL to
+ *          connected Display, connect to the default Display.
+ *
+ * @param[in]   display             display to connect
+ * @param[in]   callback            callback function
+ * @return      result
+ * @retval      ICO_ICTL_EOK        Success
+ * @retval      ICO_ICTL_ERR        Failed
+ */
+/*--------------------------------------------------------------------------*/
+int
+ico_ictl_wayland_init(const char *display, Ico_ICtl_Wayland_Cb callback)
+{
+    DEBUG_PRINT("ico_ictl_wayland_init: Enter");
+
+    int ret;
+
+    /* regist callback funtion  */
+    gIco_ICtrl_Mng.ICtl_CallBack = callback;
+
+    /* connect to wayland(retry max 3 sec)  */
+    for (ret = 0; ret < (3000/20); ret++) {
+        gIco_ICtrl_Mng.Wayland_Display = wl_display_connect(display);
+        if (gIco_ICtrl_Mng.Wayland_Display) {
+            break;
+        }
+        usleep(20*1000);
+    }
+    if (! gIco_ICtrl_Mng.Wayland_Display) {
+        ERROR_PRINT("ico_ictl_wayland_init: Leave(ERR), Wayland Connect Error");
+        return ICO_ICTL_ERR;
+    }
+
+    /* add listener of wayland registry */
+    gIco_ICtrl_Mng.Wayland_Registry =
+        wl_display_get_registry(gIco_ICtrl_Mng.Wayland_Display);
+    wl_registry_add_listener(gIco_ICtrl_Mng.Wayland_Registry,
+                             &registry_listener, &gIco_ICtrl_Mng);
+
+    /* display dispatch to wait     */
+    do  {
+        wl_display_dispatch(gIco_ICtrl_Mng.Wayland_Display);
+    } while (gIco_ICtrl_Mng.Wayland_InputMgr == NULL);
+
+    /* get the Wayland descriptor   */
+    gIco_ICtrl_Mng.WaylandFd =
+        wl_display_get_fd(gIco_ICtrl_Mng.Wayland_Display);
+    DEBUG_PRINT("ico_ictl_wayland_init: WFD = %d", gIco_ICtrl_Mng.WaylandFd);
+
+    /* create epoll file descriptor */
+    gIco_ICtrl_Mng.ICTL_EFD = epoll_create1(EPOLL_CLOEXEC);
+    if (gIco_ICtrl_Mng.ICTL_EFD < 0) {
+        ERROR_PRINT("ico_ictl_wayland_init: Leave(ERR), Epoll Create Error");
+        return ICO_ICTL_ERR;
+    }
+    struct epoll_event ev;
+    memset(&ev, 0, sizeof(ev));
+    ev.events = EPOLLIN;
+    ev.data.fd = gIco_ICtrl_Mng.WaylandFd;
+    if (epoll_ctl(gIco_ICtrl_Mng.ICTL_EFD, EPOLL_CTL_ADD,
+                  gIco_ICtrl_Mng.WaylandFd, &ev) != 0) {
+        ERROR_PRINT("ico_ictl_wayland_init: Leave(ERR), Epoll ctl Error");
+        return ICO_ICTL_ERR;
+    }
+    DEBUG_PRINT("ico_ictl_wayland_init: Leave(EOK)");
+    return ICO_ICTL_OK;
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   ico_ictl_wayland_globalcb
+ *
+ * @param[in]   data        the information that appointed at the time of
+ *                          callback registration
+ * @param[in]   registry    wayland registry
+ * @param[in]   wldispid    wayland displya id
+ * @param[in]   event       event name
+ * @param[in]   version     version of Wayland
+ * @return      nothing
+ */
+/*--------------------------------------------------------------------------*/
+static void
+ico_ictl_wayland_globalcb(void *data, struct wl_registry *registry, uint32_t wldispid,
+                          const char *event, uint32_t version)
+{
+    DEBUG_PRINT("ico_ictl_wayland_globalcb: Event=%s DispId=%08x", event, wldispid);
+
+    if (strcmp(event, "ico_input_mgr_device") == 0) {
+        /* connect ictl_master in multi input manager   */
+        gIco_ICtrl_Mng.Wayland_InputMgr = (struct ico_input_mgr_device *)
+            wl_registry_bind(gIco_ICtrl_Mng.Wayland_Registry,
+                             wldispid, &ico_input_mgr_device_interface, 1);
+
+        DEBUG_PRINT("ico_ictl_wayland_globalcb: wl_registry_bind(ico_input_mgr_device)");
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   ico_ictl_wayland_iterate
+ *          iterate processing of wayland
+ *
+ * @param[in]   timeout     wait time miri-sec
+ * @return      nothing
+ */
+/*--------------------------------------------------------------------------*/
+int
+ico_ictl_wayland_iterate(struct epoll_event *ev_ret, int timeout)
+{
+    int nfds;
+    int ii = 0;
+
+    memset(ev_ret, 0, sizeof(struct epoll_event) * ICO_ICTL_EVENT_NUM);
+    wl_display_flush(gIco_ICtrl_Mng.Wayland_Display);
+
+    while (1) {
+        if ((nfds = epoll_wait( gIco_ICtrl_Mng.ICTL_EFD, ev_ret,
+                                       ICO_ICTL_EVENT_NUM, timeout)) > 0) {
+            for (ii = 0; ii < nfds; ii++) {
+                if (ev_ret[ii].data.fd == gIco_ICtrl_Mng.WaylandFd) {
+                    wl_display_dispatch(gIco_ICtrl_Mng.Wayland_Display);
+                    DEBUG_PRINT( "ico_ictl_wayland_iterate: Exit wayland fd");
+                }
+            }
+            return nfds;
+        }
+        else if (nfds == 0) {
+            return nfds;
+        }
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   ico_ictl_add_fd
+ *          Add file descriptor to watch in pool.
+ *
+ * @param[in]   fd                  File descriptor
+ * @return      result
+ * @retval      ICO_ICTL_EOK        Success
+ * @retval      ICO_ICTL_ERR        Failed
+ */
+/*--------------------------------------------------------------------------*/
+int
+ico_ictl_add_fd(int fd)
+{
+    DEBUG_PRINT("ico_ictl_add_fd: Enter(fd=%d)", fd);
+
+    struct epoll_event      ev;
+
+    if (gIco_ICtrl_Mng.ICTL_EFD <= 0) {
+        ERROR_PRINT("ico_ictl_add_fd: Leave(ERR), Epoll Never Created");
+        return ICO_ICTL_ERR;
+    }
+
+    memset(&ev, 0, sizeof(ev));
+    ev.events = EPOLLIN;
+    ev.data.fd = fd;
+    if (epoll_ctl(gIco_ICtrl_Mng.ICTL_EFD, EPOLL_CTL_ADD, fd, &ev) != 0) {
+        ERROR_PRINT("ico_ictl_add_fd: Leave(ERR), Epoll ctl Error");
+        return ICO_ICTL_ERR;
+    }
+    DEBUG_PRINT("ico_ictl_add_fd: Leave(EOK)");
+
+    return ICO_ICTL_OK;
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   ico_ictl_wayland_finish
+ *          Finish wayland connection
+ *
+ * @param       nothing
+ * @return      nothing
+ */
+/*--------------------------------------------------------------------------*/
+void
+ico_ictl_wayland_finish(void)
+{
+    DEBUG_PRINT("ico_ictl_wayland_finish: Enter");
+
+    wl_display_flush(gIco_ICtrl_Mng.Wayland_Display);
+    wl_display_disconnect(gIco_ICtrl_Mng.Wayland_Display);
+
+    DEBUG_PRINT("ico_ictl_wayland_finish: Leave");
+}
+
diff --git a/packaging/ico-uxf-device-input-controller.changes b/packaging/ico-uxf-device-input-controller.changes
new file mode 100644 (file)
index 0000000..35ba624
--- /dev/null
@@ -0,0 +1,3 @@
+* Fri Apr 26 2013 Shibata Makoto <shibata@mac.tec.toyota.co.jp> de524fc
+- Import initial.
+
diff --git a/packaging/ico-uxf-device-input-controller.spec b/packaging/ico-uxf-device-input-controller.spec
new file mode 100644 (file)
index 0000000..c125e30
--- /dev/null
@@ -0,0 +1,50 @@
+Name:       ico-uxf-device-input-controller
+Summary:    Device Input Controller
+Version:    0.5.01
+Release:    1.1
+Group:      System/GUI
+License:    Apache License, Version 2.0
+URL:        ""
+Source0:    %{name}-%{version}.tar.bz2
+
+BuildRequires: pkgconfig(wayland-client) >= 1.0
+BuildRequires: pkgconfig(wayland-egl)
+BuildRequires: pkgconfig(egl)
+BuildRequires: pkgconfig(glesv2)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: ico-uxf-weston-plugin-devel >= 0.5.0
+Requires: weston >= 1.0
+Requires: ico-uxf-weston-plugin >= 0.5.0
+
+%description
+Device Input Controller for ico-uxf-weston-plugin(Multi Input Manager)
+
+%prep
+%setup -q -n %{name}-%{version}
+
+%build
+autoreconf --install
+
+%autogen --prefix=/usr
+
+%configure
+make %{?_smp_mflags}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+# configurations
+%define ictl_conf /opt/etc/ico-uxf-device-input-controller
+mkdir -p %{buildroot}%{ictl_conf}
+install -m 0644 joystick_gtforce.conf %{buildroot}%{ictl_conf}
+install -m 0644 egalax_calibration.conf %{buildroot}%{ictl_conf}
+
+%files
+%defattr(-,root,root,-)
+%{_bindir}/ico_ictl-joystick_gtforce
+%{_bindir}/ico_ictl-touch_egalax
+%{_bindir}/ico_ictl-egalax_calibration
+%{ictl_conf}/joystick_gtforce.conf
+%{ictl_conf}/egalax_calibration.conf
+
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644 (file)
index 0000000..eee4ee5
--- /dev/null
@@ -0,0 +1,35 @@
+TESTS_ENVIRONMENT = $(SHELL) $(top_srcdir)/tests/weston-plugin-test
+
+export abs_builddir
+
+EFL_INCLUDE = `pkg-config --cflags ecore-evas ecore evas ecore-wayland elementary`
+AM_CFLAGS = $(GCC_CFLAGS) $(EFL_INCLUDE)
+AM_CPPFLAGS = -I$(top_srcdir)/src -DUNIT_TEST $(COMPOSITOR_CFLAGS)
+
+noinst_PROGRAMS =              \
+       test-send_event         \
+       test-homescreen         \
+       test-client
+
+check_LTLIBRARIES = $(TESTS)
+check_PROGRAMS = test-homescreen test-client test-send_event
+
+AM_LDFLAGS = -module -avoid-version -rpath $(libdir) -lwayland-egl -lEGL -lGLESv2
+AM_CFLAGS = $(wayland_ivi_client_inc) $(GCC_CFLAGS)
+
+test_common_src = test-common.c test-common.h
+test_wayland_client = -lwayland-client
+wayland_ivi_client_lib = -lico-uxf-weston-plugin
+wayland_ivi_client_inc = -I/usr/include/ico-uxf-weston-plugin
+
+test_send_event_SOURCES = test-send_event.c $(test_common_src)
+test_send_event_LDADD = $(SIMPLE_CLIENT_LIBS) $(test_wayland_client)
+
+test_homescreen_SOURCES = test-homescreen.c $(test_common_src)
+test_homescreen_LDADD = $(SIMPLE_CLIENT_LIBS) $(wayland_ivi_client_lib) $(test_wayland_client)
+
+test_client_SOURCES = test-client.c $(test_common_src)
+test_client_LDADD = $(SIMPLE_CLIENT_LIBS) $(wayland_ivi_client_lib) $(test_wayland_client)
+
+EXTRA_DIST = input-controller-test
+
diff --git a/tests/input-controller-test b/tests/input-controller-test
new file mode 100755 (executable)
index 0000000..218335c
--- /dev/null
@@ -0,0 +1,85 @@
+#!/bin/sh
+#
+#      Device Input Controller Test
+#
+#        Remark: This examination premises that Weston does not run.
+
+# 1 Delete log file
+rm -fr ../tests/testlog/*
+
+# 2 Start Pseudo event device (for Touch Panel and Jyostick)
+../tests/test-send_event -device=ico_test_touch -d -mq=55551 2> ../tests/testlog/event_log_touch.log &
+../tests/test-send_event -device=ico_test_joystick -d -J -mq=55552 2> ../tests/testlog/event_log_joystic.log &
+sleep 1
+
+# 3 Start Device Input Controllers
+export CALIBRATOIN_CONF="../egalax_calibration.conf"
+export ICTL_TOUCH_DEV="ico_test_touch"
+#../touch_egalax/ico_ictl-touch_egalax -d -L ico_test_touch 2> ../tests/testlog/touch_egalax.log &
+../touch_egalax/ico_ictl-touch_egalax -d -L > ../tests/testlog/touch_egalax.log 2>&1 &
+sleep 0.5
+export ICTL_GTFORCE_CONF="../joystick_gtforce.conf"
+export ICTL_GTFORCE_DEV="ico_test_joystick"
+#../joystick_gtforce/ico_ictl-joystick_gtforce -d -l ico_test_joystick 2> ../tests/testlog/joystick_gtforce.log &
+../joystick_gtforce/ico_ictl-joystick_gtforce -d -l > ../tests/testlog/joystick_gtforce.log 2>&1 &
+sleep 1
+
+# 4 Weston/Wayland Envionment
+export XDG_RUNTIME_DIR=/tmp/run-root
+export QT_QPA_PLATFORM=wayland
+export ELM_ENGINE=wayland_egl
+export ECORE_EVAS_ENGINE=wayland_egl
+#export ELM_ENGINE=wayland_shm
+#export ECORE_EVAS_ENGINE=wayland_shm
+export EVAS_FONT_DPI=72
+export ECORE_IMF_MODULE=isf
+export ELM_MODULES="ctxpopup_copypasteUI>entry/api:datetime_input_ctxpopup>datetime/api"
+export ELM_SCALE="0.7"
+export ELM_PROFILE=mobile
+
+# 5 Start Weston
+export XDG_CONFIG_HOME="../tests"
+/usr/bin/weston --backend=drm-backend.so --idle-time=0 --log=../tests/testlog/weston.log &
+sleep 1
+
+# 5 Start test-homescreen
+../tests/test-homescreen < ../tests/testdata/hs_alltest.dat 2> ../tests/testlog/test-homescreen.log
+
+# 6 End of Test
+sleep 1
+/usr/bin/killall weston
+/usr/bin/killall test-send_event
+/usr/bin/killall test-send_event
+/usr/bin/killall ico_ictl-touch_egalax
+/usr/bin/killall ico_ictl-joystick_gtforce
+sleep 1
+
+# 9 Check Error
+FOUND_ERR=0
+/bin/grep "ERR>" testlog/*
+if [ "$?" != "1" ] ; then
+       FOUND_ERR=1
+fi
+/bin/grep "WRN>" testlog/*
+if [ "$?" != "1" ] ; then
+       FOUND_ERR=1
+fi
+/bin/grep "Error" testlog/*
+if [ "$?" != "1" ] ; then
+       FOUND_ERR=1
+fi
+/bin/grep "error" testlog/* | /bin/grep -v "error_but_no_problem_for_test"
+if [ "$?" != "1" ] ; then
+       FOUND_ERR=1
+fi
+/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test"
+if [ "$?" != "1" ] ; then
+       FOUND_ERR=1
+fi
+
+if [ $FOUND_ERR = 0 ] ; then
+       echo "Device Input Controller Test: OK"
+else
+       echo "Device Input Controller Test: ERROR"
+fi
+
diff --git a/tests/test-client.c b/tests/test-client.c
new file mode 100644 (file)
index 0000000..f6b877e
--- /dev/null
@@ -0,0 +1,634 @@
+/*
+ * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
+ *
+ * This program is licensed under the terms and conditions of the
+ * Apache License, version 2.0.  The full text of the Apache License is at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ */
+/**
+ * @brief   Wayland Application for uint test of Weston(Wayland) IVI plugins
+ *
+ * @date    Feb-08-2013
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+#include <poll.h>
+#include <wayland-client.h>
+#include <linux/input.h>
+#include "ico_ivi_shell-client-protocol.h"
+#include "ico_window_mgr-client-protocol.h"
+#include "ico_input_mgr-client-protocol.h"
+#include "test-common.h"
+
+#define MAX_CON_NAME    127
+
+struct display {
+    struct wl_display *display;
+    struct wl_registry *registry;
+    struct wl_compositor *compositor;
+    struct wl_shell *shell;
+    struct ico_ivi_shell *ico_ivi_shell;
+    struct ico_window_mgr *ico_window_mgr;
+    struct ico_exinput *ico_exinput;
+    struct input *input;
+    struct output *output;
+    struct surface *surface;
+    int    init_color;
+    int    init_width;
+    int    init_height;
+    int    prompt;
+    char   connect[MAX_CON_NAME+1];
+};
+
+struct input {
+    struct display *display;
+    struct wl_seat *seat;
+    struct wl_pointer *pointer;
+    struct wl_keyboard *keyboard;
+    float x, y;
+    uint32_t button_mask;
+    struct surface *pointer_focus;
+    struct surface *keyboard_focus;
+    uint32_t last_key, last_key_state;
+};
+
+struct output {
+    struct display *display;
+    struct wl_output *output;
+    int x, y;
+    int width, height;
+};
+
+struct surface {
+    struct display *display;
+    struct wl_surface *surface;
+    struct wl_shell_surface *shell_surface;
+    struct output *output;
+    EGLDisplay  dpy;
+    EGLConfig   conf;
+    EGLContext  ctx;
+    EGLSurface  egl_surface;
+};
+
+static void clear_surface(struct display *display);
+
+static void
+pointer_handle_enter(void *data, struct wl_pointer *pointer,
+                     uint32_t serial, struct wl_surface *surface,
+                     wl_fixed_t x, wl_fixed_t y)
+{
+    struct input *input = data;
+
+    input->pointer_focus = wl_surface_get_user_data(surface);
+    input->x = wl_fixed_to_double(x);
+    input->y = wl_fixed_to_double(y);
+    print_log("CLIENT: got pointer enter (%d,%d), surface %p",
+              (int)input->x, (int)input->y, surface);
+}
+
+static void
+pointer_handle_leave(void *data, struct wl_pointer *pointer,
+                     uint32_t serial, struct wl_surface *surface)
+{
+    struct input *input = data;
+
+    input->pointer_focus = NULL;
+
+    print_log("CLIENT: got pointer leave, surface %p", surface);
+}
+
+static void
+pointer_handle_motion(void *data, struct wl_pointer *pointer,
+                      uint32_t time, wl_fixed_t x, wl_fixed_t y)
+{
+    struct input *input = data;
+
+    input->x = wl_fixed_to_double(x);
+    input->y = wl_fixed_to_double(y);
+
+    print_log("CLIENT: got pointer motion (%d,%d)", (int)input->x, (int)input->y);
+}
+
+static void
+pointer_handle_button(void *data, struct wl_pointer *pointer,
+                      uint32_t serial, uint32_t time, uint32_t button, uint32_t state_w)
+{
+    struct input *input = data;
+    uint32_t bit;
+    enum wl_pointer_button_state state = state_w;
+
+    bit = 1 << (button - BTN_LEFT);
+    if (state == WL_POINTER_BUTTON_STATE_PRESSED)
+        input->button_mask |= bit;
+    else
+        input->button_mask &= ~bit;
+    print_log("CLIENT: got pointer button %u %u", button, state_w);
+}
+
+static void
+pointer_handle_axis(void *data, struct wl_pointer *pointer,
+                    uint32_t time, uint32_t axis, wl_fixed_t value)
+{
+    fprintf(stderr, "CLIENT: got pointer axis %u %d\n", axis, value);
+}
+
+static void
+keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
+                       uint32_t format, int fd, uint32_t size)
+{
+    close(fd);
+    print_log("CLIENT: got keyboard keymap");
+}
+
+static void
+keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
+                      uint32_t serial, struct wl_surface *surface, struct wl_array *keys)
+{
+    struct input *input = data;
+
+    input->keyboard_focus = wl_surface_get_user_data(surface);
+    print_log("CLIENT: got keyboard enter, surface %p", surface);
+}
+
+static void
+keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
+                      uint32_t serial, struct wl_surface *surface)
+{
+    struct input *input = data;
+
+    input->keyboard_focus = NULL;
+    print_log("CLIENT: got keyboard leave, surface %p", surface);
+}
+
+static void
+keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
+                    uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
+{
+    struct input *input = data;
+
+    input->last_key = key;
+    input->last_key_state = state;
+
+    print_log("CLIENT: got keyboard key %u %u", key, state);
+}
+
+static void
+keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
+                          uint32_t serial, uint32_t mods_depressed,
+                          uint32_t mods_latched, uint32_t mods_locked, uint32_t group)
+{
+    print_log("CLIENT: got keyboard modifier");
+}
+
+static const struct wl_pointer_listener pointer_listener = {
+    pointer_handle_enter,
+    pointer_handle_leave,
+    pointer_handle_motion,
+    pointer_handle_button,
+    pointer_handle_axis,
+};
+
+static const struct wl_keyboard_listener keyboard_listener = {
+    keyboard_handle_keymap,
+    keyboard_handle_enter,
+    keyboard_handle_leave,
+    keyboard_handle_key,
+    keyboard_handle_modifiers,
+};
+
+static void
+seat_handle_capabilities(void *data, struct wl_seat *seat,
+                         enum wl_seat_capability caps)
+{
+    struct input *input = data;
+
+    if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) {
+        input->pointer = wl_seat_get_pointer(seat);
+        wl_pointer_set_user_data(input->pointer, input);
+        wl_pointer_add_listener(input->pointer, &pointer_listener,
+                    input);
+    }
+    else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) {
+        wl_pointer_destroy(input->pointer);
+        input->pointer = NULL;
+    }
+
+    if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard) {
+        input->keyboard = wl_seat_get_keyboard(seat);
+        wl_keyboard_set_user_data(input->keyboard, input);
+        wl_keyboard_add_listener(input->keyboard, &keyboard_listener,
+                     input);
+    }
+    else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard) {
+        wl_keyboard_destroy(input->keyboard);
+        input->keyboard = NULL;
+    }
+}
+
+static const struct wl_seat_listener seat_listener = {
+    seat_handle_capabilities,
+};
+
+static void
+output_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
+                       int physical_width, int physical_height, int subpixel,
+                       const char *make, const char *model, int32_t transform)
+{
+    struct output *output = data;
+
+    output->x = x;
+    output->y = y;
+
+    print_log("CLIENT: Output[geometry] x/y=%d/%d,trans=%d", x, y, transform);
+}
+
+static void
+output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags,
+                   int width, int height, int refresh)
+{
+    struct output *output = data;
+
+    if (flags & WL_OUTPUT_MODE_CURRENT) {
+        output->width = width;
+        output->height = height;
+        print_log("CLIENT: Output[mode] w/h=%d/%d", width, height);
+    }
+}
+
+static const struct wl_output_listener output_listener = {
+    output_handle_geometry,
+    output_handle_mode
+};
+
+static void
+cb_input_capabilities(void *data, struct ico_exinput *ico_exinput,
+                      const char *device, int32_t type, const char *swname, int32_t input,
+                      const char *codename, int32_t code)
+{
+    print_log("CLIENT: Event[input_capabilities] device=%s type=%d sw=%s input=%d "
+              "code=%s[%d]", device, type, swname, input, codename, code);
+}
+
+static void
+cb_input_code(void *data, struct ico_exinput *ico_exinput,
+              const char *device, int32_t input, const char *codename, int32_t code)
+{
+    print_log("CLIENT: Event[input_code] device=%s input=%d code=%s[%d]",
+              device, input, codename, code);
+}
+
+static void
+cb_input_input(void *data, struct ico_exinput *ico_exinput, uint32_t time,
+               const char *device, int32_t input, int32_t code, int32_t state)
+{
+    print_log("CLIENT: Event[input_input] device=%s input=%d code=%d state=%d",
+              device, input, code, state);
+}
+
+static const struct ico_exinput_listener exinput_listener = {
+    cb_input_capabilities,
+    cb_input_code,
+    cb_input_input
+};
+
+static void
+shell_surface_ping(void *data, struct wl_shell_surface *wl_shell_surface, uint32_t serial)
+{
+    print_log("CLIENT: shell_surface_ping: surface=%08x serial=%d",
+              (int)wl_shell_surface, serial);
+}
+
+static void
+shell_surface_configure(void *data, struct wl_shell_surface *wl_shell_surface,
+                        uint32_t edges, int32_t width, int32_t height)
+{
+    print_log("CLIENT: shell_surface_configure: surface=%08x edg=%x, width=%d height=%d",
+              (int)wl_shell_surface, edges, width, height);
+}
+
+static void
+shell_surface_popup_done(void *data, struct wl_shell_surface *wl_shell_surface)
+{
+    print_log("CLIENT: shell_surface_popup_done: surface=%08x", (int)wl_shell_surface);
+}
+
+static const struct wl_shell_surface_listener shell_surface_listener = {
+    shell_surface_ping,
+    shell_surface_configure,
+    shell_surface_popup_done
+};
+
+static void
+handle_global(void *data, struct wl_registry *registry, uint32_t id,
+              const char *interface, uint32_t version)
+{
+    struct display *display = data;
+    struct input *input;
+    struct output *output;
+
+    print_log("CLIENT: handle_global: interface=<%s> id=%d", interface, (int)id);
+
+    if (strcmp(interface, "wl_compositor") == 0) {
+        display->compositor =
+            wl_registry_bind(display->registry,
+                     id, &wl_compositor_interface, 1);
+    }
+    else if (strcmp(interface, "wl_seat") == 0) {
+        input = calloc(1, sizeof *input);
+        input->display = display;
+        input->seat = wl_registry_bind(display->registry, id,
+                           &wl_seat_interface, 1);
+        input->pointer_focus = NULL;
+        input->keyboard_focus = NULL;
+
+        wl_seat_add_listener(input->seat, &seat_listener, input);
+        display->input = input;
+    }
+    else if (strcmp(interface, "wl_output") == 0) {
+        output = malloc(sizeof *output);
+        output->display = display;
+        output->output = wl_registry_bind(display->registry,
+                          id, &wl_output_interface, 1);
+        wl_output_add_listener(output->output,
+                       &output_listener, output);
+        display->output = output;
+
+        print_log("CLIENT: created output global %p", display->output);
+    }
+    else if (strcmp(interface, "wl_shell") == 0)    {
+        display->shell =
+            wl_registry_bind(display->registry,
+                     id, &wl_shell_interface, 1);
+    }
+    else if (strcmp(interface, "ico_ivi_shell") == 0)   {
+        display->ico_ivi_shell =
+            wl_registry_bind(display->registry,
+                     id, &ico_ivi_shell_interface, 1);
+    }
+    else if (strcmp(interface, "ico_window_mgr") == 0)  {
+        display->ico_window_mgr =
+            wl_registry_bind(display->registry,
+                     id, &ico_window_mgr_interface, 1);
+        print_log("CLIENT: created window_mgr global %p", display->ico_window_mgr);
+    }
+    else if (strcmp(interface, "ico_exinput") == 0)   {
+        display->ico_exinput =
+            wl_registry_bind(display->registry,
+                             id, &ico_exinput_interface, 1);
+        ico_exinput_add_listener(display->ico_exinput,
+                                 &exinput_listener, display);
+        print_log("CLIENT: created exinput global %p", display->ico_exinput);
+    }
+}
+
+static const struct wl_registry_listener registry_listener = {
+    handle_global
+};
+
+static void
+surface_enter(void *data, struct wl_surface *wl_surface, struct wl_output *output)
+{
+    struct surface *surface = data;
+
+    surface->output = wl_output_get_user_data(output);
+
+    print_log("CLIENT: got surface enter, output %p", surface->output);
+}
+
+static void
+surface_leave(void *data, struct wl_surface *wl_surface, struct wl_output *output)
+{
+    struct surface *surface = data;
+
+    surface->output = NULL;
+
+    print_log("CLIENT: got surface leave, output %p", wl_output_get_user_data(output));
+}
+
+static const struct wl_surface_listener surface_listener = {
+    surface_enter,
+    surface_leave
+};
+
+static void
+send_keyboard_state(struct display *display)
+{
+    int focus = display->input->keyboard_focus != NULL;
+
+    if (focus) {
+        assert(display->input->keyboard_focus == display->surface);
+    }
+
+    wl_display_flush(display->display);
+
+    print_log("CLIENT: keyboard_state %u %u %d",
+              display->input->last_key, display->input->last_key_state, focus);
+
+    wl_display_roundtrip(display->display);
+}
+
+static void
+send_button_state(struct display *display)
+{
+    wl_display_roundtrip(display->display);
+
+    print_log("CLIENT: button_state %u", display->input->button_mask);
+
+    wl_display_roundtrip(display->display);
+}
+
+static void
+send_state(struct display* display)
+{
+    int visible = display->surface->output != NULL;
+    wl_fixed_t x = wl_fixed_from_int(-1);
+    wl_fixed_t y = wl_fixed_from_int(-1);
+
+    if (display->input->pointer_focus != NULL) {
+        assert(display->input->pointer_focus == display->surface);
+        x = wl_fixed_from_double(display->input->x);
+        y = wl_fixed_from_double(display->input->y);
+    }
+
+    if (visible) {
+        /* FIXME: this fails on multi-display setup */
+        /* assert(display->surface->output == display->output); */
+    }
+
+    wl_display_flush(display->display);
+
+    print_log("CLIENT: state %d %d %d", x, y, visible);
+
+    wl_display_roundtrip(display->display);
+}
+
+static void
+create_surface(struct display *display)
+{
+    struct surface *surface;
+
+    surface = malloc(sizeof *surface);
+    assert(surface);
+    surface->display = display;
+    display->surface = surface;
+    surface->surface = wl_compositor_create_surface(display->compositor);
+    wl_surface_add_listener(surface->surface, &surface_listener, surface);
+
+    if (display->shell) {
+        surface->shell_surface =
+            wl_shell_get_shell_surface(display->shell, surface->surface);
+        if (surface->shell_surface) {
+            wl_shell_surface_add_listener(surface->shell_surface,
+                                          &shell_surface_listener, display);
+            wl_shell_surface_set_toplevel(surface->shell_surface);
+        }
+    }
+    wl_display_flush(display->display);
+
+    print_log("CLIENT: create surface %d shell=%08x",
+              wl_proxy_get_id((struct wl_proxy *) surface->surface),
+              (int)surface->shell_surface);
+
+    poll(NULL, 0, 100); /* Wait for next frame where we'll get events. */
+
+    wl_display_roundtrip(display->display);
+
+    surface->dpy = opengl_init(display->display, &surface->conf, &surface->ctx);
+    if (surface->dpy)   {
+        surface->egl_surface = opengl_create_window(display->display, surface->surface,
+                                                    surface->dpy, surface->conf,
+                                                    surface->ctx, display->init_width,
+                                                    display->init_height, display->init_color);
+        clear_surface(display);
+        print_log("CLIENT: created egl_surface %08x", (int)surface->egl_surface);
+    }
+}
+
+static void
+clear_surface(struct display *display)
+{
+    if (! display->surface) {
+        create_surface(display);
+    }
+    else    {
+        opengl_clear_window(display->init_color);
+        opengl_swap_buffer(display->display,
+                           display->surface->dpy, display->surface->egl_surface);
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    struct display *display;
+    char buf[256];
+    int ret, fd;
+    int msec;
+    int postsec = 0;
+
+    display = malloc(sizeof *display);
+    assert(display);
+    memset((char *)display, 0, sizeof *display);
+
+    display->init_width = 640;
+    display->init_height = 480;
+    display->init_color = 0xA0A08020;
+    for (fd = 1; fd < argc; fd++ )  {
+        if (argv[fd][0] == '-') {
+            if (strncasecmp(argv[fd], "-color=", 7) == 0)   {
+                display->init_color = strtoul(&argv[fd][7], (char **)0, 0);
+            }
+            else if (strncasecmp(argv[fd], "-width=", 7) == 0)  {
+                display->init_width = strtol(&argv[fd][7], (char **)0, 0);
+            }
+            else if (strncasecmp(argv[fd], "-height=", 8) == 0) {
+                display->init_height = strtol(&argv[fd][8], (char **)0, 0);
+            }
+            else if (strncasecmp(argv[fd], "-display=", 9) == 0)   {
+                strncpy(display->connect, &argv[fd][9], MAX_CON_NAME);
+            }
+            else if (strncasecmp(argv[fd], "-postsleep=", 11) == 0)   {
+                postsec = sec_str_2_value(&argv[fd][11]);
+            }
+            else if (strncasecmp(argv[fd], "-prompt=", 8) == 0)  {
+                if (argv[fd][8] == 0)   {
+                    display->prompt = argv[fd][8] & 1;
+                }
+                else    {
+                    display->prompt = 1;
+                }
+            }
+        }
+    }
+
+    if (display->connect[0])    {
+        display->display = wl_display_connect(display->connect);
+    }
+    else    {
+        display->display = wl_display_connect(NULL);
+    }
+    assert(display->display);
+
+    display->registry = wl_display_get_registry(display->display);
+    wl_registry_add_listener(display->registry,
+                 &registry_listener, display);
+    wl_display_dispatch(display->display);
+
+    fd = 0;
+
+    while (1) {
+        sleep_with_wayland(display->display, 20);
+        if (display->prompt)    {
+            printf("CLIENT: "); fflush(stdout);
+        }
+        ret = getdata(display->ico_window_mgr, "CLIENT: ", fd, buf, sizeof(buf));
+        if (ret < 0) {
+            fprintf(stderr, "CLIENT: read error: fd %d, %m\n",
+                fd);
+            break;
+        }
+        if (ret == 0)   continue;
+        wl_display_flush(display->display);
+
+        if ((strncasecmp(buf, "bye", 3) == 0) ||
+            (strncasecmp(buf, "quit", 4) == 0) ||
+            (strncasecmp(buf, "end", 3) == 0))  {
+            /* Exit, end of test            */
+            break;
+        }
+        else if (strncasecmp(buf, "create-surface", ret) == 0) {
+            create_surface(display);
+        }
+        else if (strncasecmp(buf, "clear-surface", 13) == 0) {
+            display->init_color = strtoul(&buf[14], (char **)0, 0);
+            clear_surface(display);
+        }
+        else if (strncasecmp(buf, "send-state", ret) == 0) {
+            send_state(display);
+        }
+        else if (strncasecmp(buf, "send-button-state", ret) == 0) {
+            send_button_state(display);
+        }
+        else if (strncasecmp(buf, "send-keyboard-state", ret) == 0) {
+            send_keyboard_state(display);
+        }
+        else if (strncasecmp(buf, "sleep", 5) == 0) {
+            msec = sec_str_2_value(&buf[6]);
+            sleep_with_wayland(display->display, msec);
+        }
+        else {
+            print_log("CLIENT: unknown command[%s]", buf);
+            return(-1);
+        }
+    }
+    if (postsec > 0)    {
+        sleep_with_wayland(display->display, postsec);
+    }
+
+    exit(0);
+}
+
diff --git a/tests/test-common.c b/tests/test-common.c
new file mode 100644 (file)
index 0000000..5b83995
--- /dev/null
@@ -0,0 +1,411 @@
+/*
+ * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
+ *
+ * This program is licensed under the terms and conditions of the
+ * Apache License, version 2.0.  The full text of the Apache License is at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ */
+/**
+ * @brief   Uint test common routines
+ *
+ * @date    Feb-08-2013
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+#include <errno.h>
+#include <wayland-client.h>
+#include <ico_window_mgr-client-protocol.h>
+#include "test-common.h"
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   getdata: Input data string
+ *
+ * @param[in]   window_mgr  ico_window_mgr, if Null, output to stderr
+ * @param[in]   prompt      Echoback printout header
+ * @param[in]   fd          Input file discriptor
+ * @param[in]   buf         Input buffer
+ * @param[in]   size        Buffer size
+ * @return      Number of input characters
+ * @retval      >= 0        Number of input characters
+ * @retval      < 0         Input error
+ */
+/*--------------------------------------------------------------------------*/
+int
+getdata(void *window_mgr, const char *prompt, int fd, char *buf, const int size)
+{
+    int     ret;
+    int     i, j;
+
+    j = -1;
+    for (i = 0; i < (size-1); i++)  {
+        ret = read(fd, &buf[i], 1);
+
+        if (ret < 0)    {
+            return(ret);
+        }
+
+        if ((buf[i] == '\n') || (buf[i] == '\r'))   break;
+        if (buf[i] == '\t') {
+            buf[i] = ' ';
+        }
+        if ((buf[i] == '#') && (j < 0)) {
+            j = i;
+        }
+    }
+    buf[i] = 0;
+    print_log("%s%s", prompt, buf);
+
+    /* Delete trailing spaces       */
+    if (j >= 0) {
+        for (; j > 0; j--)  {
+            if (buf[j-1] != ' ')    break;
+        }
+        buf[j] = 0;
+        i = j;
+    }
+
+    /* Delete header spaces         */
+    for (j = 0; buf[j]; j++)    {
+        if (buf[j] != ' ')  break;
+    }
+    if (j > 0)  {
+        strcpy( buf, &buf[j] );
+        i -= j;
+    }
+    return(i);
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   print_log: Weston log output
+ *
+ * @param[in]   fmt         printf format
+ * @param[in]   ...         printf arguments
+ * @return      None
+ */
+/*--------------------------------------------------------------------------*/
+void
+print_log(const char *fmt, ...)
+{
+    va_list     ap;
+    char        log[128];
+    struct timeval  NowTime;
+    extern long timezone;
+    static int  sTimeZone = (99*60*60);
+
+    va_start(ap, fmt);
+    vsnprintf(log, sizeof(log)-2, fmt, ap);
+    va_end(ap);
+
+    gettimeofday( &NowTime, (struct timezone *)0 );
+    if( sTimeZone > (24*60*60) )    {
+        tzset();
+        sTimeZone = timezone;
+    }
+    NowTime.tv_sec -= sTimeZone;
+    fprintf(stderr, "[%02d:%02d:%02d.%03d@%d] %s\n",
+            (int)((NowTime.tv_sec/3600) % 24),
+            (int)((NowTime.tv_sec/60) % 60),
+            (int)(NowTime.tv_sec % 60),
+            (int)NowTime.tv_usec/1000, getpid(), log);
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   wayland_dispatch_nonblock: Read from wayland if receive data exist
+ *
+ * @param[in]   display     Wayland connection
+ * @return      None
+ */
+/*--------------------------------------------------------------------------*/
+void
+wayland_dispatch_nonblock(struct wl_display *display)
+{
+    int     nread;
+
+    /* Check wayland input      */
+    do  {
+        /* Flush send data          */
+        wl_display_flush(display);
+
+        nread = 0;
+        if (ioctl(wl_display_get_fd(display), FIONREAD, &nread) < 0)    {
+            nread = 0;
+        }
+        if (nread >= 8) {
+            /* Read event from wayland  */
+            wl_display_dispatch(display);
+        }
+    } while (nread > 0);
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   sleep_with_wayland: Sleep and receive wayland event
+ *
+ * @param[in]   display     Wayland connection
+ * @param[in]   msec        Sleep time (miri-sec)
+ * @return      None
+ */
+/*--------------------------------------------------------------------------*/
+void
+sleep_with_wayland(struct wl_display *display, int msec)
+{
+    int     nread;
+    int     fd;
+
+
+    fd = wl_display_get_fd(display);
+
+    do  {
+        /* Flush send data          */
+        wl_display_flush(display);
+
+        /* Check wayland input      */
+        nread = 0;
+        if (ioctl(fd, FIONREAD, &nread) < 0)    {
+            nread = 0;
+        }
+        if (nread >= 8) {
+            /* Read event from wayland  */
+            wl_display_dispatch(display);
+        }
+        msec -= 20;
+        if (msec >= 0)   usleep(20*1000);
+    } while (msec > 0);
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   wait_with_wayland: Wait for end and receive wayland event
+ *
+ * @param[in]   display     Wayland connection
+ * @param[in]   msec        Maximum wait time (miri-sec)
+ * @param[in]   endflag     End flag address
+ * @return      None
+ */
+/*--------------------------------------------------------------------------*/
+void
+wait_with_wayland(struct wl_display *display, int msec, int *endflag)
+{
+    int     nread;
+    int     fd;
+
+    fd = wl_display_get_fd(display);
+
+    do  {
+        /* Flush send data          */
+        wl_display_flush(display);
+
+        /* Check wayland input      */
+        nread = 0;
+        if (ioctl(fd, FIONREAD, &nread) < 0)    {
+            nread = 0;
+        }
+        if (nread >= 8) {
+            /* Read event from wayland  */
+            wl_display_dispatch(display);
+        }
+        msec -= 20;
+        if (msec >= 0)   usleep(20*1000);
+    } while ((*endflag == 0) && (msec > 0));
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   sec_str_2_value: Convert seconds string to value
+ *
+ * @param[in]   ssec        Time ("sec.msec")
+ * @return      miri-second
+ */
+/*--------------------------------------------------------------------------*/
+int
+sec_str_2_value(const char *ssec)
+{
+    int     sec;
+    int     msec;
+    int     n;
+    char    *errp = NULL;
+
+    sec = strtol(ssec, &errp, 0) * 1000;
+    if ((errp != NULL) && (*errp == '.'))   {
+        msec = 0;
+        n = 0;
+        for (errp++; *errp; errp++) {
+            if ((*errp < '0') || (*errp > '9')) break;
+            msec = msec * 10 + *errp - '0';
+            n++;
+            if (n >= 3) break;
+        }
+        if (n == 1)     msec *= 100;
+        if (n == 2)     msec *= 10;
+        sec += msec;
+    }
+    return(sec);
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   opengl_init: Initialize OpenGL ESv2/EGL
+ *
+ * @param[in]   display     Wayland connection
+ * @param[out]  rconf       EGL configuration
+ * @param[out]  rctx        EGL context
+ * @return      EGL display
+ * @retval      != NULL     EGL display
+ * @retval      == NULL     OpenGL/EGL initialize error
+ */
+/*--------------------------------------------------------------------------*/
+EGLDisplay
+opengl_init(struct wl_display *display, EGLConfig *rconf, EGLContext *rctx)
+{
+    EGLDisplay  dpy;                    /* EGL dsplay id                    */
+    EGLint      major, minor;
+    EGLint      num_configs;
+    EGLConfig   conf = 0;
+    EGLContext  ctx;
+
+    static const EGLint config_attribs[] = {
+        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+        EGL_RED_SIZE, 1,
+        EGL_GREEN_SIZE, 1,
+        EGL_BLUE_SIZE, 1,
+        EGL_ALPHA_SIZE, 1,
+        EGL_DEPTH_SIZE, 1,
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+        EGL_NONE
+    };
+    static const EGLint context_attribs[] = {
+        EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE
+    };
+
+    dpy = eglGetDisplay((EGLNativeDisplayType)display);
+    if (! dpy)  {
+        fprintf(stderr, "eglGetDisplay Error\n");
+        return NULL;
+    }
+
+    if (eglInitialize(dpy, &major, &minor) == EGL_FALSE)    {
+        fprintf(stderr, "eglInitialize Error\n");
+        return NULL;
+    }
+
+    if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) {
+        fprintf(stderr, "eglBindAPI Error\n");
+        return NULL;
+    }
+
+    if (eglChooseConfig(dpy, config_attribs, &conf, 1, &num_configs) == EGL_FALSE)  {
+        fprintf(stderr, "eglChooseConfig Error\n");
+        return NULL;
+    }
+
+    ctx = eglCreateContext(dpy, conf, EGL_NO_CONTEXT, context_attribs);
+    if (! ctx)  {
+        fprintf(stderr, "eglCreateContext Error\n");
+        return NULL;
+    }
+    *rconf = conf;
+    *rctx = ctx;
+
+    wayland_dispatch_nonblock(display);
+
+    return(dpy);
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   opengl_create_window: Create OpenGL/EGL window
+ *
+ * @param[in]   display     Wayland connection
+ * @param[in]   surface     Wayland surface
+ * @param[in]   dpy         EGL display
+ * @param[in]   conf        EGL configuration
+ * @param[in]   ctx         EGL context
+ * @param[in]   width       Widown width
+ * @param[in]   height      Window height
+ * @param[in]   color       Initiale color(A<<24|R<<16|G<<8|B)
+ * @return      EGL surface
+ * @retval      != NULL     EGL surface
+ * @retval      == NULL     Create window error
+ */
+/*--------------------------------------------------------------------------*/
+EGLSurface
+opengl_create_window(struct wl_display *display, struct wl_surface *surface,
+                     EGLDisplay dpy, EGLConfig conf, EGLContext ctx,
+                     const int width, const int height, const int color)
+{
+    struct wl_egl_window    *egl_window;
+    EGLSurface              egl_surface;
+
+    static const EGLint surface_attribs[] = {
+        EGL_ALPHA_FORMAT, EGL_ALPHA_FORMAT_PRE, EGL_NONE
+    };
+
+    egl_window = wl_egl_window_create(surface, width, height);
+    egl_surface = eglCreateWindowSurface(dpy, conf, (EGLNativeWindowType)egl_window,
+                                         surface_attribs);
+    eglMakeCurrent(dpy, egl_surface, egl_surface, ctx);
+    glViewport(0, 0, width, height);
+
+    wayland_dispatch_nonblock(display);
+
+    opengl_clear_window(color);
+
+    opengl_swap_buffer(display, dpy, egl_surface);
+
+    return(egl_surface);
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   opengl_clear_window: OpenGL window clear
+ *
+ * @param[in]   color       Initiale color(A<<24|R<<16|G<<8|B)
+ * @return      None
+ */
+/*--------------------------------------------------------------------------*/
+void
+opengl_clear_window(const unsigned int color)
+{
+    double                  r, g, b, a;
+
+    r = (double)((color>>16) & 0x0ff);
+    r = r / 256.0;
+    g = (double)((color>>8) & 0x0ff);
+    g = g / 256.0;
+    b = (double)(color & 0x0ff);
+    b = b / 256.0;
+    a = (double)((color>>24) & 0x0ff);
+    a = (a + 1.0) / 256.0;
+
+    glClearColor(r, g, b, a);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT| GL_STENCIL_BUFFER_BIT);
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   opengl_create_window: Create OpenGL/EGL window
+ *
+ * @param[in]   display     Wayland connection
+ * @param[in]   dpy         EGL display
+ * @param[in]   egl_surface EGL surface
+ * @return      None
+ */
+/*--------------------------------------------------------------------------*/
+void
+opengl_swap_buffer(struct wl_display *display, EGLDisplay dpy, EGLSurface egl_surface)
+{
+    eglSwapBuffers(dpy, egl_surface);
+
+    wayland_dispatch_nonblock(display);
+}
diff --git a/tests/test-common.h b/tests/test-common.h
new file mode 100644 (file)
index 0000000..a17e3ad
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
+ *
+ * This program is licensed under the terms and conditions of the
+ * Apache License, version 2.0.  The full text of the Apache License is at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ */
+/**
+ * @brief   Header file for uint test common routines
+ *
+ * @date    Feb-08-2013
+ */
+
+#ifndef _TEST_COMMON_H_
+#define _TEST_COMMON_H_
+
+#include    <GLES2/gl2.h>               /* OpenGL ES 2.x                    */
+#include    <EGL/egl.h>                 /* EGL                              */
+#include    <wayland-client.h>          /* Wayland client library           */
+#include    <wayland-egl.h>             /* Wayland EGL library              */
+#include    <wayland-util.h>            /* Wayland Misc library             */
+
+/* Function prototype           */
+int getdata(void *window_mgr, const char *prompt, int fd, char *buf, const int size);
+void print_log(const char *fmt, ...);
+void wayland_dispatch_nonblock(struct wl_display *display);
+void sleep_with_wayland(struct wl_display *display, int msec);
+void wait_with_wayland(struct wl_display *display, int msec, int *endflag);
+int sec_str_2_value(const char *ssec);
+EGLDisplay opengl_init(struct wl_display *display, EGLConfig *rconf, EGLContext *rctx);
+EGLSurface opengl_create_window(struct wl_display *display, struct wl_surface *surface,
+                                EGLDisplay dpy, EGLConfig conf, EGLContext ctx,
+                                const int width, const int height, const int color);
+void opengl_clear_window(const unsigned int color);
+void opengl_swap_buffer(struct wl_display *display, EGLDisplay dpy, EGLSurface egl_surface);
+
+#endif /*_TEST_COMMON_H_*/
diff --git a/tests/test-homescreen.c b/tests/test-homescreen.c
new file mode 100644 (file)
index 0000000..9b7fc68
--- /dev/null
@@ -0,0 +1,1464 @@
+/*
+ * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
+ *
+ * This program is licensed under the terms and conditions of the
+ * Apache License, version 2.0.  The full text of the Apache License is at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ */
+/**
+ * @brief   HomeScreen for uint test of Weston(Wayland) IVI plugins
+ *
+ * @date    Feb-08-2013
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+#include <poll.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <linux/input.h>
+#include <wayland-client.h>
+#include "ico_ivi_shell-client-protocol.h"
+#include "ico_window_mgr-client-protocol.h"
+#include "ico_input_mgr-client-protocol.h"
+#include "test-common.h"
+
+#define MAX_APPID   128
+#define ICO_IVI_MAX_COORDINATE  16383
+
+struct surface_name {
+    struct surface_name *next;
+    int     surfaceid;
+    int     pid;
+    char    appid[MAX_APPID];
+    int     x;
+    int     y;
+    int     width;
+    int     height;
+    int     visible;
+};
+
+#define MAX_CON_NAME    127
+
+struct display {
+    struct wl_display *display;
+    struct wl_registry *registry;
+    struct wl_compositor *compositor;
+    struct wl_shell *shell;
+    struct ico_ivi_shell *ico_ivi_shell;
+    struct ico_window_mgr *ico_window_mgr;
+    struct ico_input_mgr_control *ico_input_mgr;
+    struct ico_input_mgr_device *ico_input_device;
+    struct ico_exinput *ico_exinput;
+    struct input *input;
+    struct output *output;
+    struct surface *surface;
+    struct surface_name *surface_name;
+    struct surface_name *bgsurface_name;
+    int    bg_created;
+    int    init_color;
+    int    init_width;
+    int    init_height;
+    int    surface_created;
+    int    surface_destroyed;
+    int    prompt;
+    int    visible_on_create;
+    char   connect[MAX_CON_NAME+1];
+};
+
+struct input {
+    struct display *display;
+    struct wl_seat *seat;
+    struct wl_pointer *pointer;
+    struct wl_keyboard *keyboard;
+    float x, y;
+    uint32_t button_mask;
+    struct surface *pointer_focus;
+    struct surface *keyboard_focus;
+    uint32_t last_key, last_key_state;
+};
+
+struct output {
+    struct display *display;
+    struct wl_output *output;
+    int x, y;
+    int width, height;
+};
+
+struct surface {
+    struct display *display;
+    struct wl_surface *surface;
+    struct wl_shell_surface *shell_surface;
+    struct output *output;
+    EGLDisplay  dpy;
+    EGLConfig   conf;
+    EGLContext  ctx;
+    EGLSurface  egl_surface;
+};
+
+static void clear_surface(struct display *display);
+
+static void
+pointer_handle_enter(void *data, struct wl_pointer *pointer,
+                     uint32_t serial, struct wl_surface *surface,
+                     wl_fixed_t x, wl_fixed_t y)
+{
+    struct input *input = data;
+
+    input->pointer_focus = wl_surface_get_user_data(surface);
+    input->x = wl_fixed_to_double(x);
+    input->y = wl_fixed_to_double(y);
+    print_log("HOMESCREEN: got pointer enter (%d,%d), surface %p",
+              (int)input->x, (int)input->y, surface);
+}
+
+static void
+pointer_handle_leave(void *data, struct wl_pointer *pointer,
+                     uint32_t serial, struct wl_surface *surface)
+{
+    struct input *input = data;
+
+    input->pointer_focus = NULL;
+
+    print_log("HOMESCREEN: got pointer leave, surface %p", surface);
+}
+
+static void
+pointer_handle_motion(void *data, struct wl_pointer *pointer,
+                      uint32_t time, wl_fixed_t x, wl_fixed_t y)
+{
+    struct input *input = data;
+
+    input->x = wl_fixed_to_double(x);
+    input->y = wl_fixed_to_double(y);
+
+    print_log("HOMESCREEN: got pointer motion (%d,%d)", (int)input->x, (int)input->y);
+}
+
+static void
+pointer_handle_button(void *data, struct wl_pointer *pointer,
+                      uint32_t serial, uint32_t time, uint32_t button, uint32_t state_w)
+{
+    struct input *input = data;
+    uint32_t bit;
+    enum wl_pointer_button_state state = state_w;
+
+    bit = 1 << (button - BTN_LEFT);
+    if (state == WL_POINTER_BUTTON_STATE_PRESSED)
+        input->button_mask |= bit;
+    else
+        input->button_mask &= ~bit;
+    print_log("HOMESCREEN: got pointer button %u %u", button, state_w);
+}
+
+static void
+pointer_handle_axis(void *data, struct wl_pointer *pointer,
+                    uint32_t time, uint32_t axis, wl_fixed_t value)
+{
+    print_log("HOMESCREEN: got pointer axis %u %d", axis, value);
+}
+
+static void
+keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
+                       uint32_t format, int fd, uint32_t size)
+{
+    close(fd);
+    print_log("HOMESCREEN: got keyboard keymap");
+}
+
+static void
+keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
+                      uint32_t serial, struct wl_surface *surface, struct wl_array *keys)
+{
+    struct input *input = data;
+
+    input->keyboard_focus = wl_surface_get_user_data(surface);
+    print_log("HOMESCREEN: got keyboard enter, surface %p", surface);
+}
+
+static void
+keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
+                      uint32_t serial, struct wl_surface *surface)
+{
+    struct input *input = data;
+
+    input->keyboard_focus = NULL;
+    print_log("HOMESCREEN: got keyboard leave, surface %p", surface);
+}
+
+static void
+keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
+                    uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
+{
+    struct input *input = data;
+
+    input->last_key = key;
+    input->last_key_state = state;
+
+    print_log("HOMESCREEN: got keyboard key %u %u", key, state);
+}
+
+static void
+keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
+                          uint32_t serial, uint32_t mods_depressed,
+                          uint32_t mods_latched, uint32_t mods_locked, uint32_t group)
+{
+    print_log("HOMESCREEN: got keyboard modifier");
+}
+
+static const struct wl_pointer_listener pointer_listener = {
+    pointer_handle_enter,
+    pointer_handle_leave,
+    pointer_handle_motion,
+    pointer_handle_button,
+    pointer_handle_axis,
+};
+
+static const struct wl_keyboard_listener keyboard_listener = {
+    keyboard_handle_keymap,
+    keyboard_handle_enter,
+    keyboard_handle_leave,
+    keyboard_handle_key,
+    keyboard_handle_modifiers,
+};
+
+static void
+seat_handle_capabilities(void *data, struct wl_seat *seat,
+                         enum wl_seat_capability caps)
+{
+    struct input *input = data;
+
+    if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) {
+        input->pointer = wl_seat_get_pointer(seat);
+        wl_pointer_set_user_data(input->pointer, input);
+        wl_pointer_add_listener(input->pointer, &pointer_listener,
+                    input);
+    }
+    else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) {
+        wl_pointer_destroy(input->pointer);
+        input->pointer = NULL;
+    }
+
+    if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard) {
+        input->keyboard = wl_seat_get_keyboard(seat);
+        wl_keyboard_set_user_data(input->keyboard, input);
+        wl_keyboard_add_listener(input->keyboard, &keyboard_listener,
+                     input);
+    }
+    else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard) {
+        wl_keyboard_destroy(input->keyboard);
+        input->keyboard = NULL;
+    }
+}
+
+static const struct wl_seat_listener seat_listener = {
+    seat_handle_capabilities,
+};
+
+static void
+surface_enter(void *data, struct wl_surface *wl_surface, struct wl_output *output)
+{
+    struct surface *surface = data;
+
+    surface->output = wl_output_get_user_data(output);
+
+    print_log("HOMESCREEN: got surface enter, output %p", surface->output);
+}
+
+static void
+surface_leave(void *data, struct wl_surface *wl_surface, struct wl_output *output)
+{
+    struct surface *surface = data;
+
+    surface->output = NULL;
+
+    print_log("HOMESCREEN: got surface leave, output %p",
+              wl_output_get_user_data(output));
+}
+
+static const struct wl_surface_listener surface_listener = {
+    surface_enter,
+    surface_leave
+};
+
+static void
+create_surface(struct display *display)
+{
+    struct surface *surface;
+    int id;
+
+    surface = malloc(sizeof *surface);
+    assert(surface);
+    surface->display = display;
+    display->surface = surface;
+    surface->surface = wl_compositor_create_surface(display->compositor);
+    wl_surface_add_listener(surface->surface, &surface_listener, surface);
+
+    if (display->shell) {
+        surface->shell_surface =
+            wl_shell_get_shell_surface(display->shell, surface->surface);
+        if (surface->shell_surface) {
+            wl_shell_surface_set_toplevel(surface->shell_surface);
+        }
+    }
+    wl_display_flush(display->display);
+
+    id = wl_proxy_get_id((struct wl_proxy *) surface->surface);
+    print_log("HOMESCREEN: create surface = %d", id);
+
+    poll(NULL, 0, 100); /* Wait for next frame where we'll get events. */
+
+    wl_display_roundtrip(display->display);
+
+    surface->dpy = opengl_init(display->display, &surface->conf, &surface->ctx);
+    if (surface->dpy)   {
+        surface->egl_surface = opengl_create_window(display->display, surface->surface,
+                                                    surface->dpy, surface->conf,
+                                                    surface->ctx, display->init_width,
+                                                    display->init_height, display->init_color);
+        clear_surface(display);
+        print_log("HOMESCREEN: created egl_surface %08x", (int)surface->egl_surface);
+    }
+}
+
+static void
+clear_surface(struct display *display)
+{
+    if (! display->surface) {
+        create_surface(display);
+    }
+    else    {
+        opengl_clear_window(display->init_color);
+        opengl_swap_buffer(display->display,
+                           display->surface->dpy, display->surface->egl_surface);
+    }
+}
+
+static void
+output_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
+                       int physical_width, int physical_height, int subpixel,
+                       const char *make, const char *model, int32_t transform)
+{
+    struct output *output = data;
+
+    output->x = x;
+    output->y = y;
+}
+
+static void
+output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags,
+                   int width, int height, int refresh)
+{
+    struct output *output = data;
+
+    if (flags & WL_OUTPUT_MODE_CURRENT) {
+        struct display  *display = output->display;
+
+        output->width = width;
+        output->height = height;
+
+        print_log("HOMESCREEN: Event[handle_mode] x/y=%d/%d bgsurf=%08x",
+                  width, height, (int)display->bgsurface_name);
+
+        display->init_width = width;
+        display->init_height = height;
+
+        if (display->bgsurface_name)    {
+            ico_window_mgr_set_positionsize(display->ico_window_mgr,
+                                            display->bgsurface_name->surfaceid,
+                                            0, 0, width, height);
+        }
+        else if (display->bg_created == 0)  {
+            display->bg_created = 9;
+            create_surface(output->display);
+        }
+    }
+}
+
+static const struct wl_output_listener output_listener = {
+    output_handle_geometry,
+    output_handle_mode
+};
+
+static int
+search_surface(struct display *display, const char *surfname)
+{
+    struct surface_name     *p;
+
+    p = display->surface_name;
+    while (p)   {
+        if (strcmp(p->appid, surfname) == 0)    break;
+        p = p->next;
+    }
+
+    if (p)  {
+        return(p->surfaceid);
+    }
+    else    {
+        return(-1);
+    }
+}
+
+static struct surface_name *
+search_surfacename(struct display *display, const char *surfname)
+{
+    struct surface_name     *p;
+
+    p = display->surface_name;
+    while (p)   {
+        if (strcmp(p->appid, surfname) == 0)    break;
+        p = p->next;
+    }
+    return(p);
+}
+
+static struct surface_name *
+search_surfaceid(struct display *display, const int surfaceid)
+{
+    struct surface_name     *p;
+
+    p = display->surface_name;
+    while (p)   {
+        if (p->surfaceid == surfaceid)  {
+            return(p);
+        }
+        p = p->next;
+    }
+    return(NULL);
+}
+
+static void
+window_created(void *data, struct ico_window_mgr *ico_window_mgr,
+               uint32_t surfaceid, int32_t pid, const char *appid)
+{
+    struct display *display = data;
+    struct surface_name     *p;
+    struct surface_name     *fp;
+
+    display->surface_created = 1;
+    p = display->surface_name;
+    fp = NULL;
+    while (p)   {
+        if (p->surfaceid == (int)surfaceid) break;
+        fp = p;
+        p = p->next;
+    }
+    if (p)  {
+        print_log("HOMESCREEN: Event[window_created] surface=%08x(app=%s) exist",
+                  (int)surfaceid, appid);
+    }
+    else    {
+        print_log("HOMESCREEN: Event[window_created] new surface=%08x(app=%s)",
+                  (int)surfaceid, appid);
+        p = malloc(sizeof(struct surface_name));
+        if (! p)    {
+            return;
+        }
+        memset(p, 0, sizeof(struct surface_name));
+        if (fp) {
+            fp->next = p;
+        }
+        else    {
+            display->surface_name = p;
+        }
+    }
+    p->surfaceid = surfaceid;
+    p->pid = pid;
+    strncpy(p->appid, appid, MAX_APPID-1);
+
+    /* Set default size and show        */
+    if (p->width > 0)   {
+        ico_window_mgr_set_positionsize(display->ico_window_mgr, surfaceid,
+                                    p->x, p->y, p->width, p->height);
+    }
+
+    print_log("HOMESCREEN: Created window[%08x] (app=%s)", (int)surfaceid, appid);
+
+    if (strncasecmp(appid, "test-homescreen", 15) == 0) {
+        display->bgsurface_name = p;
+        if (display->bg_created == 1)   {
+            display->bg_created = 9;
+            ico_window_mgr_set_positionsize(display->ico_window_mgr, surfaceid,
+                                            0, 0, display->init_width, display->init_height);
+        }
+        ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, 1, 0);
+        print_log("HOMESCREEN: Created window[%08x] (app=%s) Visible",
+                  (int)surfaceid, appid);
+        p->visible = 1;
+    }
+}
+
+static void
+window_destroyed(void *data, struct ico_window_mgr *ico_window_mgr, uint32_t surfaceid)
+{
+    struct display *display = data;
+    struct surface_name     *p;
+    struct surface_name     *fp;
+
+    display->surface_destroyed = 1;
+    p = search_surfaceid(display, (int)surfaceid);
+    if (! p)    {
+        print_log("HOMESCREEN: Event[window_destroyed] surface=%08x dose not exist",
+                  (int)surfaceid);
+    }
+    else    {
+        print_log("HOMESCREEN: Event[window_destroyed] surface=%08x", (int)surfaceid);
+        if (p == display->surface_name) {
+            display->surface_name = p->next;
+        }
+        else    {
+            fp = display->surface_name;
+            while (fp)  {
+                if (fp->next == p)  {
+                    fp->next = p->next;
+                    break;
+                }
+                fp = fp->next;
+            }
+        }
+        free(p);
+    }
+}
+
+static void
+window_visible(void *data, struct ico_window_mgr *ico_window_mgr,
+               uint32_t surfaceid, int32_t visible, int32_t raise, int32_t hint)
+{
+    struct display *display = data;
+    struct surface_name     *p;
+
+    p = search_surfaceid(display, (int)surfaceid);
+    if (! p)    {
+        print_log("HOMESCREEN: Event[window_visible] surface=%08x dose not exist",
+                  (int)surfaceid);
+    }
+    else    {
+        print_log("HOMESCREEN: Event[window_visible] surface=%08x "
+                  "visible=%d raise=%d hint=%d",
+                  (int)surfaceid, visible, raise, hint);
+        p->visible = visible;
+        if (hint == 0)  {
+            ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, visible, 9);
+        }
+    }
+}
+
+static void
+window_configure(void *data, struct ico_window_mgr *ico_window_mgr,
+                 uint32_t surfaceid, const char *appid, int32_t layer,
+                 int32_t x, int32_t y, int32_t width, int32_t height, int32_t hint)
+{
+    struct display *display = data;
+    struct surface_name     *p;
+
+    print_log("HOMESCREEN: Event[window_configure] surface=%08x "
+              "app=%s x/y=%d/%d w/h=%d/%d hint=%d",
+              (int)surfaceid, appid, x, y, width, height, hint);
+
+    p = search_surfaceid(display, (int)surfaceid);
+    if (! p)    {
+        print_log("HOMESCREEN: Event[window_configure] surface=%08x(app=%s) new create",
+                  (int)surfaceid, appid);
+        window_created(data, ico_window_mgr, surfaceid, 0, appid);
+        p = search_surfaceid(display, (int)surfaceid);
+        if (! p)    {
+            print_log("HOMESCREEN: Event[window_configure] can not make table");
+            return;
+        }
+    }
+}
+
+static void
+window_active(void *data, struct ico_window_mgr *ico_window_mgr,
+              uint32_t surfaceid, const uint32_t active)
+{
+    print_log("HOMESCREEN: Event[window_active] surface=%08x acive=%d",
+              (int)surfaceid, (int)active);
+}
+
+static const struct ico_window_mgr_listener window_mgr_listener = {
+    window_created,
+    window_destroyed,
+    window_visible,
+    window_configure,
+    window_active
+};
+
+static void
+cb_input_capabilities(void *data, struct ico_exinput *ico_exinput,
+                      const char *device, int32_t type, const char *swname, int32_t input,
+                      const char *codename, int32_t code)
+{
+    print_log("HOMESCREEN: Event[input_capabilities] device=%s type=%d sw=%s input=%d "
+              "code=%s[%d]", device, type, swname, input, codename, code);
+}
+
+static void
+cb_input_code(void *data, struct ico_exinput *ico_exinput,
+              const char *device, int32_t input, const char *codename, int32_t code)
+{
+    print_log("HOMESCREEN: Event[input_code] device=%s input=%d code=%s[%d]",
+              device, input, codename, code);
+}
+
+static void
+cb_input_input(void *data, struct ico_exinput *ico_exinput, uint32_t time,
+               const char *device, int32_t input, int32_t code, int32_t state)
+{
+    print_log("HOMESCREEN: Event[input_input] device=%s input=%d code=%d state=%d",
+              device, input, code, state);
+}
+
+static const struct ico_exinput_listener exinput_listener = {
+    cb_input_capabilities,
+    cb_input_code,
+    cb_input_input
+};
+
+static void
+handle_global(void *data, struct wl_registry *registry, uint32_t id,
+              const char *interface, uint32_t version)
+{
+    struct display *display = data;
+    struct input *input;
+    struct output *output;
+
+    print_log("HOMESCREEN: handle_global: interface=<%s> id=%d", interface, (int)id);
+
+    if (strcmp(interface, "wl_compositor") == 0) {
+        display->compositor =
+            wl_registry_bind(display->registry,
+                     id, &wl_compositor_interface, 1);
+    }
+    else if (strcmp(interface, "wl_seat") == 0) {
+        input = calloc(1, sizeof *input);
+        input->display = display;
+        input->seat = wl_registry_bind(display->registry, id,
+                           &wl_seat_interface, 1);
+        input->pointer_focus = NULL;
+        input->keyboard_focus = NULL;
+
+        wl_seat_add_listener(input->seat, &seat_listener, input);
+        display->input = input;
+    }
+    else if (strcmp(interface, "wl_output") == 0) {
+        output = malloc(sizeof *output);
+        output->display = display;
+        output->output = wl_registry_bind(display->registry,
+                          id, &wl_output_interface, 1);
+        wl_output_add_listener(output->output,
+                       &output_listener, output);
+        display->output = output;
+
+        print_log("HOMESCREEN: created output global %p", display->output);
+    }
+    else if (strcmp(interface, "wl_shell") == 0)    {
+        display->shell =
+            wl_registry_bind(display->registry,
+                     id, &wl_shell_interface, 1);
+    }
+    else if (strcmp(interface, "ico_ivi_shell") == 0)   {
+        display->ico_ivi_shell =
+            wl_registry_bind(display->registry,
+                     id, &ico_ivi_shell_interface, 1);
+    }
+    else if (strcmp(interface, "ico_window_mgr") == 0)  {
+        display->ico_window_mgr =
+            wl_registry_bind(display->registry,
+                     id, &ico_window_mgr_interface, 1);
+        ico_window_mgr_add_listener(display->ico_window_mgr,
+                                    &window_mgr_listener, display);
+        print_log("HOMESCREEN: created window_mgr global %p", display->ico_window_mgr);
+
+        ico_window_mgr_set_eventcb(display->ico_window_mgr, 1);
+    }
+    else if (strcmp(interface, "ico_input_mgr_control") == 0)   {
+        display->ico_input_mgr =
+            wl_registry_bind(display->registry,
+                             id, &ico_input_mgr_control_interface, 1);
+        print_log("HOMESCREEN: created input_mgr global %p", display->ico_input_mgr);
+    }
+    else if (strcmp(interface, "ico_input_mgr_device") == 0)   {
+        display->ico_input_device =
+            wl_registry_bind(display->registry,
+                             id, &ico_input_mgr_device_interface, 1);
+        print_log("HOMESCREEN: created input_device global %p", display->ico_input_device);
+    }
+    else if (strcmp(interface, "ico_exinput") == 0)   {
+        display->ico_exinput =
+            wl_registry_bind(display->registry,
+                             id, &ico_exinput_interface, 1);
+        ico_exinput_add_listener(display->ico_exinput,
+                                 &exinput_listener, display);
+        print_log("HOMESCREEN: created exinput global %p", display->ico_exinput);
+
+        ico_window_mgr_set_eventcb(display->ico_window_mgr, 1);
+
+        display->bg_created = 1;
+        create_surface(display);
+    }
+}
+
+static const struct wl_registry_listener registry_listener = {
+    handle_global
+};
+
+static char *
+skip_spaces(char *buf)
+{
+    while ((*buf == ' ') || (*buf == '\t')) {
+        buf++;
+    }
+    return(buf);
+}
+
+static int
+pars_command(char *buf, char *pt[], const int len)
+{
+    char    *p;
+    int     narg;
+
+    memset(pt, 0, sizeof(int *)*10);
+    p = buf;
+    for (narg = 0; narg < len; narg++)  {
+        p = skip_spaces(p);
+        if (*p == 0)    break;
+        pt[narg] = p;
+        for (; *p; p++) {
+            if ((*p == ' ') || (*p == '\t') ||
+                (*p == '=') || (*p == ',')) break;
+        }
+        if (*p == 0)    {
+            narg++;
+            break;
+        }
+        *p = 0;
+        p++;
+    }
+    return (narg);
+}
+
+static void
+launch_app(struct display *display, char *buf)
+{
+    char    sbuf[256];
+
+    display->surface_created = 0;
+    display->surface_destroyed = 0;
+    snprintf(sbuf, sizeof(sbuf)-1, "%s &", skip_spaces(buf));
+    if (system(sbuf) < 0)   {
+        print_log("HOMESCREEN: Can not launch application[%s]", sbuf);
+    }
+    else    {
+        sleep_with_wayland(display->display, 500);
+    }
+}
+
+static void
+kill_app(struct display *display, char *buf)
+{
+    char    *args[10];
+    int     narg;
+    struct surface_name     *p;
+    struct surface_name     *fp;
+
+    narg = pars_command(buf, args, 10);
+    if (narg >= 1)  {
+        p = search_surfacename(display, args[0]);
+        if (kill(p->pid, SIGINT) < 0)   {
+            print_log("HOMESCREEN: kill[%s.%d] Application dose not exist",
+                      p->appid, p->pid);
+        }
+        else    {
+            sleep_with_wayland(display->display, 300);
+            p = search_surfacename(display, args[0]);
+            if ((p != NULL) && (kill(p->pid, SIGTERM) >= 0))    {
+                sleep_with_wayland(display->display, 200);
+                p = search_surfacename(display, args[0]);
+                if (p)  {
+                    kill(p->pid, SIGKILL);
+                    sleep_with_wayland(display->display, 200);
+                }
+            }
+        }
+        p = search_surfacename(display, args[0]);
+        if (p)  {
+            if (p == display->surface_name) {
+                display->surface_name = p->next;
+            }
+            else    {
+                fp = display->surface_name;
+                while (fp)  {
+                    if (fp->next == p)  {
+                        fp->next = p->next;
+                        break;
+                    }
+                }
+            }
+            free(p);
+        }
+    }
+    else    {
+        print_log("HOMESCREEN: kill command[kill appid] has no argument");
+    }
+}
+
+static void
+layer_surface(struct display *display, char *buf)
+{
+    char    *args[10];
+    int     narg;
+    int     surfaceid;
+    int     layerid;
+
+    narg = pars_command(buf, args, 10);
+    if (narg >= 2)  {
+        surfaceid = search_surface(display, args[0]);
+        layerid = strtol(args[1], (char **)0, 0);
+        if ((surfaceid >= 0) && (layerid >= 0)) {
+            print_log("HOMESCREEN: set_window_layer(%s,%08x)",
+                      args[0], surfaceid, layerid);
+            ico_window_mgr_set_window_layer(display->ico_window_mgr, surfaceid, layerid);
+        }
+        else    {
+            print_log("HOMESCREEN: Unknown surface(%s) at layer command", args[0]);
+        }
+    }
+    else    {
+        print_log("HOMESCREEN: layer command[layer appid layerid] has no argument");
+    }
+}
+
+static void
+positionsize_surface(struct display *display, char *buf)
+{
+    char    *args[10];
+    int     narg;
+    int     surfaceid;
+    int     x, y, width, height;
+
+    narg = pars_command(buf, args, 10);
+    if (narg >= 5)  {
+        surfaceid = search_surface(display, args[0]);
+        x = strtol(args[1], (char **)0, 0);
+        y = strtol(args[2], (char **)0, 0);
+        width = strtol(args[3], (char **)0, 0);
+        height = strtol(args[4], (char **)0, 0);
+        if ((surfaceid >= 0) && (x >= 0) && (y >=0) && (width >= 0) && (height >=0))    {
+            print_log("HOMESCREEN: set_positionsize(%s,%08x,%d,%d,%d,%d)",
+                args[0], surfaceid, x, y, width, height);
+            ico_window_mgr_set_positionsize(display->ico_window_mgr, surfaceid,
+                                            x, y, width, height);
+        }
+        else    {
+            print_log("HOMESCREEN: Unknown surface(%s) at positionsize command",
+                      args[0]);
+        }
+    }
+    else    {
+        print_log("HOMESCREEN: positionsize command"
+                  "[positionsize appid x y width heigh] has no argument");
+    }
+}
+
+static void
+move_surface(struct display *display, char *buf)
+{
+    char    *args[10];
+    int     narg;
+    int     surfaceid;
+    int     x, y;
+
+    narg = pars_command(buf, args, 10);
+    if (narg >= 3)  {
+        surfaceid = search_surface(display, args[0]);
+        x = strtol(args[1], (char **)0, 0);
+        y = strtol(args[2], (char **)0, 0);
+        if ((surfaceid >= 0) && (x >= 0) && (y >=0))    {
+            print_log("HOMESCREEN: move(%s,%08x,%d,%d)", args[0], surfaceid, x, y);
+            ico_window_mgr_set_positionsize(display->ico_window_mgr, surfaceid,
+                                            x, y,
+                                            ICO_IVI_MAX_COORDINATE+1, ICO_IVI_MAX_COORDINATE+1);
+        }
+        else    {
+            print_log("HOMESCREEN: Unknown surface(%s) at move command", args[0]);
+        }
+    }
+    else    {
+        print_log("HOMESCREEN: move command[positionsize appid x y] has no argument");
+    }
+}
+
+static void
+resize_surface(struct display *display, char *buf)
+{
+    char    *args[10];
+    int     narg;
+    int     surfaceid;
+    int     width, height;
+
+    narg = pars_command(buf, args, 10);
+    if (narg >= 3)  {
+        surfaceid = search_surface(display, args[0]);
+        width = strtol(args[1], (char **)0, 0);
+        height = strtol(args[2], (char **)0, 0);
+        if ((surfaceid >= 0) && (width >= 0) && (height >=0))   {
+            print_log("HOMESCREEN: resize(%s,%08x,%d,%d)", args[0], surfaceid, width, height);
+            ico_window_mgr_set_positionsize(display->ico_window_mgr, surfaceid,
+                                            ICO_IVI_MAX_COORDINATE+1, ICO_IVI_MAX_COORDINATE+1,
+                                            width, height);
+        }
+        else    {
+            print_log("HOMESCREEN: Unknown surface(%s) at resize command", args[0]);
+        }
+    }
+    else    {
+        print_log("HOMESCREEN: positionsize command"
+                  "[resize appid width heigh] has no argument");
+    }
+}
+
+static void
+visible_surface(struct display *display, char *buf)
+{
+    char    *args[10];
+    int     narg;
+    int     surfaceid;
+    int     visible;
+    int     raise;
+
+    narg = pars_command(buf, args, 10);
+    if (narg >= 3)  {
+        surfaceid = search_surface(display, args[0]);
+        visible = strtol(args[1], (char **)0, 0);
+        raise = strtol(args[2], (char **)0, 0);
+        if ((surfaceid >= 0) && (visible >= 0) && (raise >=0))  {
+            print_log("HOMESCREEN: visible(%s,%08x,%d,%d)",
+                      args[0], surfaceid, visible, raise);
+            ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid,
+                                       visible, raise);
+        }
+        else    {
+            print_log("HOMESCREEN: Unknown surface(%s) at visible command", args[0]);
+        }
+    }
+    else    {
+        print_log("HOMESCREEN: visible command[visible appid visible raise] has no argument");
+    }
+}
+
+static void
+show_surface(struct display *display, char *buf, const int show)
+{
+    char    *args[10];
+    int     narg;
+    int     surfaceid;
+
+    narg = pars_command(buf, args, 10);
+    if (narg >= 1)  {
+        surfaceid = search_surface(display, args[0]);
+        if (surfaceid >= 0) {
+            if (show)   {
+                print_log("HOMESCREEN: show(%s,%08x)", args[0], surfaceid);
+                ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, 1, 9);
+            }
+            else    {
+                print_log("HOMESCREEN: hide(%s,%08x)", args[0], surfaceid);
+                ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, 0, 9);
+            }
+        }
+        else    {
+            print_log("HOMESCREEN: Unknown surface(%s) at show/hide command", args[0]);
+        }
+    }
+    else    {
+        print_log("HOMESCREEN: show command[show/hide appid] has no argument");
+    }
+}
+
+static void
+raise_surface(struct display *display, char *buf, const int raise)
+{
+    char    *args[10];
+    int     narg;
+    int     surfaceid;
+
+    narg = pars_command(buf, args, 10);
+    if (narg >= 1)  {
+        surfaceid = search_surface(display, args[0]);
+        if (surfaceid >= 0) {
+            if (raise)  {
+                print_log("HOMESCREEN: raise(%s,%08x)", args[0], surfaceid);
+                ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, 9, 1);
+            }
+            else    {
+                print_log("HOMESCREEN: lower(%s,%08x)", args[0], surfaceid);
+                ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, 9, 0);
+            }
+        }
+        else    {
+            print_log("HOMESCREEN: Unknown surface(%s) at raise/lower command", args[0]);
+        }
+    }
+    else    {
+        print_log("HOMESCREEN: show command[raise/lower appid] has no argument");
+    }
+}
+
+static void
+transition_surface(struct display *display, char *buf)
+{
+    char    *args[10];
+    int     narg;
+    int     surfaceid;
+    int     transition;
+
+    narg = pars_command(buf, args, 10);
+    if (narg >= 2)  {
+        surfaceid = search_surface(display, args[0]);
+        transition = strtol(args[1], (char **)0, 0);
+        if ((surfaceid >= 0) && (transition >=0))   {
+            print_log("HOMESCREEN: transition(%s,%08x,%d)", args[0], surfaceid, transition);
+            ico_window_mgr_set_transition(display->ico_window_mgr, surfaceid, transition);
+        }
+        else    {
+            print_log("HOMESCREEN: Unknown surface(%s) at transition command", args[0]);
+        }
+    }
+    else    {
+        print_log("HOMESCREEN: transition command"
+                  "[transition appid transition] has no argument");
+    }
+}
+
+static void
+visible_layer(struct display *display, char *buf)
+{
+    char    *args[10];
+    int     narg;
+    int     layer;
+    int     visible;
+
+    narg = pars_command(buf, args, 10);
+    if (narg >= 2)  {
+        layer = strtol(args[0], (char **)0, 0);
+        visible = strtol(args[1], (char **)0, 0);
+        ico_window_mgr_set_layer_visible(display->ico_window_mgr, layer, visible);
+    }
+    else    {
+        print_log("HOMESCREEN: layer_visible command"
+                  "[layer_visible layer visible] has no argument");
+    }
+}
+
+static void
+input_add(struct display *display, char *buf)
+{
+    char    *args[10];
+    int     narg;
+    int     input;
+    int     fix;
+
+    narg = pars_command(buf, args, 10);
+    if (narg >= 3)  {
+        input = strtol(args[1], (char **)0, 0);
+        if (narg >= 4)  {
+            fix = strtol(args[3], (char **)0, 0);
+        }
+        else    {
+            fix = 0;
+        }
+        if ((input >= 0) && (fix >=0))  {
+            print_log("HOMESCREEN: input_add(%s.%d to %s[%d])", args[0], input, args[2], fix);
+            ico_input_mgr_control_add_input_app(display->ico_input_mgr,
+                                                args[2], args[0], input, fix);
+        }
+        else    {
+            print_log("HOMESCREEN: Unknown input(%s) at input_add command", args[1]);
+        }
+    }
+    else    {
+        print_log("HOMESCREEN: input_add command[input_add device inputId appid fix] "
+                  "has no argument");
+    }
+}
+
+static void
+input_del(struct display *display, char *buf)
+{
+    char    *args[10];
+    int     narg;
+    int     input;
+    char    wk1[32], wk2[32];
+
+    narg = pars_command(buf, args, 10);
+    if (narg >= 3)  {
+        input = strtol(args[1], (char **)0, 0);
+        if (args[0][0] == '@')  {
+            wk1[0] = 0;
+            args[0] = wk1;
+        }
+        if (args[2][0] == '@')  {
+            wk2[0] = 0;
+            args[2] = wk2;
+        }
+        print_log("HOMESCREEN: input_del(%s.%d to %s)", args[0], input, args[2]);
+        ico_input_mgr_control_del_input_app(display->ico_input_mgr,
+                                            args[2], args[0], input);
+    }
+    else    {
+        print_log("HOMESCREEN: input_del command[input_del device inputId appid] "
+                  "has no argument");
+    }
+}
+
+static void
+input_conf(struct display *display, char *buf)
+{
+    char    *args[10];
+    int     narg;
+    int     type;
+    int     input;
+    int     code;
+    char    wk1[32], wk2[32];
+
+    narg = pars_command(buf, args, 10);
+    if (narg >= 4)  {
+        type = strtol(args[1], (char **)0, 0);
+        input = strtol(args[3], (char **)0, 0);
+        if (narg >= 6)  {
+            code = strtol(args[5], (char **)0, 0);
+        }
+        else    {
+            code = 0;
+            args[4] = wk1;
+            strcpy(wk1, args[2]);
+            args[5] = wk2;
+            strcpy(wk2, "0");
+        }
+        if ((type >= 0) && (input >= 0) && (code >=0))  {
+            ico_input_mgr_device_configure_input(display->ico_input_device, args[0], type,
+                                                 args[2], input, args[4], code);
+        }
+        else    {
+            print_log("HOMESCREEN: Unknown type(%s),input(%s) or code(%s) "
+                      "at input_conf command", args[1], args[3], args[5]);
+        }
+    }
+    else    {
+        print_log("HOMESCREEN: input_conf command[input_conf device type swname input "
+                  "codename code] has no argument");
+    }
+}
+
+static void
+input_code(struct display *display, char *buf)
+{
+    char    *args[10];
+    int     narg;
+    int     input;
+    int     code;
+
+    narg = pars_command(buf, args, 10);
+    if (narg >= 4)  {
+        input = strtol(args[1], (char **)0, 0);
+        code = strtol(args[3], (char **)0, 0);
+        if ((input >= 0) && (code >= 0))    {
+            ico_input_mgr_device_configure_code(display->ico_input_device, args[0], input,
+                                                args[2], code);
+        }
+        else    {
+            print_log("HOMESCREEN: Unknown input(%s) or code(%s) "
+                      "at input_code command", args[1], args[3]);
+        }
+    }
+    else    {
+        print_log("HOMESCREEN: input_conf command[input_code device input codename code] "
+                  "has no argument");
+    }
+}
+
+static void
+input_sw(struct display *display, char *buf)
+{
+    char    *args[10];
+    int     narg;
+    int     timems;
+    int     input;
+    int     code;
+    int     state;
+    struct timeval  stv;
+
+    narg = pars_command(buf, args, 10);
+    if (narg >= 4)  {
+        input = strtol(args[1], (char **)0, 0);
+        code = strtol(args[2], (char **)0, 0);
+        state = strtol(args[3], (char **)0, 0);
+        if ((input >= 0) && (state >= 0))   {
+            gettimeofday(&stv, (struct timezone *)NULL);
+            timems = (stv.tv_sec % 1000) * 1000 + (stv.tv_usec / 1000);
+            ico_input_mgr_device_input_event(display->ico_input_device,
+                                             timems, args[0], input, code, state);
+        }
+        else    {
+            print_log("HOMESCREEN: Unknown input(%s),code(%s) or state(%s) "
+                      "at input_sw command", args[1], args[2], args[3]);
+        }
+    }
+    else    {
+        print_log("HOMESCREEN: input_sw command[input_sw device input code, state] "
+                  "has no argument");
+    }
+}
+
+static void
+send_event(const char *cmd)
+{
+    static int  nmqinfo = 0;
+    static struct   {
+        int     mqkey;
+        int     mqid;
+    }           mqinfo[10];
+    int     mqkey;
+    int     mqid;
+    struct {
+        long    mtype;
+        char    buf[240];
+    }       mqbuf;
+    int     pt, i;
+
+    if (cmd == NULL)    {
+        return;
+    }
+    mqkey = 0;
+    for (pt = 0; cmd[pt]; pt++) {
+        if ((cmd[pt] >= '0') && (cmd[pt] <= '9'))   {
+            mqkey = mqkey * 10 + cmd[pt] - '0';
+        }
+        else    {
+            break;
+        }
+    }
+    for (; cmd[pt] == ' '; pt++)    ;
+
+    if (mqkey <= 0) {
+        mqkey = 5551;
+        pt = 0;
+    }
+    for (i = 0; i < nmqinfo; i++)   {
+        if (mqinfo[i].mqkey == mqkey)   {
+            mqid = mqinfo[i].mqid;
+            break;
+        }
+    }
+    if (i >= nmqinfo)   {
+        if (nmqinfo >= 10)  {
+            fprintf(stderr, "HOMESCREEN: message queue(%d) overflow\n", mqkey);
+            return;
+        }
+        mqid = msgget(mqkey, 0);
+        if (mqid < 0)   {
+            fprintf(stderr, "HOMESCREEN: message queue(%d(0x%x)) get error[%d]\n",
+                    mqkey, mqkey, errno);
+            return;
+        }
+        mqinfo[nmqinfo].mqkey = mqkey;
+        mqinfo[nmqinfo].mqid = mqid;
+        nmqinfo ++;
+    }
+
+    memset(&mqbuf, 0, sizeof(mqbuf));
+    mqbuf.mtype = 1;
+    strncpy(mqbuf.buf, &cmd[pt], sizeof(mqbuf)-sizeof(long));
+
+    if (msgsnd(mqid, &mqbuf, sizeof(mqbuf)-sizeof(long), 0) < 0)    {
+        fprintf(stderr, "HOMESCREEN: message queue(%d(0x%x)) send error[%d]\n",
+                        mqkey, mqkey, errno);
+        return;
+    }
+}
+
+/*
+ * Main Program
+ *
+ *   usage:
+ *     test-homescreen < test-case-data-file > test-result-output
+ */
+int main(int argc, char *argv[])
+{
+    struct display *display;
+    char buf[256];
+    int ret, fd;
+    int msec;
+
+    display = malloc(sizeof *display);
+    assert(display);
+    memset((char *)display, 0, sizeof *display);
+
+    display->init_width = 640;
+    display->init_height = 480;
+    display->init_color = 0xFF304010;
+
+    for (fd = 1; fd < argc; fd++)   {
+        if (argv[fd][0] == '-') {
+            if (strncasecmp(argv[fd], "-visible=", 9) == 0) {
+                display->visible_on_create = argv[fd][9] & 1;
+            }
+            else if (strncasecmp(argv[fd], "-display=", 9) == 0)    {
+                strncpy(display->connect, &argv[fd][9], MAX_CON_NAME);
+            }
+            else if (strncasecmp(argv[fd], "-prompt=", 8) == 0) {
+                display->prompt = argv[fd][8] & 1;
+            }
+        }
+    }
+
+    if (display->connect[0])    {
+        display->display = wl_display_connect(display->connect);
+    }
+    else    {
+        display->display = wl_display_connect(NULL);
+    }
+    assert(display->display);
+
+    display->registry = wl_display_get_registry(display->display);
+    wl_registry_add_listener(display->registry,
+                 &registry_listener, display);
+    wl_display_dispatch(display->display);
+
+    fd = 0;
+
+    while (1) {
+        sleep_with_wayland(display->display, 20);
+        if (display->prompt)    {
+            printf("HOMESCREEN: "); fflush(stdout);
+        }
+        ret = getdata(display->ico_window_mgr, "HOMESCREEN: ", fd, buf, sizeof(buf));
+        if (ret < 0) {
+            fprintf(stderr, "HOMESCREEN: read error: fd %d, %m\n",
+                fd);
+            return -1;
+        }
+        if (ret == 0)   continue;
+        wl_display_flush(display->display);
+
+        if ((strncasecmp(buf, "bye", 3) == 0) ||
+            (strncasecmp(buf, "quit", 4) == 0) ||
+            (strncasecmp(buf, "end", 3) == 0))  {
+            /* Exit, end of test            */
+            return 0;
+        }
+        else if (strncasecmp(buf, "launch", 6) == 0) {
+            /* Launch test application      */
+            launch_app(display, &buf[6]);
+        }
+        else if (strncasecmp(buf, "kill", 4) == 0) {
+            /* Launch test application      */
+            kill_app(display, &buf[4]);
+        }
+        else if (strncasecmp(buf, "layer_visible", 13) == 0) {
+            /* Change layer visiblety       */
+            visible_layer(display, &buf[13]);
+        }
+        else if (strncasecmp(buf, "layer", 5) == 0) {
+            /* layer change surface window  */
+            layer_surface(display, &buf[5]);
+        }
+        else if (strncasecmp(buf, "positionsize", 12) == 0) {
+            /* Move and Ressize surface window*/
+            positionsize_surface(display, &buf[12]);
+        }
+        else if (strncasecmp(buf, "move", 4) == 0) {
+            /* Move surface window          */
+            move_surface(display, &buf[4]);
+        }
+        else if (strncasecmp(buf, "resize", 6) == 0) {
+            /* Resize surface window        */
+            resize_surface(display, &buf[6]);
+        }
+        else if (strncasecmp(buf, "visible", 7) == 0) {
+            /* Visible and Raise surface window*/
+            visible_surface(display, &buf[7]);
+        }
+        else if (strncasecmp(buf, "show", 4) == 0) {
+            /* Show/Hide surface window     */
+            show_surface(display, &buf[4], 1);
+        }
+        else if (strncasecmp(buf, "hide", 4) == 0) {
+            /* Show/Hide surface window     */
+            show_surface(display, &buf[4], 0);
+        }
+        else if (strncasecmp(buf, "raise", 5) == 0) {
+            /* Raise/Lower surface window   */
+            raise_surface(display, &buf[5], 1);
+        }
+        else if (strncasecmp(buf, "lower", 5) == 0) {
+            /* Raise/Lower surface window   */
+            raise_surface(display, &buf[5], 0);
+        }
+        else if (strncasecmp(buf, "transition", 10) == 0) {
+            /* Set transition surface window*/
+            transition_surface(display, &buf[10]);
+        }
+        else if (strncasecmp(buf, "input_add", 9) == 0) {
+            /* Set input switch to application */
+            input_add(display, &buf[9]);
+        }
+        else if (strncasecmp(buf, "input_del", 9) == 0) {
+            /* Reset input switch to application*/
+            input_del(display, &buf[9]);
+        }
+        else if (strncasecmp(buf, "input_conf", 10) == 0) {
+            /* input switch configuration       */
+            input_conf(display, &buf[10]);
+        }
+        else if (strncasecmp(buf, "input_code", 10) == 0) {
+            /* input code configuration         */
+            input_code(display, &buf[10]);
+        }
+        else if (strncasecmp(buf, "input_sw", 8) == 0) {
+            /* input switch event               */
+            input_sw(display, &buf[8]);
+        }
+        else if (strncasecmp(buf, "sleep", 5) == 0) {
+            /* Sleep                            */
+            msec = sec_str_2_value(&buf[6]);
+            sleep_with_wayland(display->display, msec);
+        }
+        else if (strncasecmp(buf, "waitcreate", 10) == 0) {
+            /* Wait surface create              */
+            msec = sec_str_2_value(&buf[11]);
+            wait_with_wayland(display->display, msec, &display->surface_created);
+        }
+        else if (strncasecmp(buf, "waitdestroy", 11) == 0) {
+            /* Wait surface destrpy             */
+            msec = sec_str_2_value(&buf[12]);
+            wait_with_wayland(display->display, msec, &display->surface_destroyed);
+        }
+        else if (strncasecmp(buf, "event", 5) == 0) {
+            /* Send touch panel event to Weston */
+            send_event(&buf[6]);
+        }
+        else {
+            print_log("HOMESCREEN: unknown command[%s]", buf);
+            return -1;
+        }
+    }
+
+    print_log("HOMESCREEN: end");
+
+    send_event(NULL);
+
+    return(0);
+}
+
diff --git a/tests/test-send_event.c b/tests/test-send_event.c
new file mode 100644 (file)
index 0000000..9165aa3
--- /dev/null
@@ -0,0 +1,514 @@
+/*
+ * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
+ *
+ * This program is licensed under the terms and conditions of the
+ * Apache License, version 2.0.  The full text of the Apache License is at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ */
+/**
+ * @brief   System Test Tool for send device input event
+ *
+ * @date    Feb-20-2013
+ */
+
+#include    <stdio.h>
+#include    <stdlib.h>
+#include    <unistd.h>
+#include    <string.h>
+#include    <errno.h>
+#include    <pthread.h>
+#include    <sys/ioctl.h>
+#include    <sys/ipc.h>
+#include    <sys/msg.h>
+#include    <sys/time.h>
+#include    <sys/types.h>
+#include    <sys/stat.h>
+#include    <signal.h>
+#include    <fcntl.h>
+#include    <linux/input.h>
+#include    <linux/uinput.h>
+#include    <linux/joystick.h>
+#include    "test-common.h"
+
+#define DEV_TOUCH   0
+#define DEV_JS      1
+#define SPECIALTYPE_XY  9991
+
+static const struct {
+    char    *prop;
+    short   devtype;
+    short   type;
+    short   code;
+    short   value;
+}               event_key[] = {
+    { "X", DEV_TOUCH, EV_ABS, ABS_X, -1 },
+    { "Y", DEV_TOUCH, EV_ABS, ABS_Y, -1 },
+    { "Down", DEV_TOUCH, EV_KEY, BTN_TOUCH, 1 },
+    { "Up", DEV_TOUCH, EV_KEY, BTN_TOUCH, 0 },
+    { "Touch", DEV_TOUCH, EV_KEY, BTN_TOUCH, -1 },
+    { "XY", DEV_TOUCH, SPECIALTYPE_XY, 0, -1 },
+    { "SYN", DEV_TOUCH, 0, 0, 0 },
+    { "Button", DEV_TOUCH, EV_KEY, BTN_LEFT, -1 },
+    { "ButtonOn", DEV_TOUCH, EV_KEY, BTN_LEFT, 1 },
+    { "ButtonOff", DEV_TOUCH, EV_KEY, BTN_LEFT, 0 },
+
+    { "UpDown", DEV_JS, 2, 3, 1 },
+    { "UD", DEV_JS, 2, 3, 1 },
+    { "LeftRight", DEV_JS, 2, 2, 2 },
+    { "LR", DEV_JS, 2, 2, 2 },
+    { "Cross", DEV_JS, 1, 0, 3 },
+    { "Squere", DEV_JS, 1, 1, 4 },
+    { "Circle", DEV_JS, 1, 2, 5 },
+    { "Triangle", DEV_JS, 1, 3, 6 },
+    { "\0", 0, 0, 0, 0 } };
+
+static int  uifd = -1;
+static int  mqid = -1;
+static int  mDebug = 0;
+static int  mRun = 1;
+static int  mTouch = 1;
+
+static void
+term_signal(const int signo)
+{
+    mRun = 0;
+}
+
+static void
+init_mq(const int mqkey)
+{
+    char    dummy[256];
+
+    if (mqkey == 0) {
+        mqid = -1;
+    }
+    else    {
+        mqid = msgget(mqkey, 0);
+        if (mqid < 0)   {
+            mqid = msgget(mqkey, IPC_CREAT);
+        }
+        if (mqid < 0)   {
+            print_log("Can not create message queue(%d(0x%x))[%d]",
+                      mqkey, mqkey, errno);
+            fflush(stderr);
+            return;
+        }
+        while (msgrcv(mqid, dummy, sizeof(dummy)-sizeof(long), 0, IPC_NOWAIT) > 0)  ;
+    }
+}
+
+static void
+init_device(const char *device)
+{
+    int     fd;
+    int     ii;
+    char    devFile[64];
+    char    devName[64];
+    struct uinput_user_dev  uinputDevice;
+    uifd = open("/dev/uinput", O_RDWR);
+
+    if (uifd < 0)   {
+        print_log("/dev/uinput open error[%d]", errno);
+        fflush(stderr);
+        exit(1);
+    }
+
+    memset(&uinputDevice, 0, sizeof(uinputDevice));
+    strcpy(uinputDevice.name, device);
+    uinputDevice.absmax[ABS_X] = 1920;
+    uinputDevice.absmax[ABS_Y] = 1080;
+
+    /* uinput device configuration  */
+    if (write(uifd, &uinputDevice, sizeof(uinputDevice)) < (int)sizeof(uinputDevice)) {
+        print_log("/dev/uinput regist error[%d]", errno);
+        fflush(stderr);
+        close(uifd);
+        exit(1);
+    }
+
+    /* uinput set event bits        */
+    ioctl(uifd, UI_SET_EVBIT, EV_SYN);
+
+    if ((mTouch != 0) && (mTouch != 3)) {
+        ioctl(uifd, UI_SET_EVBIT, EV_ABS);
+        ioctl(uifd, UI_SET_ABSBIT, ABS_X);
+        ioctl(uifd, UI_SET_ABSBIT, ABS_Y);
+        ioctl(uifd, UI_SET_EVBIT, EV_KEY);
+        if (mTouch == 1)    {
+            ioctl(uifd, UI_SET_KEYBIT, BTN_LEFT);
+        }
+        else    {
+            ioctl(uifd, UI_SET_KEYBIT, BTN_TOUCH);
+            ioctl(uifd, UI_SET_KEYBIT, BTN_TOOL_PEN);
+        }
+    }
+    else    {
+        ioctl(uifd, UI_SET_EVBIT, EV_REL);
+        ioctl(uifd, UI_SET_RELBIT, REL_X);
+        ioctl(uifd, UI_SET_RELBIT, REL_Y);
+        ioctl(uifd, UI_SET_RELBIT, REL_Z);
+        ioctl(uifd, UI_SET_RELBIT, REL_RX);
+        ioctl(uifd, UI_SET_RELBIT, REL_RY);
+        ioctl(uifd, UI_SET_RELBIT, REL_RZ);
+        ioctl(uifd, UI_SET_EVBIT, EV_KEY);
+        ioctl(uifd, UI_SET_KEYBIT, KEY_RESERVED);
+        ioctl(uifd, UI_SET_KEYBIT, KEY_ESC);
+        ioctl(uifd, UI_SET_KEYBIT, KEY_1);
+        ioctl(uifd, UI_SET_KEYBIT, KEY_2);
+        ioctl(uifd, UI_SET_KEYBIT, KEY_3);
+        ioctl(uifd, UI_SET_KEYBIT, KEY_4);
+        ioctl(uifd, UI_SET_KEYBIT, KEY_5);
+        ioctl(uifd, UI_SET_KEYBIT, KEY_6);
+        ioctl(uifd, UI_SET_KEYBIT, KEY_7);
+        ioctl(uifd, UI_SET_KEYBIT, KEY_8);
+        ioctl(uifd, UI_SET_KEYBIT, KEY_9);
+        ioctl(uifd, UI_SET_KEYBIT, KEY_0);
+    }
+
+    ioctl(uifd, UI_SET_EVBIT, EV_MSC);
+    ioctl(uifd, UI_SET_MSCBIT, MSC_SCAN);
+
+    /* create event device          */
+    if (ioctl(uifd, UI_DEV_CREATE, NULL) < 0)   {
+        print_log("/dev/uinput create error[%d]", errno);
+        fflush(stderr);
+        close(uifd);
+        exit(1);
+    }
+    print_log("## created event device %s", device);
+
+    for (ii = 0; ii < 16; ii++) {
+        snprintf(devFile, 64, "/dev/input/event%d", ii);
+        fd = open(devFile, O_RDONLY);
+        if (fd < 0)     continue;
+
+        memset(devName, 0, sizeof(devName));
+        ioctl(fd, EVIOCGNAME(sizeof(devName)), devName);
+        close(fd);
+        print_log("%d.event device(%s) is %s", ii+1, devFile, devName);
+    }
+}
+
+static int
+convert_value(const char *value, char **errp, int base)
+{
+    int i;
+
+    for (i = 0; value[i]; i++)  {
+        if ((value[i] == ',') || (value[i] == ';') ||
+            (value[i] == ';') || (value[i] == ' ')) {
+            break;
+        }
+    }
+    if (errp)   {
+        *errp = (char *)&value[i];
+    }
+
+    if ((strncasecmp(value, "on", i) == 0) ||
+        (strncasecmp(value, "true", i) == 0) ||
+        (strncasecmp(value, "push", i) == 0) ||
+        (strncasecmp(value, "down", i) == 0) ||
+        (strncasecmp(value, "right", i) == 0))  {
+        return 1;
+    }
+    else if ((strncasecmp(value, "off", i) == 0) ||
+             (strncasecmp(value, "false", i) == 0) ||
+             (strncasecmp(value, "pop", i) == 0) ||
+             (strncasecmp(value, "up", i) == 0) ||
+             (strncasecmp(value, "left", i) == 0))  {
+        return 0;
+    }
+    return strtol(value, (char **)0, 0);
+}
+
+static void
+send_event(const char *cmd)
+{
+    int     i, j;
+    int     key;
+    char    prop[64];
+    char    value[128];
+    int     sec, msec;
+    char    *errp;
+    struct input_event  event;
+    struct js_event     js;
+
+    j = 0;
+    for (i = 0; cmd[i]; i++)    {
+        if ((cmd[i] == '=') || (cmd[i] == ' ')) break;
+        if (j < (int)(sizeof(prop)-1))  {
+            prop[j++] = cmd[i];
+        }
+    }
+
+    prop[j] = 0;
+    j = 0;
+    if (cmd[i] != 0)    {
+        for (i++; cmd[i]; i++)  {
+            if (cmd[i] == ' ')  continue;
+            if (j < (int)(sizeof(value)-1)) {
+                value[j++] = cmd[i];
+            }
+        }
+    }
+    value[j] = 0;
+
+    if (strcasecmp(prop, "sleep") == 0) {
+        sec = 0;
+        msec = 0;
+        for (i = 0; value[i]; i++)  {
+            if (value[i] == '.')        break;
+            sec = sec * 10 + (value[i] & 0x0f);
+        }
+        if (value[i] == '.')    {
+            i++;
+            if (value[i] != 0)  {
+                msec = (value[i] & 0x0f) * 100;
+                i++;
+            }
+            if (value[i] != 0)  {
+                msec = msec + (value[i] & 0x0f) * 10;
+                i++;
+            }
+            if (value[i] != 0)  {
+                msec = msec + (value[i] & 0x0f);
+            }
+        }
+        if (sec > 0)    sleep(sec);
+        if (msec > 0)   usleep(msec * 1000);
+
+        return;
+    }
+
+    for (key = 0; event_key[key].prop[0]; key++)    {
+        if (strcasecmp(prop, event_key[key].prop) == 0) break;
+    }
+    if (! event_key[key].prop[0])   {
+        print_log("UnKnown Event name[%s]", prop);
+        return;
+    }
+
+    if (mTouch != 0)    {
+        memset(&event, 0, sizeof(event));
+        gettimeofday(&event.time, NULL);
+        if (event_key[key].type == SPECIALTYPE_XY)  {
+            event.type = EV_ABS;
+            event.code = ABS_X;
+            event.value = convert_value(value, &errp, 0);
+            if (mDebug) {
+                print_log("Send Event ABS_X=%d\t# %d.%03d", event.value,
+                          (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
+                fflush(stderr);
+            }
+            if (write(uifd, &event, sizeof(struct input_event)) < 0)    {
+                print_log("event write error 1[%d]", errno);
+                fflush(stderr);
+                return;
+            }
+            event.code = ABS_Y;
+            if (*errp == ',')   {
+                event.value = convert_value(errp + 1, (char **)0, 0);
+            }
+            else    {
+                event.value = 0;
+            }
+            event.time.tv_usec += 200;
+            if (event.time.tv_usec >= 1000000)  {
+                event.time.tv_sec ++;
+                event.time.tv_usec -= 1000000;
+            }
+            if (mDebug) {
+                print_log("Send Event ABS_Y=%d\t# %d.%03d", event.value,
+                          (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
+                fflush(stderr);
+            }
+        }
+        else    {
+            event.type = event_key[key].type;
+
+            if (event_key[key].code == -1)   {
+                event.code = convert_value(value, (char **)0, 0);
+            }
+            else    {
+                event.code = event_key[key].code;
+                event.value = convert_value(value, (char **)0, 0);
+            }
+            if (mDebug) {
+                if ((event.type == EV_ABS) && (event.code == ABS_X))    {
+                    print_log("Send Event X=%d\t# %d.%03d", event.value,
+                              (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
+                }
+                else if ((event.type == EV_ABS) && (event.code == ABS_Y))    {
+                    print_log("Send Event Y=%d\t %d.%03d", event.value,
+                              (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
+                }
+                else if ((event.type == EV_KEY) && (event.code == BTN_LEFT) && (event.value == 1))    {
+                    print_log("Send Event BTN_LEFT=Down\t# %d.%03d",
+                              (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
+                }
+                else if ((event.type == EV_KEY) && (event.code == BTN_LEFT) && (event.value == 0))   {
+                    print_log("Send Event BTN_LEFT=Up\t# %d.%03d",
+                              (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
+                }
+                else    {
+                    if ((event.type == EV_REL) && (event.value == 0))   {
+                        event.value = 9;
+                    }
+                    else if ((event.type == EV_KEY) && (event.code == 0))   {
+                        event.code = 9;
+                    }
+                    print_log("Send Event type=%d code=%d value=%d\t# %d.%03d",
+                              event.type, event.code, event.value,
+                              (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
+                }
+                fflush(stderr);
+            }
+        }
+        if (write(uifd, &event, sizeof(struct input_event)) < 0)    {
+            print_log("event write error 2[%d]", errno);
+            fflush(stderr);
+        }
+        else    {
+            /* send EV_SYN */
+            memset(&event, 0, sizeof(event));
+            gettimeofday(&event.time, NULL);
+            event.type = EV_SYN;
+            event.code = SYN_REPORT;
+            if (write(uifd, &event, sizeof(struct input_event)) < 0)    {
+                print_log("syn event write error 3[%d]", errno);
+            }
+        }
+    }
+    else    {
+        memset(&js, 0, sizeof(js));
+        gettimeofday(&event.time, NULL);
+        js.time = (event.time.tv_sec * 1000) + (event.time.tv_usec / 1000);
+        js.type = event_key[key].type;
+        js.number = event_key[key].code;
+        js.value = convert_value(value, (char **)0, 0);
+        if (mDebug) {
+            print_log("Send Event JS=%d,%d,%d\t# %d",
+                      (int)js.type, (int)js.number, (int)js.value, (int)js.time);
+        }
+        if (write(uifd, &js, sizeof(struct js_event)) < 0)  {
+            print_log("event write error 4[%d]", errno);
+            fflush(stderr);
+        }
+    }
+}
+
+static void
+usage(const char *prog)
+{
+    fprintf(stderr, "Usage: %s [-device=device] [{-m/-t/-j}] [-mq[=key]] [-d] [event=value] [event=value] ...\n", prog);
+    exit(0);
+}
+
+int
+main(int argc, char *argv[])
+{
+    int     i, j, k;
+    int     mqkey = 0;
+    struct {
+        long    mtype;
+        char    buf[240];
+    }       mqbuf;
+    char    buf[240];
+
+    j = 0;
+    strcpy(buf, "ico_test_device");
+    for (i = 1; i < argc; i++)  {
+        if (argv[i][0] == '-')  {
+            if (strncasecmp(argv[i], "-device=", 8) == 0)   {
+                strcpy(buf, &argv[i][8]);
+            }
+            else if (strcasecmp(argv[i], "-m") == 0)   {
+                mTouch = 1;                 /* Simulate mouse               */
+            }
+            else if (strcasecmp(argv[i], "-t") == 0)   {
+                mTouch = 2;                 /* Simulate touch-panel         */
+            }
+            else if (strcmp(argv[i], "-j") == 0)   {
+                mTouch = 0;                 /* Simulate joystick            */
+            }
+            else if (strcmp(argv[i], "-J") == 0)   {
+                mTouch = 3;                 /* Simulate joystick, but event is mouse    */
+            }
+            else if (strncasecmp(argv[i], "-mq", 3) == 0)   {
+                if (argv[i][3] == '=')  {
+                    mqkey = strtol(&argv[i][4], (char **)0, 0);
+                }
+                else    {
+                    mqkey = 55551;          /* default message queue key    */
+                }
+            }
+            else if (strcasecmp(argv[i], "-d") == 0)   {
+                mDebug = 1;
+            }
+            else    {
+                usage(argv[0]);
+            }
+        }
+        else    {
+            j++;
+        }
+    }
+
+    init_mq(mqkey);
+
+    init_device(buf);
+
+    mRun = 1;
+
+    signal(SIGTERM, term_signal);
+    signal(SIGINT, term_signal);
+
+    if (mqid >= 0)  {
+        while (mRun)  {
+            memset(&mqbuf, 0, sizeof(mqbuf));
+            if (msgrcv(mqid, &mqbuf, sizeof(mqbuf)-sizeof(long), 0, 0) < 0) {
+                if (errno == EINTR) continue;
+                print_log("test-send_event: mq(%d) receive error[%d]",
+                          mqkey, errno);
+                fflush(stderr);
+                break;
+            }
+            k = 0;
+            j = -1;
+            for (i = 0; mqbuf.buf[i]; i++)    {
+                if ((mqbuf.buf[i] == '#') || (mqbuf.buf[i] == '\n')
+                    || (mqbuf.buf[i] == '\r'))    break;
+                if (mqbuf.buf[i] == '\t') buf[k++] = ' ';
+                else                        buf[k++] = mqbuf.buf[i];
+                if ((j < 0) && (mqbuf.buf[i] != ' ')) j = i;
+            }
+            if (j < 0)  continue;
+            buf[k] = 0;
+            send_event(&buf[j]);
+        }
+        msgctl(mqid, IPC_RMID, NULL);
+    }
+    else if (j <= 0) {
+        while ((mRun != 0) && (fgets(buf, sizeof(buf), stdin) != NULL))  {
+            j = -1;
+            for (i = 0; buf[i]; i++)    {
+                if ((buf[i] == '#') || (buf[i] == '\n') || (buf[i] == '\r'))    break;
+                if (buf[i] == '\t') buf[i] = ' ';
+                if ((j < 0) && (buf[i] != ' ')) j = i;
+            }
+            if (j < 0)  continue;
+            buf[i] = 0;
+            send_event(&buf[j]);
+        }
+    }
+    else    {
+        for (i = 1; i < argc; i++)  {
+            if (argv[i][0] == '-')  continue;
+            if (mRun == 0)  break;
+            send_event(argv[i]);
+        }
+    }
+    exit(0);
+}
+
diff --git a/tests/testdata/cl_surface3.dat b/tests/testdata/cl_surface3.dat
new file mode 100644 (file)
index 0000000..fcd10cb
--- /dev/null
@@ -0,0 +1,7 @@
+#      Test for Weston IVI Plugin for Native Application
+#      Surface Create and Exit
+#
+#      1. Create Surface
+create-surface
+#      2. End of this Application (exit)
+bye
diff --git a/tests/testdata/hs_alltest.dat b/tests/testdata/hs_alltest.dat
new file mode 100644 (file)
index 0000000..7f14582
--- /dev/null
@@ -0,0 +1,118 @@
+#      Test for Device Input Controllers
+#      Input event test
+#
+#      1. Input test (touch event)
+launch ../tests/test-client @1 -width=720 -height=760 -color=0xffff2020 -postsleep=90 < ../tests/testdata/cl_surface3.dat 2> ../tests/testlog/test-client1.log
+sleep 0.5
+layer test-client@1 101
+move test-client@1 10 20
+show test-client@1
+sleep 0.3
+#
+event 55551 XY=1800,250
+sleep 0.1
+event 55551 XY=1780,260
+sleep 0.1
+event 55551 XY=1760,270
+sleep 0.1
+event 55551 XY=1740,280
+event 55551 XY=1720,300
+sleep 0.1
+event 55551 Button=Down
+sleep 0.1
+event 55551 XY=1710,310
+event 55551 XY=1712,308
+sleep 0.1
+event 55551 XY=1714,306
+event 55551 Button=Up
+sleep 1
+kill test-client@1
+sleep 2
+
+#      2. Input test (jyostick event)
+launch ../tests/test-client @2 -color=0xff20ff20 -postsleep=90 < ../tests/testdata/cl_surface3.dat 2> ../tests/testlog/test-client2.log
+sleep 0.3
+layer test-client@2 101
+move test-client@2 250 300
+show test-client@2
+sleep 0.2
+launch ../tests/test-client @3 -color=0xff2020ff -postsleep=90 < ../tests/testdata/cl_surface3.dat 2> ../tests/testlog/test-client3.log
+sleep 0.3
+layer test-client@3 101
+move test-client@3 400 400
+show test-client@3
+sleep 0.5
+# input switch event (only send to Weston)
+event 55552 UpDown=-1
+event 55552 UpDown=0
+event 55552 UpDown=1
+event 55552 UpDown=0
+
+event 55552 LeftRight=-1
+event 55552 LeftRight=0
+event 55552 LeftRight=1
+event 55552 LeftRight=0
+
+event 55552 Cross=1
+event 55552 Cross=0
+event 55552 Squere=1
+event 55552 Squere=0
+event 55552 Circle=1
+event 55552 Circle=0
+event 55552 Triangle=1
+event 55552 Triangle=0
+
+# assign input sw to application
+input_add DrivingForceGT 0 test-client@2
+input_add DrivingForceGT 1 test-client@3
+input_add DrivingForceGT 2 test-client@2
+input_add DrivingForceGT 3 test-client@3
+input_add DrivingForceGT 4 test-client@2
+input_add DrivingForceGT 5 test-client@3
+sleep 0.3
+
+# input switch event (send to Application)
+event 55552 UpDown=-1
+sleep 0.1
+event 55552 UpDown=0
+sleep 0.3
+event 55552 UpDown=1
+sleep 0.1
+event 55552 UpDown=0
+sleep 0.3
+
+event 55552 LeftRight=-1
+sleep 0.1
+event 55552 LeftRight=0
+sleep 0.3
+event 55552 LeftRight=1
+sleep 0.1
+event 55552 LeftRight=0
+sleep 0.3
+
+event 55552 Cross=1
+sleep 0.1
+event 55552 Cross=0
+sleep 0.1
+event 55552 Squere=1
+sleep 0.1
+event 55552 Squere=0
+sleep 0.1
+event 55552 Circle=1
+sleep 0.1
+event 55552 Circle=0
+sleep 0.1
+event 55552 Triangle=1
+sleep 0.1
+event 55552 Triangle=0
+sleep 1
+
+#
+kill test-client@2
+sleep 0.5
+kill test-client@3
+sleep 0.5
+#
+#      3. End of Test
+bye
+
diff --git a/tests/weston.ini b/tests/weston.ini
new file mode 100644 (file)
index 0000000..5be1667
--- /dev/null
@@ -0,0 +1,24 @@
+[core]
+modules=ico_plugin_loader.so
+
+#[output]
+#name=HDMI3
+#mode=1680x945
+#mode=1920x1080
+#mode=173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync
+#transform=90
+
+#[output]
+#name=LVDS1
+#mode=1680x1050
+#transform=90
+
+#[output]
+#name=VGA1
+#mode=173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync
+#transform=90
+
+#[output]
+#name=X1
+#mode=1024x768
+#transform=flipped-270
diff --git a/tests/weston_ivi_plugin.ini b/tests/weston_ivi_plugin.ini
new file mode 100644 (file)
index 0000000..89798d3
--- /dev/null
@@ -0,0 +1,18 @@
+[plugin]
+modules=ico_ivi_common.so,ico_ivi_shell.so,ico_window_mgr.so,ico_input_mgr.so
+
+[shell]
+animation=none
+#animation=zoom
+# 0=hide on surface create(for with HomeScreen)/1=show on surface create(for Debug)
+visible_on_create=0
+
+[debug]
+# option flag
+#  0x00000001 : =1, At the time of unvisible of surface, it travels surface outside a screen.
+#             : =0, Exclude surface of the unvisible from a list of surface of Westons.
+option_flag=1
+
+# 0=no debug write(1=err/2=warn/3=info/4=debug)
+ivi_debug=4
+
diff --git a/touch_egalax/Makefile.am b/touch_egalax/Makefile.am
new file mode 100644 (file)
index 0000000..ea6be86
--- /dev/null
@@ -0,0 +1,24 @@
+export abs_builddir
+
+AM_CFLAGS = $(GCC_CFLAGS)
+AM_CPPFLAGS = -I$(top_srcdir)/src $(COMPOSITOR_CFLAGS)
+
+bin_PROGRAMS =         \
+       ico_ictl-touch_egalax   \
+       ico_ictl-egalax_calibration
+
+check_LTLIBRARIES = $(TESTS)
+check_PROGRAMS = \
+       ico_ictl-touch_egalax   \
+       ico_ictl-egalax_calibration
+
+AM_LDFLAGS = -module -avoid-version -rpath $(libdir)
+
+ico_ictl_touch_egalax_SOURCES = \
+       ico_ictl-touch_egalax.c
+ico_ictl_touch_egalax_LDADD = $(SIMPLE_CLIENT_LIBS)
+
+ico_ictl_egalax_calibration_SOURCES = \
+       ico_ictl-egalax_calibration.c
+ico_ictl_egalax_calibration_LDADD = $(SIMPLE_CLIENT_LIBS)
+
diff --git a/touch_egalax/ico_ictl-egalax_calibration.c b/touch_egalax/ico_ictl-egalax_calibration.c
new file mode 100644 (file)
index 0000000..731ccca
--- /dev/null
@@ -0,0 +1,467 @@
+/*
+ * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
+ *
+ * This program is licensed under the terms and conditions of the
+ * Apache License, version 2.0.  The full text of the Apache License is at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ */
+/**
+ * @brief   Touchpanel(eGalax) Calibration Tool
+ *
+ * @date    Feb-20-2013
+ */
+
+#include "ico_ictl-touch_egalax.h"
+
+/* Number of times to repeat a touch about each point   */
+#define CALIBCONF_READ_NUM    (5)
+
+static void print_usage(const char *pName);
+static char *find_event_device(void);
+static FILE *open_conffile(void);
+static void get_coordinates(int evfd);
+static void read_event(int evfd, int *x, int *y);
+static void sort_data(int buff[], int left, int right);
+
+int             mDispWidth = CALIBRATION_DISP_WIDTH;
+int             mDispHeight = CALIBRATION_DISP_HEIGHT;
+int             mPosX[4];
+int             mPosY[4];
+
+int             mDebug = 0;
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   Touchpanel(eGalax) Calibration Tool main routine
+ *
+ * @param   arguments of standard main routeins(argc, argv)
+ * @return  result
+ * @retval  0       sucess
+ * @retval  8       configuration file Error
+ * @retval  9       can not open event device(touchpanel)
+ */
+/*--------------------------------------------------------------------------*/
+int
+main(int argc, char *argv[])
+{
+    int     ii, cnt;
+    int     evfd;                               /* event device fd */
+    char    *eventDeviceName = NULL;            /* event device name to hook */
+    FILE    *fp;
+    char    buff[128];
+
+    /* Get options                      */
+    for (ii = 1; ii < argc; ii++) {
+        if (strcasecmp(argv[ii], "-h") == 0) {
+            /* Help                     */
+            print_usage(argv[0]);
+            exit(0);
+        }
+        else if (strcasecmp(argv[ii], "-width") == 0)   {
+            /* Screen width             */
+            ii++;
+            if (ii >= argc) {
+                print_usage(argv[0]);
+                exit(0);
+            }
+            mDispWidth = strtol(argv[ii], (char **)0, 0);
+            if ((mDispWidth <= 0) || (mDispWidth > 8192))   {
+                print_usage(argv[0]);
+                exit(0);
+            }
+        }
+        else if (strcasecmp(argv[ii], "-height") == 0)  {
+            /* Screen height            */
+            ii++;
+            if (ii >= argc) {
+                print_usage(argv[0]);
+                exit(0);
+            }
+            mDispHeight = strtol(argv[ii], (char **)0, 0);
+            if ((mDispHeight <= 0) || (mDispHeight > 8192)) {
+                print_usage(argv[0]);
+                exit(0);
+            }
+        }
+        else {
+            /* Input event device name  */
+            eventDeviceName = argv[ii];
+        }
+    }
+
+    if (eventDeviceName == NULL) {
+        /* If event device not present, get default device  */
+        eventDeviceName = find_event_device();
+        if (eventDeviceName == NULL) {
+            /* System has no touchpanel, Error  */
+            exit(9);
+        }
+    }
+
+    evfd = open(eventDeviceName, O_RDONLY);
+    if (evfd < 0) {
+        perror("Open event device");
+        exit(9);
+    }
+
+    /* Open configuration file for output   */
+    fp = open_conffile();
+    if (fp == NULL) {
+        fprintf(stderr, "%s: Can not open config file\n", argv[0]);
+        close(evfd);
+        exit(8);
+    }
+
+    CALIBRATION_PRINT("\n");
+    CALIBRATION_PRINT("+================================================+\n");
+    CALIBRATION_PRINT("| Configration Tool for Calibration Touch ver0.1 |\n");
+    CALIBRATION_PRINT("+------------------------------------------------+\n");
+    CALIBRATION_PRINT("| use display width = %d\n", CALIBRATION_DISP_WIDTH);
+    CALIBRATION_PRINT("| use display height = %d\n", CALIBRATION_DISP_HEIGHT);
+    CALIBRATION_PRINT("+------------------------------------------------+\n");
+
+    get_coordinates(evfd);
+
+    CALIBRATION_PRINT("+------------------------------------------------+\n");
+    CALIBRATION_PRINT("| save config                                    |\n");
+    CALIBRATION_PRINT("+------------------------------------------------+\n");
+
+    cnt = sprintf(buff, "%s=%d\n", CALIBRATOIN_STR_DISP_W, mDispWidth);
+    fwrite(buff, sizeof(char), cnt, fp);
+    CALIBRATION_PRINT("| %s", buff);
+
+    cnt = sprintf(buff, "%s=%d\n", CALIBRATOIN_STR_DISP_H, mDispHeight);
+    fwrite(buff, sizeof(char), cnt, fp);
+    CALIBRATION_PRINT("| %s", buff);
+
+    cnt = sprintf(buff, "%s=%d*%d\n", CALIBRATOIN_STR_POS1, mPosX[0], mPosY[0]);
+    fwrite(buff, sizeof(char), cnt, fp);
+    CALIBRATION_PRINT("| %s", buff);
+
+    cnt = sprintf(buff, "%s=%d*%d\n", CALIBRATOIN_STR_POS2, mPosX[1], mPosY[1]);
+    fwrite(buff, sizeof(char), cnt, fp);
+    CALIBRATION_PRINT("| %s", buff);
+
+    cnt = sprintf(buff, "%s=%d*%d\n", CALIBRATOIN_STR_POS3, mPosX[2], mPosY[2]);
+    fwrite(buff, sizeof(char), cnt, fp);
+    CALIBRATION_PRINT("| %s", buff);
+
+    cnt = sprintf(buff, "%s=%d*%d\n", CALIBRATOIN_STR_POS4, mPosX[3], mPosY[3]);
+    fwrite(buff, sizeof(char), cnt, fp);
+    CALIBRATION_PRINT("| %s", buff);
+
+    if (evfd >= 0) {
+        close(evfd);
+    }
+
+    /* Close outputed configuration file    */
+    fclose(fp);
+
+    CALIBRATION_PRINT("|                                                |\n");
+    CALIBRATION_PRINT("| finish Tools                                   |\n");
+
+    exit(0);
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   find_event_device: Find eGalax touchpanel device
+ *
+ * @param       nothing
+ * @return      device name
+ * @retval      != NULL     device name string
+ * @retvel      == NULL     system has no eGalax touchpanel
+ */
+/*--------------------------------------------------------------------------*/
+static char *
+find_event_device(void)
+{
+    FILE    *fp;
+    int     eGalax = 0;
+    int     i, j, k;
+    char    buf[240];
+    static char edevice[64];
+
+    /* Search input device      */
+    fp = fopen("/proc/bus/input/devices", "r");
+    if (!fp)    {
+        CALIBRATION_INFO("find_event_device: /proc/bus/input/devices Open Error\n");
+        return(NULL);
+    }
+
+    while (fgets(buf, sizeof(buf), fp)) {
+        if (eGalax == 0)    {
+            for (i = 0; buf[i]; i++)    {
+                if (strncmp(&buf[i], "eGalax", 6) == 0) {
+                    /* Find eGalax touchpanel device    */
+                    eGalax = 1;
+                    break;
+                }
+            }
+        }
+        else    {
+            for (i = 0; buf[i]; i++)    {
+                if (strncmp(&buf[i], "Handlers", 8) == 0)   {
+                    /* Find eGalax device and Handlers  */
+                    for (j = i+8; buf[j]; j++)  {
+                        if (buf[j] != ' ')  continue;
+                        strcpy(edevice, "/dev/input/");
+                        for (k = strlen(edevice); k < (int)sizeof(edevice); k++)    {
+                            j++;
+                            if ((buf[j] == 0) || (buf[j] == ' ') ||
+                                (buf[j] == '\t') || (buf[j] == '\n') ||
+                                (buf[j] == '\r'))   break;
+                            edevice[k] = buf[j];
+                        }
+                        edevice[k] = 0;
+                        CALIBRATION_INFO("Event device of eGalax=<%s>\n", edevice);
+                        fclose(fp);
+                        return(edevice);
+                    }
+                    break;
+                }
+            }
+        }
+    }
+    fclose(fp);
+
+    CALIBRATION_PRINT("System has no eGalax Touchpanel\n");
+    return(NULL);
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief       read coordinates form touchpanel
+ *
+ * @param[in]   evfd        touchpanel event device
+ * @return      nothing
+ */
+/*--------------------------------------------------------------------------*/
+static void
+get_coordinates(int evfd)
+{
+    int     bufX[CALIBCONF_READ_NUM];
+    int     bufY[CALIBCONF_READ_NUM];
+    int     x, y;
+    int     ii;
+
+    CALIBRATION_PRINT("| Touch the Top-Left corner of the screen %d times\n",
+                      CALIBCONF_READ_NUM);
+    for (ii = 0; ii < CALIBCONF_READ_NUM; ii++) {
+        read_event(evfd, &x, &y);
+        bufX[ii] = x;
+        bufY[ii] = y;
+        CALIBRATION_PRINT("| # %d: %dx%d \n", ii, x, y);
+    }
+    sort_data(bufX, 0, CALIBCONF_READ_NUM - 1);
+    sort_data(bufY, 0, CALIBCONF_READ_NUM - 1);
+    mPosX[0] = bufX[CALIBCONF_READ_NUM / 2];
+    mPosY[0] = bufY[CALIBCONF_READ_NUM / 2];
+
+    CALIBRATION_PRINT("+------------------------------------------------+\n");
+    CALIBRATION_PRINT("| Touch the Top-Right corner of the screen %d times\n",
+                      CALIBCONF_READ_NUM);
+    for (ii = 0; ii < CALIBCONF_READ_NUM; ii++) {
+        read_event(evfd, &x, &y);
+        bufX[ii] = x;
+        bufY[ii] = y;
+        CALIBRATION_PRINT("| # %d: %dx%d \n", ii, x, y);
+    }
+    sort_data(bufX, 0, CALIBCONF_READ_NUM - 1);
+    sort_data(bufY, 0, CALIBCONF_READ_NUM - 1);
+    mPosX[1] = bufX[CALIBCONF_READ_NUM / 2];
+    mPosY[1] = bufY[CALIBCONF_READ_NUM / 2];
+
+    CALIBRATION_PRINT("+------------------------------------------------+\n");
+    CALIBRATION_PRINT("| Touch the Bottom-Left corner of the screen %d times\n",
+                      CALIBCONF_READ_NUM);
+    for (ii = 0; ii < CALIBCONF_READ_NUM; ii++) {
+        read_event(evfd, &x, &y);
+        bufX[ii] = x;
+        bufY[ii] = y;
+        CALIBRATION_PRINT("| # %d: %dx%d \n", ii, x, y);
+    }
+    sort_data(bufX, 0, CALIBCONF_READ_NUM - 1);
+    sort_data(bufY, 0, CALIBCONF_READ_NUM - 1);
+    mPosX[2] = bufX[CALIBCONF_READ_NUM / 2];
+    mPosY[2] = bufY[CALIBCONF_READ_NUM / 2];
+
+    CALIBRATION_PRINT("+------------------------------------------------+\n");
+    CALIBRATION_PRINT("| Touch the Bottom-Right corner of the screen %d times\n",
+                      CALIBCONF_READ_NUM);
+    for (ii = 0; ii < CALIBCONF_READ_NUM; ii++) {
+        read_event(evfd, &x, &y);
+        bufX[ii] = x;
+        bufY[ii] = y;
+        CALIBRATION_PRINT("| # %d: %dx%d \n", ii, x, y);
+    }
+    sort_data(bufX, 0, CALIBCONF_READ_NUM - 1);
+    sort_data(bufY, 0, CALIBCONF_READ_NUM - 1);
+    mPosX[3] = bufX[CALIBCONF_READ_NUM / 2];
+    mPosY[3] = bufY[CALIBCONF_READ_NUM / 2];
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief       sort integer dates
+ *
+ * @param[in]   buff    array of integer datas
+ * @param[in]   left    array start index
+ * @param[in]   right   array end index
+ * @return      nothing
+ */
+/*--------------------------------------------------------------------------*/
+static void
+sort_data(int buff[], int left, int right)
+{
+    int     ii, jj, pivot;
+    int     tmp;
+
+    ii = left;
+    jj = right;
+
+    pivot = buff[(left + right) / 2];
+    while (1) {
+        while (buff[ii] < pivot) {
+            ii++;
+        }
+        while (pivot < buff[jj]) {
+            jj--;
+        }
+        if (ii >= jj) {
+            break;
+        }
+        tmp = buff[ii];
+        buff[ii] = buff[jj];
+        buff[jj] = tmp;
+        ii++;
+        jj--;
+    }
+
+    if (left < (ii - 1)) {
+        sort_data(buff, left, ii - 1);
+    }
+    if ((jj + 1) < right) {
+        sort_data(buff, jj + 1, right);
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief       event read from touchpanel
+ *
+ * @param[in]   evfd        touchpanel event device
+ * @return      nothing
+ */
+/*--------------------------------------------------------------------------*/
+static void
+read_event(int evfd, int *x, int *y)
+{
+    fd_set      fds;
+    int         ret;
+    int         rsize;
+    int         ii;
+    int         flagX = 0;
+    int         flagY = 0;
+    struct timeval  delay;
+    struct input_event events[64];
+
+    while (1) {
+        /* select timeoutt value    */
+        delay.tv_sec = 0;
+        delay.tv_usec = 100*1000;
+        /* fs_set                   */
+        FD_ZERO(&fds);
+        FD_SET(evfd, &fds);
+
+        /* wait for event read or timedout  */
+        ret = select(evfd + 1, &fds, NULL, NULL, &delay);
+        if (ret <= 0) {
+            continue;
+        }
+        if (FD_ISSET(evfd, &fds)) {
+            /* event read           */
+            rsize = read(evfd, events, sizeof(events) );
+            for (ii = 0; ii < (int)(rsize/sizeof(struct input_event)); ii++) {
+                if ((events[ii].type == EV_ABS) && (events[ii].code == ABS_X)) {
+                    /* X       */
+                    flagX++;
+                    *x = events[ii].value;
+                }
+                else if ((events[ii].type == EV_ABS) && (events[ii].code == ABS_Y)) {
+                    /* Y       */
+                    flagY++;
+                    *y = events[ii].value;
+                }
+            }
+        }
+        /* Input 2 times (Touch On and Off) */
+        if ((flagX >= 2) && (flagY >= 2)) {
+            break;
+        }
+    }
+
+    while (1) {
+        delay.tv_sec = 0;
+        delay.tv_usec = 200*1000;
+        FD_ZERO(&fds);
+        FD_SET(evfd, &fds);
+
+        /* wait for input (or timedout) */
+        ret = select(evfd + 1, &fds, NULL, NULL, &delay);
+        if (ret == 0) {
+            break;
+        }
+        else if (ret < 0) {
+            continue;
+        }
+        rsize = read(evfd, events, sizeof(events));
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief       open configuration file
+ *
+ * @param       nothing
+ * @return      file descriptor
+ * @retval      != NULL     file descriptor
+ * @retval      NULL        open error
+ */
+/*--------------------------------------------------------------------------*/
+static FILE *
+open_conffile(void)
+{
+    char    *confp;
+    FILE    *fp;
+
+    /* Get configuration file path  */
+    confp = getenv(CALIBRATOIN_CONF_ENV);
+    if (! confp)  {
+        confp = CALIBRATOIN_CONF_FILE;
+    }
+
+    /* Open configuration file      */
+    fp = fopen(confp, "w");
+    if (fp == NULL) {
+        perror(confp);
+        return fp;
+    }
+    return fp;
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief       print help
+ *
+ * @param[in]   pName       program name
+ * @return      nothing
+ */
+/*--------------------------------------------------------------------------*/
+static void
+print_usage(const char *pName)
+{
+    fprintf(stderr, "Usage: %s [-h][-width width][-height height] [device]\n", pName);
+}
+
diff --git a/touch_egalax/ico_ictl-touch_egalax.c b/touch_egalax/ico_ictl-touch_egalax.c
new file mode 100644 (file)
index 0000000..937ad4b
--- /dev/null
@@ -0,0 +1,850 @@
+/*
+ * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
+ *
+ * This program is licensed under the terms and conditions of the
+ * Apache License, version 2.0.  The full text of the Apache License is at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ */
+/**
+ * @brief   Device Input Controller(eGalax Touchpanel)
+ *          Send touchpanel input enevt to Weston
+ *
+ * @date    Feb-20-2013
+ */
+
+#include "ico_ictl-touch_egalax.h"
+
+/* Change touch event       */
+#define REPLACE_TOUCH_EVENT 1       /* Change touch event to mouse left button event*/
+
+/* Program name             */
+#define     CALIBDAE_DEV_NAME       "ico_ictl-touch_egalax"
+
+static void print_usage(const char *pName);
+static char *find_event_device(void);
+static int setup_uinput(char *uinputDeviceName);
+static void set_eventbit(int uifd);
+static int open_uinput(char *uinputDeviceName);
+static void close_uinput(int uifd);
+static void event_iterate(int uifd, int evfd);
+static void setup_sighandler(void);
+static void terminate_program(const int signal);
+static int setup_program(void);
+static int calibration_event(struct input_event *in, struct input_event *out);
+static void push_event(struct input_event *ev);
+static void push_eventlog(const char *cmd, const int value, struct timeval *tp);
+
+int             mRunning = -1;          /* Running flag             */
+int             mDebug = 0;             /* Debug flag               */
+int             mEventLog = 0;          /* event input log          */
+struct timeval  lastEvent = { 0, 0 };   /* last input event time    */
+
+/* Configurations               */
+int             mDispWidth = CALIBRATION_DISP_WIDTH;
+int             mDispHeight = CALIBRATION_DISP_HEIGHT;
+int             mPosX[4] = { 0, 0, 0, 0 };
+int             mPosY[4] = { 0, 0, 0, 0 };
+int             mXlow = 0;
+int             mXheigh = 0;
+int             mYlow = 0;
+int             mYheigh = 0;
+
+/* Optiones                     */
+int             mTrans = 0;             /* Rotate(0,90,180 or 270)  */
+int             mRevX = 0;              /* Reverse X coordinate     */
+int             mRevY = 0;              /* Reverse Y coordinate     */
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   Device Input Controller: For eGalax TouchPanel
+ *          main routine
+ *
+ * @param   main() finction's standard parameter (argc,argv)
+ * @return  result
+ * @retval  0       success
+ * @retval  8       failed(configuration error)
+ * @retval  9       failed(event device error)
+ */
+/*--------------------------------------------------------------------------*/
+int
+main(int argc, char *argv[])
+{
+    int     ii;
+    int     err;
+    int     uifd;                               /* uinput fd */
+    int     evfd;                               /* event device fd */
+    char    *eventDeviceName = NULL;            /* event device name to hook */
+    char    *uinputDeviceName = "/dev/uinput";  /* User Input module */
+
+    for (ii = 1; ii < argc; ii++) {
+        if (strcmp(argv[ii], "-h") == 0)    {
+            print_usage(argv[0]);
+            exit(0);
+        }
+        else if (strcmp(argv[ii], "-d") == 0) {
+            mDebug = 1;
+        }
+        else if (strcmp(argv[ii], "-t") == 0) {
+            if ((ii < (argc-1)) && (argv[ii+1][0] != '-'))  {
+                ii++;
+                mTrans = strtol(argv[ii], (char **)0, 0);
+            }
+            else    {
+                mTrans = 90;
+            }
+        }
+        else if (strcmp(argv[ii], "-l") == 0) {
+            mEventLog = 1;                  /* Input Log for System Test    */
+        }
+        else if (strcmp(argv[ii], "-L") == 0) {
+            mEventLog = 2;                  /* Output Log for Unit Test     */
+        }
+        else {
+            eventDeviceName = argv[ii];
+        }
+    }
+
+    if (eventDeviceName == NULL) {
+        /* If event device not present, get default device  */
+        eventDeviceName = find_event_device();
+        if (eventDeviceName == NULL) {
+            /* System has no touchpanel, Error  */
+            exit(9);
+        }
+    }
+
+    err = setup_program();
+    if (err < 0) {
+        if (err == -2)  {
+            fprintf(stderr, "%s: Illegal config value\n", argv[0]);
+        }
+        else    {
+            fprintf(stderr, "%s: Can not read config file\n", argv[0]);
+        }
+        exit(8);
+    }
+
+    if (! mDebug) {
+        if (daemon(0, 1) < 0) {
+            fprintf(stderr, "%s: Can not Create Daemon\n", argv[0]);
+            exit(1);
+        }
+    }
+
+    /* setup uinput device      */
+    uifd = setup_uinput(uinputDeviceName);
+    if (uifd < 0) {
+        fprintf(stderr, "uinput(%s) initialize failed. Continue anyway\n", uinputDeviceName);
+        exit(9);
+    }
+
+    evfd = open(eventDeviceName, O_RDONLY);
+    if (evfd < 0) {
+        fprintf(stderr, "event device(%s) Open Error[%d]\n", eventDeviceName, errno);
+        close_uinput(uifd);
+        exit(9);
+    }
+    CALIBRATION_DEBUG("main: input device(%s) = %d\n", eventDeviceName, evfd);
+
+    setup_sighandler();
+
+    /* event read               */
+    mRunning = 1;
+    event_iterate(uifd, evfd);
+
+    if (evfd >= 0)  {
+        close(evfd);
+    }
+
+    close_uinput(uifd);
+
+    exit(0);
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief       initialize with get configurations
+ *
+ * @param       nothing
+ * @return      result
+ * @retval      0           sucess
+ * @retval      -1          config file read error
+ * @retval      -2          illegal config value
+ */
+/*--------------------------------------------------------------------------*/
+static int
+setup_program(void)
+{
+    char    *confp;
+    char    buff[128];
+    FILE    *fp;
+    int     work;
+
+    /* Get configuration file path  */
+    confp = getenv(CALIBRATOIN_CONF_ENV);
+    if (! confp)  {
+        confp = CALIBRATOIN_CONF_FILE;
+    }
+
+    /* Open configuration file      */
+    fp = fopen(confp, "r");
+    if (fp == NULL) {
+        perror(confp);
+        return -1;
+    }
+
+    while (fgets(buff, sizeof(buff), fp)) {
+        if (buff[0] == '#') {
+            /* comment line, skip       */
+            continue;
+        }
+        else if (strncmp(buff,
+                         CALIBRATOIN_STR_DISP_W,
+                         sizeof(CALIBRATOIN_STR_DISP_W) - 1) == 0) {
+            /* screen width             */
+            strtok(buff, CALIBRATOIN_STR_SEPAR);
+            mDispWidth = atoi(strtok(NULL, CALIBRATOIN_STR_SEPAR));
+            CALIBRATION_INFO("mDispWidth = %d\n", mDispWidth);
+        }
+        else if (strncmp(buff,
+                         CALIBRATOIN_STR_DISP_H,
+                         sizeof(CALIBRATOIN_STR_DISP_H) - 1) == 0) {
+            /* screen height            */
+            strtok(buff, CALIBRATOIN_STR_SEPAR);
+            mDispHeight = atoi(strtok(NULL, CALIBRATOIN_STR_SEPAR));
+            CALIBRATION_INFO("mDispHeight = %d\n", mDispHeight);
+        }
+        else if (strncmp(buff,
+                         CALIBRATOIN_STR_POS1,
+                         sizeof(CALIBRATOIN_STR_POS1) - 1) == 0) {
+            /* position1 : Top-Left     */
+            strtok(buff, CALIBRATOIN_STR_SEPAR);
+            mPosX[0] = atoi(strtok(NULL, CALIBRATOIN_STR_SEPAR));
+            mPosY[0] = atoi(strtok(NULL, CALIBRATOIN_STR_SEPAR));
+            CALIBRATION_INFO("POS1 = %dx%d\n", mPosX[0], mPosY[0]);
+        }
+        else if (strncmp(buff,
+                         CALIBRATOIN_STR_POS2,
+                         sizeof(CALIBRATOIN_STR_POS2) - 1) == 0) {
+            /* position2 : Top-Right    */
+            strtok(buff, CALIBRATOIN_STR_SEPAR);
+            mPosX[1] = atoi(strtok(NULL, CALIBRATOIN_STR_SEPAR));
+            mPosY[1] = atoi(strtok(NULL, CALIBRATOIN_STR_SEPAR));
+            CALIBRATION_INFO("POS2 = %dx%d\n", mPosX[1], mPosY[1]);
+        }
+        else if (strncmp(buff,
+                         CALIBRATOIN_STR_POS3,
+                         sizeof(CALIBRATOIN_STR_POS3) - 1) == 0) {
+            /* position3 : Bottom-Left  */
+            strtok(buff, CALIBRATOIN_STR_SEPAR);
+            mPosX[2] = atoi(strtok(NULL, CALIBRATOIN_STR_SEPAR));
+            mPosY[2] = atoi(strtok(NULL, CALIBRATOIN_STR_SEPAR));
+            CALIBRATION_INFO("POS3 = %dx%d\n", mPosX[2], mPosY[2]);
+        }
+        else if (strncmp(buff,
+                         CALIBRATOIN_STR_POS4,
+                         sizeof(CALIBRATOIN_STR_POS4) - 1) == 0) {
+            /* position4 : Bottom-Right */
+            strtok(buff, CALIBRATOIN_STR_SEPAR);
+            mPosX[3] = atoi(strtok(NULL, CALIBRATOIN_STR_SEPAR));
+            mPosY[3] = atoi(strtok(NULL, CALIBRATOIN_STR_SEPAR));
+            CALIBRATION_INFO("POS4 = %dx%d\n", mPosX[3], mPosY[3]);
+        }
+    }
+    fclose(fp);
+
+    /* Reverse X coordinate, if need    */
+    if (mPosX[0] > mPosX[1])    {
+        int     work;
+        work = mPosX[0];
+        mPosX[0] = mPosX[1];
+        mPosX[1] = work;
+        work = mPosX[2];
+        mPosX[2] = mPosX[3];
+        mPosX[3] = work;
+        mRevX = 1;
+        CALIBRATION_INFO("Reverse X\n");
+    }
+
+    /* Reverse Y coordinate, if need    */
+    if (mPosY[0] > mPosY[2])    {
+        work = mPosY[0];
+        mPosY[0] = mPosY[2];
+        mPosY[2] = work;
+        work = mPosY[1];
+        mPosY[1] = mPosY[3];
+        mPosY[3] = work;
+        mRevY = 1;
+        CALIBRATION_INFO("Reverse Y\n");
+    }
+
+    if ((mRevX != 0) || (mRevY != 0))   {
+        CALIBRATION_INFO("Changed POS1 = %dx%d\n", mPosX[0], mPosY[0]);
+        CALIBRATION_INFO("Changed POS2 = %dx%d\n", mPosX[1], mPosY[1]);
+        CALIBRATION_INFO("Changed POS3 = %dx%d\n", mPosX[2], mPosY[2]);
+        CALIBRATION_INFO("Changed POS4 = %dx%d\n", mPosX[3], mPosY[3]);
+    }
+
+    mXlow = (mPosX[0] + mPosX[2]) / 2;
+    mXheigh = (mPosX[1] + mPosX[3]) / 2;
+    if (mXheigh <= mXlow)   {
+        return -2;
+    }
+
+    mYlow = (mPosY[0] + mPosY[1]) / 2;
+    mYheigh = (mPosY[2] + mPosY[3]) / 2;
+    if (mYheigh <= mYlow)   {
+        return -2;
+    }
+    return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief       signal handler
+ *
+ *
+ * @param[in]   signal  signal numnber
+ * @return      nothing
+ */
+/*--------------------------------------------------------------------------*/
+static void
+terminate_program(const int signal)
+{
+    mRunning = -signal;
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief       setup signal handler
+ *
+ * @param       nothing
+ * @return      nothing
+ */
+/*--------------------------------------------------------------------------*/
+static void
+setup_sighandler(void)
+{
+    sigset_t    mask;
+
+    sigemptyset(&mask);
+
+    signal(SIGTERM, terminate_program);
+
+    sigaddset(&mask, SIGTERM);
+    sigprocmask(SIG_UNBLOCK, &mask, NULL);
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   find_event_device: Find eGalax touchpanel device
+ *
+ *
+ * @param       nothing
+ * @return      device name
+ * @retval      != NULL     device name string
+ * @retvel      == NULL     system has no eGalax touchpanel
+ */
+/*--------------------------------------------------------------------------*/
+static char *
+find_event_device(void)
+{
+    FILE    *fp;
+    int     eGalax = 0;
+    int     i, j, k;
+    char    buf[240];
+    static char edevice[64];
+
+    char *pdev = getenv(CALIBRATOIN_INPUT_DEV);
+
+    if ((pdev != NULL) && (*pdev != 0)) {
+        /* Search pseudo input device for Debug */
+        int     fd;
+        for (i = 0; i < 16; i++) {
+            snprintf(edevice, 64, "/dev/input/event%d", i);
+            fd = open(edevice, O_RDONLY | O_NONBLOCK);
+            if (fd < 0)     continue;
+
+            memset(buf, 0, sizeof(buf));
+            ioctl(fd, EVIOCGNAME(sizeof(buf)), buf);
+            close(fd);
+            k = 0;
+            for (j = 0; buf[j]; j++) {
+                if (buf[j] != ' ') {
+                    buf[k++] = buf[j];
+                }
+            }
+            buf[k] = 0;
+
+            if (strncasecmp(buf, pdev, sizeof(buf)) == 0)   {
+                CALIBRATION_INFO("Event device of eGalax=<%s>\n", edevice);
+                return edevice;
+            }
+        }
+    }
+    else    {
+        /* Search input device      */
+        fp = fopen("/proc/bus/input/devices", "r");
+        if (!fp)    {
+            CALIBRATION_PRINT("find_event_device: /proc/bus/input/devices Open Error\n");
+            return NULL;
+        }
+
+        while (fgets(buf, sizeof(buf), fp)) {
+            if (eGalax == 0)    {
+                for (i = 0; buf[i]; i++)    {
+                    if (strncmp(&buf[i], "eGalax", 6) == 0) {
+                        /* Find eGalax touchpanel device    */
+                        eGalax = 1;
+                        break;
+                    }
+                }
+            }
+            else    {
+                for (i = 0; buf[i]; i++)    {
+                    if (strncmp(&buf[i], "Handlers", 8) == 0)   {
+                        /* Find eGalax device and Handlers  */
+                        for (j = i+8; buf[j]; j++)  {
+                            if (buf[j] != ' ')  continue;
+                            strcpy(edevice, "/dev/input/");
+                            for (k = strlen(edevice); k < (int)sizeof(edevice); k++)    {
+                                j++;
+                                if ((buf[j] == 0) || (buf[j] == ' ') ||
+                                    (buf[j] == '\t') || (buf[j] == '\n') ||
+                                    (buf[j] == '\r'))   break;
+                                edevice[k] = buf[j];
+                            }
+                            edevice[k] = 0;
+                            CALIBRATION_INFO("Event device of eGalax=<%s>\n", edevice);
+                            fclose(fp);
+                            return edevice;
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+        fclose(fp);
+    }
+    CALIBRATION_PRINT("%s: System has no eGalax Touchpanel\n", CALIBDAE_DEV_NAME);
+    return NULL;
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief       event input and convert (main loop)
+ *
+ *
+ * @param[in]   uifd        event output file descriptor
+ * @param[in]   evfd        event input file descriptor
+ * @return      nothing
+ */
+/*--------------------------------------------------------------------------*/
+static void
+event_iterate(int uifd, int evfd)
+{
+    fd_set      fds;
+    int         ret;
+    int         rsize;
+    int         ii;
+    int         retry;
+    struct timeval  delay;
+    struct input_event events[128];
+    struct input_event event;
+
+    ioctl(evfd, EVIOCGRAB, 1);
+
+    retry = 0;
+
+    while (mRunning > 0) {
+        delay.tv_sec = 1;
+        delay.tv_usec = 0;
+
+        FD_ZERO(&fds);
+        FD_SET(evfd, &fds);
+
+        ret = select(evfd + 1, &fds, NULL, NULL, &delay);
+        if (ret <= 0) {
+            continue;
+        }
+        if (FD_ISSET(evfd, &fds)) {
+            rsize = read(evfd, events, sizeof(events));
+            if (rsize <= 0) {
+                if (rsize < 0)  {
+                    CALIBRATION_PRINT("event_iterate: input device(%d) end<%d>\n", evfd, errno);
+                    retry ++;
+                    if (retry > CALIBRATOIN_RETRY_COUNT)    {
+                        return;
+                    }
+                }
+                usleep(CALIBRATOIN_RETRY_WAIT * 1000);
+                continue;
+            }
+            retry = 0;
+            for (ii = 0; ii < (int)(rsize/sizeof(struct input_event)); ii++) {
+                ret = calibration_event(&events[ii], &event);
+#ifdef  REPLACE_TOUCH_EVENT
+                if (ret >= 0)   {
+                    if (write(uifd, &event, sizeof(struct input_event)) < 0)    {
+                        CALIBRATION_PRINT("%s: Event write error %d[%d]\n",
+                                          CALIBDAE_DEV_NAME, uifd, errno);
+                    }
+                    if (mEventLog == 2) {
+                        push_event(&event);
+                    }
+                    if (ret > 0)   {
+                        event.type = EV_KEY;
+                        event.code = BTN_LEFT;
+                        event.value = 1;
+                        if (write(uifd, &event, sizeof(struct input_event)) < 0)    {
+                            CALIBRATION_PRINT("%s: Event write error %d[%d]\n",
+                                              CALIBDAE_DEV_NAME, uifd, errno);
+                        }
+                        else    {
+                            CALIBRATION_DEBUG("EV_KEY=BTN_LEFT\n");
+                        }
+                        if (mEventLog == 2) {
+                            push_event(&event);
+                        }
+                    }
+                }
+#else  /*REPLACE_TOUCH_EVENT*/
+                ret = write(uifd, &event, sizeof(struct input_event));
+                if (mEventLog == 2) {
+                    push_event(&event);
+                }
+#endif /*REPLACE_TOUCH_EVENT*/
+            }
+        }
+    }
+    ioctl(evfd, EVIOCGRAB, 0);
+}
+
+static void
+push_eventlog(const char *event, const int value, struct timeval *tp)
+{
+    struct timeval  curtime;
+
+    gettimeofday(&curtime, NULL);
+
+    if (lastEvent.tv_sec)   {
+        int     sec, usec;
+
+        sec = curtime.tv_sec - lastEvent.tv_sec;
+        usec = curtime.tv_usec - lastEvent.tv_usec;
+
+        if (usec < 0)   {
+            sec -= 1;
+            usec += 1000000;
+        }
+        usec += 500;
+        if( usec >= 1000000 )   {
+            usec -= 1000000;
+            sec += 1;
+        }
+        if ((sec > 0) || ((sec == 0) && (usec >= 10000)))   {
+            printf("sleep %d.%03d\n", sec, usec / 1000);
+            lastEvent.tv_sec = curtime.tv_sec;
+            lastEvent.tv_usec = curtime.tv_usec;
+        }
+    }
+    else    {
+        lastEvent.tv_sec = curtime.tv_sec;
+        lastEvent.tv_usec = curtime.tv_usec;
+    }
+    printf("%s=%d\t# %d.%03d\n", event, value, (int)tp->tv_sec, (int)(tp->tv_usec/1000));
+    fflush(stdout);
+}
+
+static void
+push_event(struct input_event *ev)
+{
+    switch(ev->type)    {
+    case EV_ABS:
+        switch(ev->code)    {
+        case ABS_X:
+            push_eventlog("X", ev->value, &(ev->time));
+            break;
+        case ABS_Y:
+            push_eventlog("Y", ev->value, &(ev->time));
+            break;
+        default:
+            break;
+        }
+        break;
+    case EV_KEY:
+        switch(ev->code)    {
+        case BTN_TOUCH:
+            push_eventlog("Touch", ev->value, &(ev->time));
+            break;
+        case BTN_LEFT:
+            push_eventlog("Button", ev->value, &(ev->time));
+            break;
+        default:
+            break;
+        }
+        break;
+    default:
+        break;
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief       convert x/y coordinates
+ *
+ * @param[in]   in          input event
+ * @param[in]   out         output converted event
+ * @return      result
+ * @retval      -1          input event queued(no output)
+ * @retval      0           no input event
+ * @retval      1           event converted
+ */
+/*--------------------------------------------------------------------------*/
+static int
+calibration_event(struct input_event *in, struct input_event *out)
+{
+    int     ret = 0;
+#ifdef  REPLACE_TOUCH_EVENT
+    static int queue_touch = 0;
+#endif /*REPLACE_TOUCH_EVENT*/
+
+    memcpy(out, in, sizeof(struct input_event) );
+
+    switch (in->type) {
+    case EV_ABS:
+        /* absolute coordinate      */
+        switch (in->code) {
+            /* X/Y coordinate       */
+        case ABS_X:
+            out->value = mDispWidth * (in->value - mXlow) / (mXheigh - mXlow);
+            if (mRevX)  {
+                out->value = mDispWidth - out->value;
+            }
+            if (out->value < 0)             out->value = 0;
+            if (out->value >= mDispWidth)   out->value = mDispWidth - 1;
+
+            if (mTrans == 90)   {
+                out->code = ABS_Y;
+                out->value = mDispWidth - out->value - 1;
+            }
+            else if (mTrans == 180) {
+                out->value = mDispWidth - out->value - 1;
+            }
+            else if (mTrans == 270) {
+                out->code = ABS_Y;
+            }
+            if (mEventLog == 1) {
+                push_eventlog("X", in->value, &(in->time));
+            }
+#ifdef  REPLACE_TOUCH_EVENT
+            if (queue_touch & 1)    {
+                queue_touch &= ~1;
+                if (queue_touch == 0)   {
+                    ret = 1;
+                }
+            }
+#endif /*REPLACE_TOUCH_EVENT*/
+            CALIBRATION_DEBUG("ABS_X=%s %d=>%d\n",
+                              (out->code == ABS_X) ? "X" : "Y",
+                              in->value, out->value);
+            break;
+
+        case ABS_Y:
+            out->value = mDispHeight * (in->value - mYlow) / (mYheigh - mYlow);
+            if (mRevY)  {
+                out->value = mDispHeight - out->value;
+            }
+            if (out->value < 0)             out->value = 0;
+            if (out->value >= mDispHeight)  out->value = mDispHeight - 1;
+
+            if (mTrans == 90)   {
+                out->code = ABS_X;
+            }
+            else if (mTrans == 180) {
+                out->value = mDispHeight - out->value - 1;
+            }
+            else if (mTrans == 270) {
+                out->code = ABS_X;
+                out->value = mDispHeight - out->value - 1;
+            }
+            if (mEventLog == 1) {
+                push_eventlog("Y", in->value, &(in->time));
+            }
+#ifdef  REPLACE_TOUCH_EVENT
+            if (queue_touch & 2)    {
+                queue_touch &= ~2;
+                if (queue_touch == 0)   {
+                    ret = 1;
+                }
+            }
+#endif /*REPLACE_TOUCH_EVENT*/
+            CALIBRATION_DEBUG("ABS_Y=%s %d=>%d\n",
+                              (out->code == ABS_X) ? "X" : "Y",
+                              in->value, out->value);
+            break;
+
+        default:
+            CALIBRATION_DEBUG("calibration_event: Unknown code(0x%x)\n", (int)in->code);
+            break;
+        }
+        break;
+
+#ifdef  REPLACE_TOUCH_EVENT
+    case EV_KEY:
+        if (in->code == BTN_TOUCH)  {
+            if (mEventLog == 1) {
+                push_eventlog("Touch", in->value, &(in->time));
+            }
+            /* Touch event change to mouse left button event    */
+            out->code = BTN_LEFT;
+            if (out->value != 0)    {
+                queue_touch = 3;
+                ret = -1;
+                CALIBRATION_DEBUG("BTN_TOUCH=LEFT, queue(%d)\n", out->value);
+            }
+            else    {
+                ret = 0;
+                CALIBRATION_DEBUG("BTN_TOUCH=LEFT(%d)\n", out->value);
+            }
+        }
+        break;
+#endif /*REPLACE_TOUCH_EVENT*/
+
+    case EV_SYN:
+        CALIBRATION_DEBUG("calibration_event: SYN\n");
+        break;
+
+    default:
+        CALIBRATION_DEBUG("calibration_event: Unknown type(0x%x)\n", (int)in->type);
+        break;
+    }
+    if (out->value < 0) {
+        out->value = 0;
+    }
+
+    return ret;
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief       setup uinput device for event output
+ *
+ * @param[in]   uinputDeviceName        uinput device node name
+ * @return      uinput file descriptor
+ * @retval      >= 0    file descriptor
+ * @retval      < 0     error
+ */
+/*--------------------------------------------------------------------------*/
+static int
+setup_uinput(char *uinputDeviceName)
+{
+    int     uifd;
+    struct uinput_user_dev  uinputDevice;
+
+    uifd = open_uinput(uinputDeviceName);
+    if (uifd < 0)   {
+        perror("Open uinput");
+        return -1;
+    }
+
+    memset(&uinputDevice, 0, sizeof(uinputDevice));
+    strcpy(uinputDevice.name, CALIBDAE_DEV_NAME);
+    uinputDevice.absmax[ABS_X] = mDispWidth;
+    uinputDevice.absmax[ABS_Y] = mDispHeight;
+
+    /* uinput device configuration  */
+    if (write(uifd, &uinputDevice, sizeof(uinputDevice)) < (int)sizeof(uinputDevice)) {
+        perror("Regist uinput");
+        CALIBRATION_PRINT("setup_uinput: write(%d) Error[%d]\n", uifd, errno);
+        close(uifd);
+        return -1;
+    }
+
+    /* uinput set event bits        */
+    set_eventbit(uifd);
+
+    if (ioctl(uifd, UI_DEV_CREATE, NULL) < 0)   {
+        CALIBRATION_PRINT("setup_uinput: ioclt(%d,UI_DEV_CREATE,) Error[%d]\n", uifd, errno);
+    }
+    return uifd;
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief       event bit set
+ *
+ * @param[in]   uifd        uinput file descriptor
+ * @return      nothing
+ */
+/*--------------------------------------------------------------------------*/
+static void
+set_eventbit(int uifd)
+{
+    ioctl(uifd, UI_SET_EVBIT, EV_SYN);
+
+    ioctl(uifd, UI_SET_EVBIT, EV_ABS);
+    ioctl(uifd, UI_SET_ABSBIT, ABS_X);
+    ioctl(uifd, UI_SET_ABSBIT, ABS_Y);
+
+    ioctl(uifd, UI_SET_EVBIT, EV_KEY);
+#ifdef  REPLACE_TOUCH_EVENT
+    ioctl(uifd, UI_SET_KEYBIT, BTN_LEFT);
+#else  /*REPLACE_TOUCH_EVENT*/
+    ioctl(uifd, UI_SET_KEYBIT, BTN_TOUCH);
+    ioctl(uifd, UI_SET_KEYBIT, BTN_TOOL_PEN);
+#endif /*REPLACE_TOUCH_EVENT*/
+
+    ioctl(uifd, UI_SET_EVBIT, EV_MSC);
+    ioctl(uifd, UI_SET_MSCBIT, MSC_SCAN);
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief       open uinput device
+ *
+ * @param[in]   uinputDeviceName    uinput device name
+ * @return      uinput file descriptor
+ * @retval      >= 0        file descriptor
+ * @retval      < 0         error
+ */
+/*--------------------------------------------------------------------------*/
+static int
+open_uinput(char *uinputDeviceName)
+{
+    return open(uinputDeviceName, O_RDWR);
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief       close uinput device
+ *
+ * @param[in]   uifd        uinput file descriptor
+ * @return      nothing
+ */
+/*--------------------------------------------------------------------------*/
+static void
+close_uinput(int uifd)
+{
+    if (uifd >= 0) {
+        ioctl(uifd, UI_DEV_DESTROY, NULL);
+        close(uifd);
+        uifd = -1;
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief       print help message
+ *
+ * @param[in]   pName       program name
+ * @return      nothing
+ */
+/*--------------------------------------------------------------------------*/
+static void
+print_usage(const char *pName)
+{
+    fprintf(stderr, "Usage: %s [-h][-d][-t [rotate]] [device]\n", pName );
+}
+
diff --git a/touch_egalax/ico_ictl-touch_egalax.h b/touch_egalax/ico_ictl-touch_egalax.h
new file mode 100644 (file)
index 0000000..47af5d0
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
+ *
+ * This program is licensed under the terms and conditions of the
+ * Apache License, version 2.0.  The full text of the Apache License is at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ */
+/**
+ * @brief   Device Input Controller(cartouch Touchpanel)
+ *          Program common include file
+ *
+ * @date    Feb-20-2013
+ */
+
+#ifndef _ICO_ICTL_TOUCH_EGALAX_H_
+#define _ICO_ICTL_TOUCH_EGALAX_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <linux/input.h>
+#include <linux/uinput.h>
+
+/* Default screen size      */
+#define CALIBRATION_DISP_WIDTH     1920
+#define CALIBRATION_DISP_HEIGHT    1080
+
+/* Configuration file       */
+#define CALIBRATOIN_CONF_LEN_MAX    128
+#define CALIBRATOIN_CONF_ENV        "CALIBRATOIN_CONF"
+#define CALIBRATOIN_INPUT_DEV       "ICTL_TOUCH_DEV"
+#define CALIBRATOIN_CONF_FILE   \
+                        "/opt/etc/ico-uxf-device-input-controller/egalax_calibration.conf"
+
+/* Configuration items      */
+#define CALIBRATOIN_STR_SEPAR       "=*"            /* Delimitor                */
+#define CALIBRATOIN_STR_DISP_W      "DWIDTH"        /* Screen width             */
+#define CALIBRATOIN_STR_DISP_H      "DHEIGHT"       /* Scneen height            */
+#define CALIBRATOIN_STR_POS1        "POSITION1"     /* Top-Left position        */
+#define CALIBRATOIN_STR_POS2        "POSITION2"     /* Top-Right position       */
+#define CALIBRATOIN_STR_POS3        "POSITION3"     /* Bottom-Left position     */
+#define CALIBRATOIN_STR_POS4        "POSITION4"     /* Bottom-Right position    */
+
+/* Error retry              */
+#define CALIBRATOIN_RETRY_COUNT     10              /* number of error retry    */
+#define CALIBRATOIN_RETRY_WAIT      10              /* wait time(ms) for retry  */
+
+/* Debug macros             */
+#define CALIBRATION_DEBUG(fmt, ...) {if (mDebug) {fprintf(stdout, "%s:%d "fmt, __func__, __LINE__, ##__VA_ARGS__); fflush(stdout);}}
+#define CALIBRATION_INFO(fmt, ...)  {if (mDebug) {fprintf(stdout, "%s:%d "fmt, __func__, __LINE__, ##__VA_ARGS__); fflush(stdout);}}
+#define CALIBRATION_PRINT(...)       {fprintf(stdout, ##__VA_ARGS__); fflush(stdout);}
+
+#endif /*_ICO_ICTL_TOUCH_EGALAX_H_*/
+