[PATCH weston 17/20] android: add basic evdev input support

Pekka Paalanen ppaalanen at gmail.com
Fri Aug 3 04:39:13 PDT 2012


Android backend needs mtdev now, and evdev-touchpad.c, too.

Signed-off-by: Pekka Paalanen <ppaalanen at gmail.com>
---
 configure.ac             |    1 +
 src/Makefile.am          |   16 +++++--
 src/compositor-android.c |  105 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 117 insertions(+), 5 deletions(-)

diff --git a/configure.ac b/configure.ac
index e67ad50..754469f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -115,6 +115,7 @@ AC_ARG_ENABLE(android-compositor,
 AM_CONDITIONAL(ENABLE_ANDROID_COMPOSITOR, test x$enable_android_compositor = xyes)
 if test x$enable_android_compositor = xyes; then
   AC_DEFINE([BUILD_ANDROID_COMPOSITOR], [1], [Build the compositor for Android 4.0])
+  PKG_CHECK_MODULES(ANDROID_COMPOSITOR, [mtdev >= 1.1.0])
 fi
 
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 2cf9d6b..8096849 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -124,12 +124,18 @@ endif
 if ENABLE_ANDROID_COMPOSITOR
 android_backend = android-backend.la
 android_backend_la_LDFLAGS = -module -avoid-version
-android_backend_la_LIBADD = $(COMPOSITOR_LIBS)
-android_backend_la_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS)
+android_backend_la_LIBADD = $(COMPOSITOR_LIBS) $(ANDROID_COMPOSITOR_LIBS)
+android_backend_la_CFLAGS =			\
+	$(GCC_CFLAGS)				\
+	$(COMPOSITOR_CFLAGS)			\
+	$(ANDROID_COMPOSITOR_CFLAGS)
 android_backend_la_CXXFLAGS = $(GCC_CXXFLAGS) $(COMPOSITOR_CFLAGS)
-android_backend_la_SOURCES = \
-	compositor-android.c \
-	android-framebuffer.cpp \
+android_backend_la_SOURCES =			\
+	compositor-android.c			\
+	evdev.c					\
+	evdev.h					\
+	evdev-touchpad.c			\
+	android-framebuffer.cpp			\
 	android-framebuffer.h
 endif
 
diff --git a/src/compositor-android.c b/src/compositor-android.c
index a61c5ea..5d1eeee 100644
--- a/src/compositor-android.c
+++ b/src/compositor-android.c
@@ -20,16 +20,24 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#define _GNU_SOURCE
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <math.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
 
 #include <EGL/egl.h>
 #include <GLES2/gl2.h>
 
 #include "compositor.h"
 #include "android-framebuffer.h"
+#include "evdev.h"
 
 struct android_compositor;
 
@@ -44,6 +52,7 @@ struct android_output {
 
 struct android_seat {
 	struct weston_seat base;
+	struct wl_list devices_list;
 };
 
 struct android_compositor {
@@ -58,6 +67,12 @@ to_android_output(struct weston_output *base)
 	return container_of(base, struct android_output, base);
 }
 
+static inline struct android_seat *
+to_android_seat(struct weston_seat *base)
+{
+	return container_of(base, struct android_seat, base);
+}
+
 static inline struct android_compositor *
 to_android_compositor(struct weston_compositor *base)
 {
@@ -229,8 +244,85 @@ android_compositor_add_output(struct android_compositor *compositor,
 }
 
 static void
+android_led_update(struct weston_seat *seat_base, enum weston_led leds)
+{
+	struct android_seat *seat = to_android_seat(seat_base);
+
+	evdev_led_update(&seat->devices_list, leds);
+}
+
+static void
+android_seat_open_device(struct android_seat *seat, const char *devnode)
+{
+	struct evdev_input_device *device;
+	int fd;
+
+	/* XXX: check the Android excluded list */
+
+	fd = open(devnode, O_RDWR | O_NONBLOCK | O_CLOEXEC);
+	if (fd < 0) {
+		weston_log_continue("opening '%s' failed: %s\n", devnode,
+				    strerror(errno));
+		return;
+	}
+
+	device = evdev_input_device_create(&seat->base, devnode, fd);
+	if (!device) {
+		close(fd);
+		return;
+	}
+
+	wl_list_insert(seat->devices_list.prev, &device->link);
+}
+
+static int
+is_dot_or_dotdot(const char *str)
+{
+	return (str[0] == '.' &&
+		(str[1] == 0 || (str[1] == '.' && str[2] == 0)));
+}
+
+static void
+android_seat_scan_devices(struct android_seat *seat, const char *dirpath)
+{
+	int ret;
+	DIR *dir;
+	struct dirent *dent;
+	char *devnode = NULL;
+
+	dir = opendir(dirpath);
+	if (!dir) {
+		weston_log("Could not open input device directory '%s': %s\n",
+			   dirpath, strerror(errno));
+		return;
+	}
+
+	while ((dent = readdir(dir)) != NULL) {
+		if (is_dot_or_dotdot(dent->d_name))
+			continue;
+
+		ret = asprintf(&devnode, "%s/%s", dirpath, dent->d_name);
+		if (ret < 0)
+			continue;
+
+		android_seat_open_device(seat, devnode);
+		free(devnode);
+	}
+
+	closedir(dir);
+}
+
+static void
 android_seat_destroy(struct android_seat *seat)
 {
+	struct evdev_input_device *device, *next;
+
+	wl_list_for_each_safe(device, next, &seat->devices_list, link)
+		evdev_input_device_destroy(device);
+
+	if (seat->base.seat.keyboard)
+		notify_keyboard_focus_out(&seat->base.seat);
+
 	weston_seat_release(&seat->base);
 	free(seat);
 }
@@ -245,8 +337,19 @@ android_seat_create(struct android_compositor *compositor)
 		return NULL;
 
 	weston_seat_init(&seat->base, &compositor->base);
+	seat->base.led_update = android_led_update;
+	wl_list_init(&seat->devices_list);
 	compositor->base.seat = &seat->base;
 
+	android_seat_scan_devices(seat, "/dev/input");
+
+	evdev_notify_keyboard_focus(&seat->base, &seat->devices_list);
+
+	if (wl_list_empty(&seat->devices_list))
+		weston_log("Warning: no input devices found.\n");
+
+	/* XXX: implement hotplug support */
+
 	return seat;
 }
 
@@ -412,6 +515,8 @@ android_compositor_create(struct wl_display *display, int argc, char *argv[],
 	struct android_compositor *compositor;
 	struct android_output *output;
 
+	weston_log("initializing android backend\n");
+
 	compositor = calloc(1, sizeof *compositor);
 	if (compositor == NULL)
 		return NULL;
-- 
1.7.8.6



More information about the wayland-devel mailing list