[gnome-bluetooth] Add first pass at an X input devices monitor



commit 11908099c06564b9648f4da781b764b9ac4f2037
Author: Bastien Nocera <hadess hadess net>
Date:   Wed Oct 28 18:20:36 2009 +0000

    Add first pass at an X input devices monitor
    
    Should allow us to implement the keyboard/mouse setup helper.

 wizard/Makefile.am       |    5 +-
 wizard/bluetooth-input.c |  215 ++++++++++++++++++++++++++++++++++++++++++++++
 wizard/bluetooth-input.h |   65 ++++++++++++++
 wizard/test-input.c      |   52 +++++++++++
 4 files changed, 336 insertions(+), 1 deletions(-)
---
diff --git a/wizard/Makefile.am b/wizard/Makefile.am
index 074f55f..d5f5046 100644
--- a/wizard/Makefile.am
+++ b/wizard/Makefile.am
@@ -5,12 +5,15 @@ libwizard_la_SOURCES = pin.c pin.h
 libwizard_la_LIBADD = $(WIZARD_LIBS)
 libwizard_la_LDFLAGS = -no-undefined $(AM_LDFLAGS)
 
-bin_PROGRAMS = bluetooth-wizard
+bin_PROGRAMS = bluetooth-wizard test-input
 
 bluetooth_wizard_SOURCES = main.c
 
 bluetooth_wizard_LDADD = $(top_builddir)/lib/libgnome-bluetooth.la $(top_builddir)/lib/libcommon.la libwizard.la $(WIZARD_LIBS)
 
+test_input_SOURCES = test-input.c bluetooth-input.c bluetooth-input.h
+test_input_LDADD = $(WIZARD_LIBS)
+
 AM_CFLAGS = $(WIZARD_CFLAGS) $(WARN_CFLAGS) $(DISABLE_DEPRECATED) -DPKGDATADIR="\"$(pkgdatadir)\""
 
 pin_DATA = pin-code-database.xml
