#### End of Ecore_File
+#### Eeze
+have_libmount_new="no"
+have_libmount_old="no"
+have_eeze_mount="no"
+
+EFL_LIB_START_OPTIONAL([Eeze], [test "x${build_libeeze}" = "xyes"])
+
+### Additional options to configure
+AC_ARG_WITH([mount],
+ [AS_HELP_STRING([--with-mount], [specify mount bin @<:@default=detect@:>@])],
+ [with_eeze_mount=$withval], [with_eeze_mount="detect"])
+AC_ARG_WITH([umount],
+ [AS_HELP_STRING([--with-umount], [specify umount bin @<:@default=detect@:>@])],
+ [with_eeze_umount=$withval], [with_eeze_umount="detect"])
+AC_ARG_WITH([eject],
+ [AS_HELP_STRING([--with-eject], [specify eject bin @<:@default=detect@:>@])],
+ [with_eeze_eject=$withval], [with_eeze_eject="detect"])
+
+### Default values
+
+### Checks for programs
+
+### Checks for libraries
+EFL_INTERNAL_DEPEND_PKG([EEZE], [eina])
+EFL_INTERNAL_DEPEND_PKG([EEZE], [ecore])
+EFL_INTERNAL_DEPEND_PKG([EEZE], [eo])
+EFL_INTERNAL_DEPEND_PKG([EEZE], [ecore-file])
+EFL_INTERNAL_DEPEND_PKG([EEZE], [ecore-con])
+EFL_INTERNAL_DEPEND_PKG([EEZE], [eet])
+EFL_INTERNAL_DEPEND_PKG([EEZE], [emile])
+
+EFL_DEPEND_PKG([EEZE], [UDEV], [libudev >= 148])
+
+AC_ARG_ENABLE([libmount],
+ [AS_HELP_STRING([--disable-libmount],[disable libmount support. @<:@default=enabled@:>@])],
+ [
+ if test "x${enableval}" = "xyes" ; then
+ want_libmount="yes"
+ else
+ want_libmount="no"
+ CFOPT_WARNING="xyes"
+ fi
+ ],
+ [want_libmount="yes"])
+
+EFL_OPTIONAL_DEPEND_PKG([EEZE], [${want_libmount}],
+ [EEZE_MOUNT], [mount >= 2.18.0])
+EFL_ADD_FEATURE([EEZE], [libmount], [${have_eeze_mount}])
+
+PKG_CHECK_EXISTS([libudev < 199],
+ [have_libudev_old="yes"],
+ [have_libudev_old="no"])
+AC_MSG_CHECKING([Use old libudev API (before 199)])
+AC_MSG_RESULT([${have_libudev_old}])
+
+PKG_CHECK_EXISTS([mount < 2.19.0],
+ [have_libmount_old="yes"],
+ [have_libmount_old="no"])
+AC_MSG_CHECKING([Use old libmount API (before 2.19.0)])
+AC_MSG_RESULT([${have_libmount_old}])
+
+PKG_CHECK_EXISTS([mount == 2.19.0],
+ [have_libmount_219="yes"],
+ [have_libmount_219="no"])
+AC_MSG_CHECKING([Use libmount 2.19.0 API])
+AC_MSG_RESULT([${have_libmount_219}])
+
+PKG_CHECK_EXISTS([mount > 2.19.0],
+ [have_libmount_new="yes"],
+ [have_libmount_new="no"])
+AC_MSG_CHECKING([Use new libmount API (newer than 2.19.0)])
+AC_MSG_RESULT([${have_libmount_new}])
+
+if test "x${have_libudev_old}" = "xyes"; then
+ AC_DEFINE_UNQUOTED([OLD_LIBUDEV], [1], [using older version of libudev])
+fi
+
+if test "x${have_libmount_old}" = "xyes"; then
+ AC_DEFINE_UNQUOTED([OLD_LIBMOUNT], [1], [using first version of libmount])
+fi
+
+## modules
+if test "${want_tizen}" = "yes"; then
+ PKG_CHECK_MODULES([TIZEN_SENSOR], [capi-system-sensor >= 0.1.17])
+fi
+EFL_ADD_FEATURE([EEZE], [tizen])
+
+EFL_EVAL_PKGS([EEZE])
+
+### Checks for header files
+
+### Checks for types
+
+### Checks for structures
+
+### Checks for compiler characteristics
+
+### Checks for linker characteristics
+
+### Checks for library functions
+
+### Checks for binaries
+if test "x$with_eeze_mount" = "xdetect"; then
+ AC_PATH_PROG([with_eeze_mount], [mount], [])
+fi
+AC_DEFINE_UNQUOTED([EEZE_MOUNT_BIN], ["$with_eeze_mount"], [mount bin to use])
+
+if test "x$with_eeze_umount" = "xdetect";then
+ AC_PATH_PROG([with_eeze_umount], [umount], [])
+fi
+AC_DEFINE_UNQUOTED([EEZE_UNMOUNT_BIN], ["$with_eeze_umount"], [umount bin to use])
+
+if test "x$with_eeze_eject" = "xdetect";then
+ AC_PATH_PROG([with_eeze_eject], [eject], [])
+fi
+AC_DEFINE_UNQUOTED([EEZE_EJECT_BIN], ["$with_eeze_eject"], [eject bin to use])
+
+EFL_LIB_END_OPTIONAL([Eeze])
+
+AM_CONDITIONAL([EEZE_LIBMOUNT_AFTER_219],
+ [test "x${have_libmount_new}" = "xyes"])
+AM_CONDITIONAL([EEZE_LIBMOUNT_BEFORE_219],
+ [test "x${have_libmount_old}" = "xyes"])
+AM_CONDITIONAL([HAVE_EEZE_MOUNT], [test "x${have_eeze_mount}" = "xyes"])
+AM_CONDITIONAL([HAVE_EEZE_TIZEN], [test "x${want_tizen}" = "xyes"])
+#### End of Eeze
+
+
#### Ecore_Input
EFL_LIB_START([Ecore_Input])
EFL_INTERNAL_DEPEND_PKG([ECORE_INPUT], [eo])
EFL_INTERNAL_DEPEND_PKG([ECORE_INPUT], [eina])
+EFL_OPTIONAL_INTERNAL_DEPEND_PKG([ECORE_INPUT], [${efl_lib_optional_eeze}], [eeze])
+
### Checks for header files
### Checks for types
#### End of Eldbus
-#### Eeze
-have_libmount_new="no"
-have_libmount_old="no"
-have_eeze_mount="no"
-
-EFL_LIB_START_OPTIONAL([Eeze], [test "x${build_libeeze}" = "xyes"])
-
-### Additional options to configure
-AC_ARG_WITH([mount],
- [AS_HELP_STRING([--with-mount], [specify mount bin @<:@default=detect@:>@])],
- [with_eeze_mount=$withval], [with_eeze_mount="detect"])
-AC_ARG_WITH([umount],
- [AS_HELP_STRING([--with-umount], [specify umount bin @<:@default=detect@:>@])],
- [with_eeze_umount=$withval], [with_eeze_umount="detect"])
-AC_ARG_WITH([eject],
- [AS_HELP_STRING([--with-eject], [specify eject bin @<:@default=detect@:>@])],
- [with_eeze_eject=$withval], [with_eeze_eject="detect"])
-
-### Default values
-
-### Checks for programs
-
-### Checks for libraries
-EFL_INTERNAL_DEPEND_PKG([EEZE], [eina])
-EFL_INTERNAL_DEPEND_PKG([EEZE], [ecore])
-EFL_INTERNAL_DEPEND_PKG([EEZE], [eo])
-EFL_INTERNAL_DEPEND_PKG([EEZE], [ecore-file])
-EFL_INTERNAL_DEPEND_PKG([EEZE], [ecore-con])
-EFL_INTERNAL_DEPEND_PKG([EEZE], [eet])
-EFL_INTERNAL_DEPEND_PKG([EEZE], [emile])
-
-EFL_DEPEND_PKG([EEZE], [UDEV], [libudev >= 148])
-
-AC_ARG_ENABLE([libmount],
- [AS_HELP_STRING([--disable-libmount],[disable libmount support. @<:@default=enabled@:>@])],
- [
- if test "x${enableval}" = "xyes" ; then
- want_libmount="yes"
- else
- want_libmount="no"
- CFOPT_WARNING="xyes"
- fi
- ],
- [want_libmount="yes"])
-
-EFL_OPTIONAL_DEPEND_PKG([EEZE], [${want_libmount}],
- [EEZE_MOUNT], [mount >= 2.18.0])
-EFL_ADD_FEATURE([EEZE], [libmount], [${have_eeze_mount}])
-
-PKG_CHECK_EXISTS([libudev < 199],
- [have_libudev_old="yes"],
- [have_libudev_old="no"])
-AC_MSG_CHECKING([Use old libudev API (before 199)])
-AC_MSG_RESULT([${have_libudev_old}])
-
-PKG_CHECK_EXISTS([mount < 2.19.0],
- [have_libmount_old="yes"],
- [have_libmount_old="no"])
-AC_MSG_CHECKING([Use old libmount API (before 2.19.0)])
-AC_MSG_RESULT([${have_libmount_old}])
-
-PKG_CHECK_EXISTS([mount == 2.19.0],
- [have_libmount_219="yes"],
- [have_libmount_219="no"])
-AC_MSG_CHECKING([Use libmount 2.19.0 API])
-AC_MSG_RESULT([${have_libmount_219}])
-
-PKG_CHECK_EXISTS([mount > 2.19.0],
- [have_libmount_new="yes"],
- [have_libmount_new="no"])
-AC_MSG_CHECKING([Use new libmount API (newer than 2.19.0)])
-AC_MSG_RESULT([${have_libmount_new}])
-
-if test "x${have_libudev_old}" = "xyes"; then
- AC_DEFINE_UNQUOTED([OLD_LIBUDEV], [1], [using older version of libudev])
-fi
-
-if test "x${have_libmount_old}" = "xyes"; then
- AC_DEFINE_UNQUOTED([OLD_LIBMOUNT], [1], [using first version of libmount])
-fi
-
-## modules
-if test "${want_tizen}" = "yes"; then
- PKG_CHECK_MODULES([TIZEN_SENSOR], [capi-system-sensor >= 0.1.17])
-fi
-EFL_ADD_FEATURE([EEZE], [tizen])
-
-EFL_EVAL_PKGS([EEZE])
-
-### Checks for header files
-
-### Checks for types
-
-### Checks for structures
-
-### Checks for compiler characteristics
-
-### Checks for linker characteristics
-
-### Checks for library functions
-
-### Checks for binaries
-if test "x$with_eeze_mount" = "xdetect"; then
- AC_PATH_PROG([with_eeze_mount], [mount], [])
-fi
-AC_DEFINE_UNQUOTED([EEZE_MOUNT_BIN], ["$with_eeze_mount"], [mount bin to use])
-
-if test "x$with_eeze_umount" = "xdetect";then
- AC_PATH_PROG([with_eeze_umount], [umount], [])
-fi
-AC_DEFINE_UNQUOTED([EEZE_UNMOUNT_BIN], ["$with_eeze_umount"], [umount bin to use])
-
-if test "x$with_eeze_eject" = "xdetect";then
- AC_PATH_PROG([with_eeze_eject], [eject], [])
-fi
-AC_DEFINE_UNQUOTED([EEZE_EJECT_BIN], ["$with_eeze_eject"], [eject bin to use])
-
-EFL_LIB_END_OPTIONAL([Eeze])
-
-AM_CONDITIONAL([EEZE_LIBMOUNT_AFTER_219],
- [test "x${have_libmount_new}" = "xyes"])
-AM_CONDITIONAL([EEZE_LIBMOUNT_BEFORE_219],
- [test "x${have_libmount_old}" = "xyes"])
-AM_CONDITIONAL([HAVE_EEZE_MOUNT], [test "x${have_eeze_mount}" = "xyes"])
-AM_CONDITIONAL([HAVE_EEZE_TIZEN], [test "x${want_tizen}" = "xyes"])
-#### End of Eeze
-
-
#### Ecore_Drm
have_libinput_new="no"
EFL_LIB_START_OPTIONAL([Ecore_Drm], [test "${want_drm}" = "yes"])
lib_ecore_input_libecore_input_la_SOURCES = \
lib/ecore_input/ecore_input.c \
lib/ecore_input/ecore_input_compose.c \
+lib/ecore_input/ecore_input_joystick.c \
lib/ecore_input/ecore_input_compose.h \
lib/ecore_input/ecore_input_private.h
--- /dev/null
+//Compile with:
+// gcc -g -Wall -o ecore_input_joystick_example ecore_input_joystick_example.c `pkg-config --cflags --libs ecore ecore-input`
+
+#include <Ecore.h>
+#include <Ecore_Input.h>
+
+static Eina_Bool
+_joystick_event_handler_cb(void *data, int type EINA_UNUSED, void *event)
+{
+ Ecore_Event_Joystick *ev = event;
+ switch (ev->type)
+ {
+ case ECORE_EVENT_JOYSTICK_EVENT_TYPE_CONNECTED:
+ printf("joystick is connected: %d\n", ev->index);
+ break;
+ case ECORE_EVENT_JOYSTICK_EVENT_TYPE_DISCONNECTED:
+ printf("joystick is disconnected: %d\n", ev->index);
+ break;
+ case ECORE_EVENT_JOYSTICK_EVENT_TYPE_BUTTON:
+ printf("joystick(%d) button index: %d, value: %f, time: %u\n",
+ ev->index, ev->button.index,
+ ev->button.value, ev->timestamp);
+ break;
+ case ECORE_EVENT_JOYSTICK_EVENT_TYPE_AXIS:
+ printf("joystick(%d) axis index: %d, value: %f, time: %u\n",
+ ev->index, ev->axis.index,
+ ev->axis.value, ev->timestamp);
+ break;
+ default:
+ printf("unhandled event type: %d\n", ev->type);
+ break;
+ }
+
+ if (ev->type == ECORE_EVENT_JOYSTICK_EVENT_TYPE_BUTTON &&
+ ev->button.index == ECORE_EVENT_JOYSTICK_BUTTON_START)
+ ecore_main_loop_quit();
+
+ return ECORE_CALLBACK_DONE;
+}
+
+int
+main(void)
+{
+ if (!ecore_event_init())
+ {
+ printf("ERROR: Cannot init Ecore!\n");
+ return -1;
+ }
+
+ ecore_event_handler_add(ECORE_EVENT_JOYSTICK,
+ _joystick_event_handler_cb,
+ NULL);
+
+ printf("start the main loop.\n");
+
+ ecore_main_loop_begin();
+
+ ecore_shutdown();
+
+ return 0;
+}
EAPI extern int ECORE_EVENT_DEVICE_ADD;
EAPI extern int ECORE_EVENT_DEVICE_DEL;
EAPI extern int ECORE_EVENT_DETENT_ROTATE; //TIZEN ONLY
+ EAPI extern int ECORE_EVENT_JOYSTICK; /**< @since 1.18 */
#define ECORE_EVENT_MODIFIER_SHIFT 0x0001
#define ECORE_EVENT_MODIFIER_CTRL 0x0002
typedef struct _Ecore_Axis Ecore_Axis; /**< @since 1.13 */
typedef struct _Ecore_Event_Device_Info Ecore_Event_Device_Info;
typedef struct _Ecore_Event_Detent_Rotate Ecore_Event_Detent_Rotate; //TIZEN ONLY
+ typedef struct _Ecore_Event_Joystick Ecore_Event_Joystick; /**< @since 1.18 */
/**
* @typedef Ecore_Event_Modifier
};
/**
+ * @struct _Ecore_Event_Joystic_Button
+ * Contains information about a joystick button event.
+ */
+ typedef enum _Ecore_Event_Joystick_Button
+ {
+ ECORE_EVENT_JOYSTICK_BUTTON_NONE,
+ ECORE_EVENT_JOYSTICK_BUTTON_FACE_0,
+ ECORE_EVENT_JOYSTICK_BUTTON_FACE_1,
+ ECORE_EVENT_JOYSTICK_BUTTON_FACE_2,
+ ECORE_EVENT_JOYSTICK_BUTTON_FACE_3,
+ ECORE_EVENT_JOYSTICK_BUTTON_LEFT_SHOULDER,
+ ECORE_EVENT_JOYSTICK_BUTTON_RIGHT_SHOULDER,
+ ECORE_EVENT_JOYSTICK_BUTTON_SELECT,
+ ECORE_EVENT_JOYSTICK_BUTTON_START,
+ ECORE_EVENT_JOYSTICK_BUTTON_LEFT_ANALOG_STICK,
+ ECORE_EVENT_JOYSTICK_BUTTON_RIGHT_ANALOG_STICK,
+ ECORE_EVENT_JOYSTICK_BUTTON_META,
+ ECORE_EVENT_JOYSTICK_BUTTON_LAST
+ } Ecore_Event_Joystick_Button; /**< @since 1.18 */
+
+ /**
+ * @struct _Ecore_Event_Joystic_Axis
+ * Contains information about a joystick axis event.
+ */
+ typedef enum _Ecore_Event_Joystick_Axis
+ {
+ ECORE_EVENT_JOYSTICK_AXIS_NONE,
+ ECORE_EVENT_JOYSTICK_AXIS_HAT_X,
+ ECORE_EVENT_JOYSTICK_AXIS_HAT_Y,
+ ECORE_EVENT_JOYSTICK_AXIS_LEFT_SHOULDER,
+ ECORE_EVENT_JOYSTICK_AXIS_RIGHT_SHOULDER,
+ ECORE_EVENT_JOYSTICK_AXIS_LEFT_ANALOG_HOR,
+ ECORE_EVENT_JOYSTICK_AXIS_LEFT_ANALOG_VER,
+ ECORE_EVENT_JOYSTICK_AXIS_RIGHT_ANALOG_HOR,
+ ECORE_EVENT_JOYSTICK_AXIS_RIGHT_ANALOG_VER,
+ ECORE_EVENT_JOYSTICK_AXIS_LAST
+ } Ecore_Event_Joystick_Axis; /**< @since 1.18 */
+
+ /**
+ * @struct _Ecore_Event_Joystic_Event_Type
+ * Contains information about a joystick event type.
+ */
+ typedef enum _Ecore_Event_Joystick_Event
+ {
+ ECORE_EVENT_JOYSTICK_EVENT_TYPE_NONE,
+ ECORE_EVENT_JOYSTICK_EVENT_TYPE_CONNECTED,
+ ECORE_EVENT_JOYSTICK_EVENT_TYPE_DISCONNECTED,
+ ECORE_EVENT_JOYSTICK_EVENT_TYPE_BUTTON,
+ ECORE_EVENT_JOYSTICK_EVENT_TYPE_AXIS,
+ ECORE_EVENT_JOYSTICK_EVENT_TYPE_LAST
+ } Ecore_Event_Joystick_Event_Type; /**< @since 1.18 */
+
+ /**
* @struct _Ecore_Event_Key
* Contains information about an Ecore keyboard event.
*/
};
/**
- * Initializes the Ecore Event system.
+ * @struct _Ecore_Event_Joystick
+ * Contains information about a joystick event.
+ */
+ struct _Ecore_Event_Joystick
+ {
+ Ecore_Event_Joystick_Event_Type type;
+ unsigned int index;
+ unsigned int timestamp;
+
+ union
+ {
+ struct
+ {
+ Ecore_Event_Joystick_Axis index;
+ double value; /* [-1.0 .. 1.0] -1.0 == up or left, 1.0 == down or right */
+ } axis;
+
+ struct
+ {
+ Ecore_Event_Joystick_Button index;
+ double value; /* [0.0 .. 1.0] 0.0 == fully unpressed, 1.0 == fully pressed */
+ } button;
+ };
+ };
+
+ /**
+ * Initialises the Ecore Event system.
*
* @if MOBILE @since_tizen 2.4
* @elseif WEARABLE @since_tizen 3.0
* @endif
+ * @struct _Ecore_Event_Joystick
*/
EAPI int ecore_event_init(void);
/**
EAPI int ECORE_EVENT_DEVICE_ADD = 0;
EAPI int ECORE_EVENT_DEVICE_DEL = 0;
EAPI int ECORE_EVENT_DETENT_ROTATE = 0; //TIZEN ONLY
+EAPI int ECORE_EVENT_JOYSTICK = 0;
static int _ecore_event_init_count = 0;
ECORE_EVENT_DEVICE_ADD = ecore_event_type_new();
ECORE_EVENT_DEVICE_DEL = ecore_event_type_new();
ECORE_EVENT_DETENT_ROTATE = ecore_event_type_new(); //TIZEN ONLY
+ ECORE_EVENT_JOYSTICK = ecore_event_type_new();
+
+ ecore_input_joystick_init();
return _ecore_event_init_count;
}
ECORE_EVENT_DEVICE_ADD = 0;
ECORE_EVENT_DEVICE_DEL = 0;
ECORE_EVENT_DETENT_ROTATE = 0; //TIZEN ONLY
+ ECORE_EVENT_JOYSTICK = 0;
+ ecore_input_joystick_shutdown();
eina_log_domain_unregister(_ecore_input_log_dom);
_ecore_input_log_dom = -1;
ecore_shutdown();
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+/*FIXME: change OS specific value */
+#ifdef __linux__
+# include <linux/joystick.h>
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#ifdef HAVE_EEZE
+ #include "Eeze.h"
+#endif
+#include "Ecore.h"
+#include "Ecore_Input.h"
+#include "ecore_input_private.h"
+
+static int _ecore_input_joystick_init_count = 0;
+
+#ifdef HAVE_EEZE
+
+typedef void (*Joystick_Mapper)(struct js_event *event, Ecore_Event_Joystick *e);
+static void _joystick_xiinput_mapper(struct js_event *event, Ecore_Event_Joystick *e);
+
+struct _Joystick_Info
+{
+ Ecore_Fd_Handler *fd_handler;
+ Eina_Stringshare *system_path;
+ int index;
+ Joystick_Mapper mapper;
+};
+typedef struct _Joystick_Info Joystick_Info;
+
+struct _Joystick_Mapping_Info
+{
+ const char *vendor;
+ const char *product;
+ Joystick_Mapper mapper;
+} Joystick_Mapping_Info[] = {{"045e", "028e", _joystick_xiinput_mapper}};
+
+static const char joystickPrefix[] = "/dev/input/js";
+static Eina_List *joystick_list;
+static Eeze_Udev_Watch *watch = NULL;
+
+static void
+_joystick_connected_event_add(int index, Eina_Bool connected)
+{
+ Ecore_Event_Joystick *e;
+ if (!(e = calloc(1, sizeof(Ecore_Event_Joystick)))) return;
+
+ e->index = index;
+ if (connected)
+ e->type = ECORE_EVENT_JOYSTICK_EVENT_TYPE_CONNECTED;
+ else
+ e->type = ECORE_EVENT_JOYSTICK_EVENT_TYPE_DISCONNECTED;
+
+ INF("index: %d, connected: %d", index, connected);
+ ecore_event_add(ECORE_EVENT_JOYSTICK, e, NULL, NULL);
+}
+
+static void
+_joystick_xiinput_mapper(struct js_event *event, Ecore_Event_Joystick *e)
+{
+ if (event->type == JS_EVENT_BUTTON)
+ {
+ e->type = ECORE_EVENT_JOYSTICK_EVENT_TYPE_BUTTON;
+ e->button.value = event->value;
+ switch (event->number)
+ {
+ case 0:
+ e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_FACE_0;
+ break;
+
+ case 1:
+ e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_FACE_1;
+ break;
+
+ case 2:
+ e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_FACE_2;
+ break;
+
+ case 3:
+ e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_FACE_3;
+ break;
+
+ case 4:
+ e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_LEFT_SHOULDER;
+ break;
+
+ case 5:
+ e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_RIGHT_SHOULDER;
+ break;
+
+ case 6:
+ e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_SELECT;
+ break;
+
+ case 7:
+ e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_START;
+ break;
+
+ case 8:
+ e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_META;
+ break;
+
+ case 9:
+ e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_LEFT_ANALOG_STICK;
+ break;
+
+ case 10:
+ e->button.index = ECORE_EVENT_JOYSTICK_BUTTON_RIGHT_ANALOG_STICK;
+ break;
+
+ default:
+ ERR("Unsupported joystick event: %d", event->number);
+ break;
+ }
+ }
+ else
+ {
+ e->type = ECORE_EVENT_JOYSTICK_EVENT_TYPE_AXIS;
+ e->axis.value = event->value / 32767.0f;;
+ switch (event->number)
+ {
+ case 0:
+ e->axis.index = ECORE_EVENT_JOYSTICK_AXIS_LEFT_ANALOG_HOR;
+ break;
+
+ case 1:
+ e->axis.index = ECORE_EVENT_JOYSTICK_AXIS_LEFT_ANALOG_VER;
+ break;
+
+ case 2:
+ e->axis.index = ECORE_EVENT_JOYSTICK_AXIS_LEFT_SHOULDER;
+ break;
+
+ case 3:
+ e->axis.index = ECORE_EVENT_JOYSTICK_AXIS_RIGHT_ANALOG_HOR;
+ break;
+
+ case 4:
+ e->axis.index = ECORE_EVENT_JOYSTICK_AXIS_RIGHT_ANALOG_VER;
+ break;
+
+ case 5:
+ e->axis.index = ECORE_EVENT_JOYSTICK_AXIS_RIGHT_SHOULDER;
+ break;
+
+ case 6:
+ e->axis.index = ECORE_EVENT_JOYSTICK_AXIS_HAT_X;
+ break;
+
+ case 7:
+ e->axis.index = ECORE_EVENT_JOYSTICK_AXIS_HAT_Y;
+ break;
+
+ default:
+ ERR("Unsupported joystick event: %d", event->number);
+ break;
+ }
+ }
+}
+
+static void
+_joystick_event_add(struct js_event *event, Joystick_Info *ji)
+{
+ Ecore_Event_Joystick *e;
+
+ if ((event->type != JS_EVENT_BUTTON) && (event->type != JS_EVENT_AXIS)) return;
+ if (!(e = calloc(1, sizeof(Ecore_Event_Joystick)))) return;
+
+ e->index = ji->index;
+ e->timestamp = event->time;
+
+ ji->mapper(event, e);
+
+ ecore_event_add(ECORE_EVENT_JOYSTICK, e, NULL, NULL);
+}
+
+static Eina_Bool
+_fd_handler_cb(void* userData, Ecore_Fd_Handler* fdHandler)
+{
+ int fd;
+ Joystick_Info *ji = userData;
+ struct js_event event;
+ ssize_t len;
+
+ fd = ecore_main_fd_handler_fd_get(fdHandler);
+
+ len = read(fd, &event, sizeof(event));
+ if (len == -1) return ECORE_CALLBACK_RENEW;
+
+ INF("index: %d, type: %d, number: %d, value: %d",
+ ji->index, event.type, event.number, event.value);
+
+ _joystick_event_add(&event, ji);
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+static Joystick_Mapper
+_joystick_mapping_info_get(const char* syspath)
+{
+ int index, mapping_info_size;
+ const char *parent, *vendor, *product;
+ Joystick_Mapper ret;
+
+ ret = NULL;
+ parent = eeze_udev_syspath_get_parent_filtered(syspath, "input", NULL);
+ vendor = eeze_udev_syspath_get_sysattr(parent, "id/vendor");
+ product = eeze_udev_syspath_get_sysattr(parent, "id/product");
+
+ mapping_info_size = (int)(sizeof(Joystick_Mapping_Info) / sizeof(Joystick_Mapping_Info[0]));
+ for (index = 0; index < mapping_info_size; index++)
+ {
+ if ((vendor && !strcmp(vendor, Joystick_Mapping_Info[index].vendor)) &&
+ (product && !strcmp(product, Joystick_Mapping_Info[index].product)))
+ {
+ INF("joystick mapping info found (vendor: %s, product: %s)", vendor, product);
+ ret = Joystick_Mapping_Info[index].mapper;
+ break;
+ }
+ }
+
+ eina_stringshare_del(parent);
+ eina_stringshare_del(vendor);
+ eina_stringshare_del(product);
+
+ return ret;
+}
+
+static int
+_joystick_index_get(const char *dev)
+{
+ int plen, dlen, diff, ret = -1;
+
+ dlen = strlen(dev);
+ plen = strlen(joystickPrefix);
+ diff = dlen - plen;
+
+ if (diff > 0)
+ {
+ ret = atoi(dev + plen);
+ }
+
+ return ret;
+}
+
+static void
+_joystick_register(const char* syspath)
+{
+ int fd, index;
+ const char *devnode;
+ Joystick_Info *ji;
+ Joystick_Mapper mapper;
+
+ devnode = eeze_udev_syspath_get_devpath(syspath);
+ if (!devnode) return;
+ if (!eina_str_has_prefix(devnode, joystickPrefix)) goto register_failed;
+
+ mapper = _joystick_mapping_info_get(syspath);
+ if (!mapper)
+ {
+ ERR("Unsupported joystick.");
+ goto register_failed;
+ }
+
+ index = _joystick_index_get(devnode);
+ if (index == -1)
+ {
+ ERR("Invalid index value.");
+ goto register_failed;
+ }
+
+ ji = calloc(1, sizeof(Joystick_Info));
+ if (!ji)
+ {
+ ERR("Cannot allocate memory.");
+ goto register_failed;
+ }
+
+ ji->index = index;
+ ji->mapper = mapper;
+ ji->system_path = eina_stringshare_ref(syspath);
+
+ fd = open(devnode, O_RDONLY | O_NONBLOCK);
+ ji->fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ,
+ _fd_handler_cb, ji, 0, 0);
+
+ joystick_list = eina_list_append(joystick_list, ji);
+ _joystick_connected_event_add(index, EINA_TRUE);
+
+register_failed:
+ eina_stringshare_del(devnode);
+}
+
+static void
+_joystick_unregister(const char *syspath)
+{
+ int fd;
+ Eina_List *l, *l2;
+ Joystick_Info *ji;
+
+ EINA_LIST_FOREACH_SAFE(joystick_list, l, l2, ji)
+ {
+ if (syspath == ji->system_path)
+ {
+ fd = ecore_main_fd_handler_fd_get(ji->fd_handler);
+ close(fd);
+ ecore_main_fd_handler_del(ji->fd_handler);
+ joystick_list = eina_list_remove(joystick_list, ji);
+ _joystick_connected_event_add(ji->index, EINA_FALSE);
+ eina_stringshare_del(ji->system_path);
+ free(ji);
+ break;
+ }
+ }
+}
+
+static void
+_watch_cb(const char *syspath, Eeze_Udev_Event event,
+ void *data EINA_UNUSED, Eeze_Udev_Watch *w EINA_UNUSED)
+{
+ switch (event) {
+ case EEZE_UDEV_EVENT_ADD:
+ _joystick_register(syspath);
+ break;
+ case EEZE_UDEV_EVENT_REMOVE:
+ _joystick_unregister(syspath);
+ break;
+ default:
+ break;
+ }
+
+ eina_stringshare_del(syspath);
+}
+#endif
+
+int
+ecore_input_joystick_init(void)
+{
+#ifdef HAVE_EEZE
+ Eina_List *syspaths;
+ const char *syspath;
+
+ if (++_ecore_input_joystick_init_count != 1)
+ return _ecore_input_joystick_init_count;
+
+ if (!eeze_init())
+ return --_ecore_input_joystick_init_count;
+
+ watch = eeze_udev_watch_add(EEZE_UDEV_TYPE_JOYSTICK,
+ (EEZE_UDEV_EVENT_ADD | EEZE_UDEV_EVENT_REMOVE),
+ _watch_cb, NULL);
+
+ syspaths = eeze_udev_find_by_type(EEZE_UDEV_TYPE_JOYSTICK, NULL);
+ EINA_LIST_FREE(syspaths, syspath)
+ {
+ _joystick_register(syspath);
+ eina_stringshare_del(syspath);
+ }
+#endif
+
+ return _ecore_input_joystick_init_count;
+}
+
+int
+ecore_input_joystick_shutdown(void)
+{
+#ifdef HAVE_EEZE
+ if (--_ecore_input_joystick_init_count != 0)
+ return _ecore_input_joystick_init_count;
+
+ if (watch)
+ {
+ eeze_udev_watch_del(watch);
+ watch = NULL;
+ }
+ eeze_shutdown();
+#endif
+
+ return _ecore_input_joystick_init_count;
+}
#endif
#define CRI(...) EINA_LOG_DOM_CRIT(_ecore_input_log_dom, __VA_ARGS__)
+int ecore_input_joystick_init(void);
+int ecore_input_joystick_shutdown(void);
#endif