summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShibata Makoto <shibata@mac.tec.toyota.co.jp>2013-04-26 20:39:06 +0900
committerShibata Makoto <shibata@mac.tec.toyota.co.jp>2013-04-26 20:39:41 +0900
commit0f80d0012c6f40ebb02622e058911e9d581bc4f2 (patch)
treeb184a9305d983642adfdc4855a49d714541033b9
downloadico-uxf-device-input-controller-0f80d0012c6f40ebb02622e058911e9d581bc4f2.tar.gz
ico-uxf-device-input-controller-0f80d0012c6f40ebb02622e058911e9d581bc4f2.tar.bz2
ico-uxf-device-input-controller-0f80d0012c6f40ebb02622e058911e9d581bc4f2.zip
Updated package changelog.
Change-Id: I24b2c18efcc223a2abea06b317f0b54c976841d9 Signed-off-by: Shibata Makoto <shibata@mac.tec.toyota.co.jp>
-rw-r--r--Makefile.am6
-rwxr-xr-xautogen.sh9
-rw-r--r--configure.ac57
-rw-r--r--egalax_calibration.conf6
-rw-r--r--joystick_gtforce.conf59
-rw-r--r--joystick_gtforce/Makefile.am26
-rw-r--r--joystick_gtforce/dbg_curtime.c55
-rw-r--r--joystick_gtforce/ico_ictl-joystick.c658
-rw-r--r--joystick_gtforce/ico_ictl-local.h91
-rw-r--r--joystick_gtforce/ico_ictl-wayland.c227
-rw-r--r--packaging/ico-uxf-device-input-controller.changes3
-rw-r--r--packaging/ico-uxf-device-input-controller.spec50
-rw-r--r--tests/Makefile.am35
-rwxr-xr-xtests/input-controller-test85
-rw-r--r--tests/test-client.c634
-rw-r--r--tests/test-common.c411
-rw-r--r--tests/test-common.h38
-rw-r--r--tests/test-homescreen.c1464
-rw-r--r--tests/test-send_event.c514
-rw-r--r--tests/testdata/cl_surface3.dat7
-rw-r--r--tests/testdata/hs_alltest.dat118
-rw-r--r--tests/weston.ini24
-rw-r--r--tests/weston_ivi_plugin.ini18
-rw-r--r--touch_egalax/Makefile.am24
-rw-r--r--touch_egalax/ico_ictl-egalax_calibration.c467
-rw-r--r--touch_egalax/ico_ictl-touch_egalax.c850
-rw-r--r--touch_egalax/ico_ictl-touch_egalax.h64
27 files changed, 6000 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..a5ec0c8
--- /dev/null
+++ b/Makefile.am
@@ -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
index 0000000..916169a
--- /dev/null
+++ b/autogen.sh
@@ -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
index 0000000..61e9d3b
--- /dev/null
+++ b/configure.ac
@@ -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
index 0000000..7fe61e2
--- /dev/null
+++ b/egalax_calibration.conf
@@ -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
index 0000000..9537ad1
--- /dev/null
+++ b/joystick_gtforce.conf
@@ -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
index 0000000..6f3f8ed
--- /dev/null
+++ b/joystick_gtforce/Makefile.am
@@ -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
index 0000000..23063fb
--- /dev/null
+++ b/joystick_gtforce/dbg_curtime.c
@@ -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
index 0000000..3e10160
--- /dev/null
+++ b/joystick_gtforce/ico_ictl-joystick.c
@@ -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
index 0000000..cc6265b
--- /dev/null
+++ b/joystick_gtforce/ico_ictl-local.h
@@ -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
index 0000000..9665f2c
--- /dev/null
+++ b/joystick_gtforce/ico_ictl-wayland.c
@@ -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
index 0000000..35ba624
--- /dev/null
+++ b/packaging/ico-uxf-device-input-controller.changes
@@ -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
index 0000000..c125e30
--- /dev/null
+++ b/packaging/ico-uxf-device-input-controller.spec
@@ -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
index 0000000..eee4ee5
--- /dev/null
+++ b/tests/Makefile.am
@@ -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
index 0000000..218335c
--- /dev/null
+++ b/tests/input-controller-test
@@ -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
index 0000000..f6b877e
--- /dev/null
+++ b/tests/test-client.c
@@ -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
index 0000000..5b83995
--- /dev/null
+++ b/tests/test-common.c
@@ -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
index 0000000..a17e3ad
--- /dev/null
+++ b/tests/test-common.h
@@ -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
index 0000000..9b7fc68
--- /dev/null
+++ b/tests/test-homescreen.c
@@ -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
index 0000000..9165aa3
--- /dev/null
+++ b/tests/test-send_event.c
@@ -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
index 0000000..fcd10cb
--- /dev/null
+++ b/tests/testdata/cl_surface3.dat
@@ -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
index 0000000..7f14582
--- /dev/null
+++ b/tests/testdata/hs_alltest.dat
@@ -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
index 0000000..5be1667
--- /dev/null
+++ b/tests/weston.ini
@@ -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
index 0000000..89798d3
--- /dev/null
+++ b/tests/weston_ivi_plugin.ini
@@ -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
index 0000000..ea6be86
--- /dev/null
+++ b/touch_egalax/Makefile.am
@@ -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
index 0000000..731ccca
--- /dev/null
+++ b/touch_egalax/ico_ictl-egalax_calibration.c
@@ -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
index 0000000..937ad4b
--- /dev/null
+++ b/touch_egalax/ico_ictl-touch_egalax.c
@@ -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
index 0000000..47af5d0
--- /dev/null
+++ b/touch_egalax/ico_ictl-touch_egalax.h
@@ -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_*/
+