diff --git a/wizard/bluetooth-input.c b/wizard/bluetooth-input.c
new file mode 100644
index 0000000..f13eeb0
--- /dev/null
+++ b/wizard/bluetooth-input.c
@@ -0,0 +1,215 @@
+/*
+ *
+ *  Copyright (C) 2009 Bastien Nocera <hadess hadess net>
+ *
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <X11/extensions/XInput.h>
+#include <X11/extensions/XIproto.h>
+
+#include "bluetooth-input.h"
+
+enum {
+	KEYBOARD_APPEARED,
+	KEYBOARD_DISAPPEARED,
+	MOUSE_APPEARED,
+	MOUSE_DISAPPEARED,
+	LAST_SIGNAL
+};
+
+static int signals[LAST_SIGNAL] = { 0 };
+
+#define BLUETOOTH_INPUT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+				BLUETOOTH_TYPE_INPUT, BluetoothInputPrivate))
+
+typedef struct _BluetoothInputPrivate BluetoothInputPrivate;
+
+struct _BluetoothInputPrivate {
+	char *foo;
+};
+
+G_DEFINE_TYPE(BluetoothInput, bluetooth_input, G_TYPE_OBJECT)
+
+static void bluetooth_input_finalize(GObject *input)
+{
+	BluetoothInputPrivate *priv = BLUETOOTH_INPUT_GET_PRIVATE(input);
+
+	G_OBJECT_CLASS(bluetooth_input_parent_class)->finalize(input);
+}
+
+static void bluetooth_input_class_init(BluetoothInputClass *klass)
+{
+	GObjectClass *object_class = (GObjectClass *) klass;
+
+	g_type_class_add_private(klass, sizeof(BluetoothInputPrivate));
+
+	object_class->finalize = bluetooth_input_finalize;
+
+	signals[KEYBOARD_APPEARED] = g_signal_new ("keyboard-appeared",
+						   G_TYPE_FROM_CLASS (klass),
+						   G_SIGNAL_RUN_LAST,
+						   G_STRUCT_OFFSET (BluetoothInputClass, keyboard_appeared),
+						   NULL, NULL,
+						   g_cclosure_marshal_VOID__VOID,
+						   G_TYPE_NONE, 0, G_TYPE_NONE);
+	signals[KEYBOARD_DISAPPEARED] = g_signal_new ("keyboard-disappeared",
+						   G_TYPE_FROM_CLASS (klass),
+						   G_SIGNAL_RUN_LAST,
+						   G_STRUCT_OFFSET (BluetoothInputClass, keyboard_disappeared),
+						   NULL, NULL,
+						   g_cclosure_marshal_VOID__VOID,
+						   G_TYPE_NONE, 0, G_TYPE_NONE);
+	signals[MOUSE_APPEARED] = g_signal_new ("mouse-appeared",
+						G_TYPE_FROM_CLASS (klass),
+						G_SIGNAL_RUN_LAST,
+						G_STRUCT_OFFSET (BluetoothInputClass, mouse_appeared),
+						NULL, NULL,
+						g_cclosure_marshal_VOID__VOID,
+						G_TYPE_NONE, 0, G_TYPE_NONE);
+	signals[MOUSE_DISAPPEARED] = g_signal_new ("mouse-disappeared",
+						   G_TYPE_FROM_CLASS (klass),
+						   G_SIGNAL_RUN_LAST,
+						   G_STRUCT_OFFSET (BluetoothInputClass, mouse_disappeared),
+						   NULL, NULL,
+						   g_cclosure_marshal_VOID__VOID,
+						   G_TYPE_NONE, 0, G_TYPE_NONE);
+}
+
+static gboolean
+supports_xinput_devices (void)
+{
+	gint op_code, event, error;
+
+	return XQueryExtension (GDK_DISPLAY (),
+				"XInputExtension",
+				&op_code,
+				&event,
+				&error);
+}
+
+void
+bluetooth_input_check_for_devices (BluetoothInput *input)
+{
+	XDeviceInfo *device_info;
+	gint n_devices;
+	guint i;
+	gboolean has_keyboard, has_mouse;
+
+	has_keyboard = FALSE;
+	has_mouse = FALSE;
+
+	device_info = XListInputDevices (GDK_DISPLAY (), &n_devices);
+	for (i = 0; i < n_devices; i++) {
+		if (device_info[i].use == IsXExtensionPointer) {
+			/* XTest */
+			if (g_strcmp0 ("Virtual core XTEST pointer", device_info[i].name) == 0)
+				continue;
+			/* Linux mouse button emulation */
+			if (g_strcmp0 ("Macintosh mouse button emulation", device_info[i].name) == 0)
+				continue;
+			g_message ("has mouse: %s (id = %d)", device_info[i].name, device_info[i].id);
+			has_mouse = TRUE;
+			//break;
+		} else if (device_info[i].use == IsXExtensionKeyboard) {
+			/* XTest */
+			if (g_strcmp0 ("Virtual core XTEST keyboard", device_info[i].name) == 0)
+				continue;
+			/* ACPI Power buttons */
+			if (g_strcmp0 ("Power Button", device_info[i].name) == 0)
+				continue;
+			g_message ("has keyboard: %s (id = %d)", device_info[i].name, device_info[i].id);
+			has_keyboard = TRUE;
+			//break;
+		}
+
+		//List and shit
+	}
+
+	if (device_info != NULL)
+		XFreeDeviceList (device_info);
+}
+
+static GdkFilterReturn
+devicepresence_filter (GdkXEvent *xevent,
+		       GdkEvent  *event,
+		       BluetoothInput *input)
+{
+	XEvent *xev = (XEvent *) xevent;
+	XEventClass class_presence;
+	int xi_presence;
+
+	DevicePresence (gdk_x11_get_default_xdisplay (), xi_presence, class_presence);
+
+	if (xev->type == xi_presence) {
+		XDevicePresenceNotifyEvent *dpn = (XDevicePresenceNotifyEvent *) xev;
+		if (dpn->devchange == DeviceEnabled || dpn->devchange == DeviceDisabled)
+			bluetooth_input_check_for_devices (input);
+	}
+	return GDK_FILTER_CONTINUE;
+}
+
+static void
+set_devicepresence_handler (BluetoothInput *input)
+{
+	Display *display;
+	XEventClass class_presence;
+	int xi_presence;
+
+	display = gdk_x11_get_default_xdisplay ();
+
+	gdk_error_trap_push ();
+	DevicePresence (display, xi_presence, class_presence);
+	XSelectExtensionEvent (display,
+			       RootWindow (display, DefaultScreen (display)),
+			       &class_presence, 1);
+
+	gdk_flush ();
+	if (!gdk_error_trap_pop ())
+		gdk_window_add_filter (NULL, (GdkFilterFunc) devicepresence_filter, input);
+}
+
+static void bluetooth_input_init(BluetoothInput *input)
+{
+	BluetoothInputPrivate *priv = BLUETOOTH_INPUT_GET_PRIVATE(input);
+
+	set_devicepresence_handler (input);
+}
+
+/**
+ * bluetooth_input_new:
+ *
+ * Return value: a reference to the #BluetoothInput singleton. Unref the object when done.
+ **/
+BluetoothInput *bluetooth_input_new(void)
+{
+	if (supports_xinput_devices () == FALSE) {
+		g_warning ("XInput not supported, input device helper disabled");
+		return NULL;
+	}
+	return BLUETOOTH_INPUT (g_object_new (BLUETOOTH_TYPE_INPUT, NULL));
+}
+
diff --git a/wizard/bluetooth-input.h b/wizard/bluetooth-input.h
new file mode 100644
index 0000000..43e5694
--- /dev/null
+++ b/wizard/bluetooth-input.h
@@ -0,0 +1,65 @@
+/*
+ *
+ *  Copyright (C) 2009 Bastien Nocera <hadess hadess net>
+ *
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef __BLUETOOTH_INPUT_H
+#define __BLUETOOTH_INPUT_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define BLUETOOTH_TYPE_INPUT (bluetooth_input_get_type())
+#define BLUETOOTH_INPUT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+					BLUETOOTH_TYPE_INPUT, BluetoothInput))
+#define BLUETOOTH_INPUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
+					BLUETOOTH_TYPE_INPUT, BluetoothInputClass))
+#define BLUETOOTH_IS_INPUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
+							BLUETOOTH_TYPE_INPUT))
+#define BLUETOOTH_IS_INPUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), \
+							BLUETOOTH_TYPE_INPUT))
+#define BLUETOOTH_GET_INPUT_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
+					BLUETOOTH_TYPE_INPUT, BluetoothInputClass))
+
+typedef struct _BluetoothInput BluetoothInput;
+typedef struct _BluetoothInputClass BluetoothInputClass;
+
+struct _BluetoothInput {
+	GObject parent;
+};
+
+struct _BluetoothInputClass {
+	GObjectClass parent_class;
+
+	void (* keyboard_appeared) (BluetoothInput *listener);
+	void (* keyboard_disappeared) (BluetoothInput *listener);
+	void (* mouse_appeared) (BluetoothInput *listener);
+	void (* mouse_disappeared) (BluetoothInput *listener);
+};
+
+GType bluetooth_input_get_type(void);
+
+BluetoothInput *bluetooth_input_new(void);
+
+void bluetooth_input_check_for_devices (BluetoothInput *input);
+
+G_END_DECLS
+
+#endif /* __BLUETOOTH_INPUT_H */
diff --git a/wizard/test-input.c b/wizard/test-input.c
new file mode 100644
index 0000000..87f21fc
--- /dev/null
+++ b/wizard/test-input.c
@@ -0,0 +1,52 @@
+#include <gtk/gtk.h>
+#include <bluetooth-input.h>
+
+static void
+keyboard_appeared_cb (BluetoothInput *input, gpointer data)
+{
+	g_message ("keyboard_appeared_cb");
+}
+
+static void
+keyboard_disappeared_cb (BluetoothInput *input, gpointer data)
+{
+	g_message ("keyboard_disappeared_cb");
+}
+
+static void
+mouse_appeared_cb (BluetoothInput *input, gpointer data)
+{
+	g_message ("mouse_appeared_cb");
+}
+
+static void
+mouse_disappeared_cb (BluetoothInput *input, gpointer data)
+{
+	g_message ("mouse_disappeared_cb");
+}
+
+int main (int argc, char **argv)
+{
+	BluetoothInput *input;
+
+	gtk_init (&argc, &argv);
+
+	input = bluetooth_input_new ();
+	if (input == NULL)
+		return 1;
+
+	g_signal_connect (G_OBJECT (input), "keyboard-appeared",
+			  G_CALLBACK (keyboard_appeared_cb), NULL);
+	g_signal_connect (G_OBJECT (input), "keyboard-disappeared",
+			  G_CALLBACK (keyboard_disappeared_cb), NULL);
+	g_signal_connect (G_OBJECT (input), "mouse-appeared",
+			  G_CALLBACK (mouse_appeared_cb), NULL);
+	g_signal_connect (G_OBJECT (input), "mouse-disappeared",
+			  G_CALLBACK (mouse_disappeared_cb), NULL);
+
+	bluetooth_input_check_for_devices (input);
+
+	gtk_main ();
+
+	return 0;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]