[gnome-settings-daemon] common: Launch a custom script on input devices



commit 2ec0fbd38cd9d787fc3ad003f462c537ea795890
Author: Peter Hutterer <peter hutterer who-t net>
Date:   Mon Mar 21 09:36:24 2011 +0000

    common: Launch a custom script on input devices
    
    A number of users require input configurations that go beyond what the
    gnome-control-center and gnome-settings-daemon offer. Some of these
    configurations are readily accessible through various commandline
    interfaces (synclient, xinput, xsetwacom, etc.) but are too uncommon to
    justify full inclusion into g-s-d and/or g-c-c.
    
    This patch adds a new key
      org.gnome.settings-daemon.peripherals.input-devices hotplug-command
    
    that lets the user specify a custom script to be executed whenever
    devices are added or removed. The script is called with three arguments:
    
      path/to/custom/command -t [added|removed|present] -i <device ID> <device name>
    
    The first argument specifies if the device was just added or removed
    or is already present at g-s-d startup time. The device name is the name
    as provided by XInput.
    
    The custom command is called for all slave devices (incl. floating ones)
    but not for master devices.
    
    Note that the functionality is not currently called for any input
    devices.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=635486

 ...e.settings-daemon.peripherals.gschema.xml.in.in |    8 ++
 plugins/common/Makefile.am                         |    5 ++
 plugins/common/gsd-input-helper.c                  |   75 ++++++++++++++++++++
 plugins/common/gsd-input-helper.h                  |    9 +++
 plugins/common/input-device-example.sh             |   66 +++++++++++++++++
 5 files changed, 163 insertions(+), 0 deletions(-)
---
diff --git a/data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in b/data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in
index 2861eb8..7c9fbff 100644
--- a/data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in
+++ b/data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in
@@ -4,6 +4,7 @@
     <child name="touchpad" schema="org.gnome.settings-daemon.peripherals.touchpad"/>
     <child name="keyboard" schema="org.gnome.settings-daemon.peripherals.keyboard"/>
     <child name="mouse" schema="org.gnome.settings-daemon.peripherals.mouse"/>
+    <child name="input-devices" schema="org.gnome.settings-daemon.peripherals.input-devices"/>
   </schema>
   <schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.peripherals.smartcard" path="/org/gnome/settings-daemon/peripherals/smartcard/">
     <key name="removal-action" enum="org.gnome.settings-daemon.GsdSmartcardRemovalAction">
@@ -131,4 +132,11 @@
       <_description>Enables middle mouse button emulation through simultaneous left and right button click.</_description>
     </key>
   </schema>
+  <schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.peripherals.input-devices" path="/org/gnome/settings-daemon/peripherals/input-devices/">
+    <key name="hotplug-command" type="s">
+      <default>''</default>
+      <_summary>Device hotplug custom command</_summary>
+      <_description>Command to be run when a device is added or removed.</_description>
+    </key>
+  </schema>
 </schemalist>
diff --git a/plugins/common/Makefile.am b/plugins/common/Makefile.am
index 608443d..bbfc4c1 100644
--- a/plugins/common/Makefile.am
+++ b/plugins/common/Makefile.am
@@ -27,3 +27,8 @@ libcommon_la_LDFLAGS = \
 libcommon_la_LIBADD  = \
 	$(SETTINGS_PLUGIN_LIBS)		\
 	$(XINPUT_LIBS)
+
+scriptsdir = $(datadir)/gnome-settings-daemon- GSD_API_VERSION@
+scripts_DATA = input-device-example.sh
+
+EXTRA_DIST = $(scripts_DATA)
diff --git a/plugins/common/gsd-input-helper.c b/plugins/common/gsd-input-helper.c
index c1051f3..d8bae69 100644
--- a/plugins/common/gsd-input-helper.c
+++ b/plugins/common/gsd-input-helper.c
@@ -28,6 +28,9 @@
 
 #include "gsd-input-helper.h"
 
+#define INPUT_DEVICES_SCHEMA "org.gnome.settings-daemon.peripherals.input-devices"
+#define KEY_HOTPLUG_COMMAND  "hotplug-command"
+
 static gboolean
 supports_xinput_devices (void)
 {
@@ -106,3 +109,75 @@ touchpad_is_present (void)
         return retval;
 }
 
+static const char *
+custom_command_to_string (CustomCommand command)
+{
+	switch (command) {
+	case COMMAND_DEVICE_ADDED:
+		return "added";
+	case COMMAND_DEVICE_REMOVED:
+		return "removed";
+	case COMMAND_DEVICE_PRESENT:
+		return "present";
+	default:
+		g_assert_not_reached ();
+	}
+}
+
+/* Run a custom command on device presence events. Parameters passed into
+ * the custom command are:
+ * command -t [added|removed|present] -i <device ID> <device name>
+ * Type 'added' and 'removed' signal 'device added' and 'device removed',
+ * respectively. Type 'present' signals 'device present at
+ * gnome-settings-daemon init'.
+ *
+ * The script is expected to run synchronously, and an exit value
+ * of "1" means that no other settings will be applied to this
+ * particular device.
+ *
+ * More options may be added in the future.
+ *
+ * This function returns TRUE if we should not apply any more settings
+ * to the device.
+ */
+gboolean
+run_custom_command (GdkDevice              *device,
+		    CustomCommand           command)
+{
+	GSettings *settings;
+	char *cmd;
+	char *argv[5];
+	int exit_status;
+	gboolean rc;
+	int id;
+
+	settings = g_settings_new (INPUT_DEVICES_SCHEMA);
+	cmd = g_settings_get_string (settings, KEY_HOTPLUG_COMMAND);
+	g_object_unref (settings);
+
+	if (!cmd || cmd[0] == '\0') {
+		g_free (cmd);
+		return FALSE;
+	}
+
+	/* Easter egg! */
+	g_object_get (device, "device-id", &id, NULL);
+
+	argv[0] = cmd;
+	argv[1] = g_strdup_printf ("-t %s", custom_command_to_string (command));
+	argv[2] = g_strdup_printf ("-i %d", id);
+	argv[3] = g_strdup_printf ("%s", gdk_device_get_name (device));
+	argv[4] = NULL;
+
+	rc = g_spawn_sync (g_get_home_dir (), argv, NULL, G_SPAWN_SEARCH_PATH,
+			   NULL, NULL, NULL, NULL, &exit_status, NULL);
+
+	if (rc == FALSE)
+		g_warning ("Couldn't execute command '%s', verify that this is a valid command.", cmd);
+
+	g_free (argv[0]);
+	g_free (argv[1]);
+	g_free (argv[2]);
+
+	return (exit_status == 0);
+}
diff --git a/plugins/common/gsd-input-helper.h b/plugins/common/gsd-input-helper.h
index 90c7310..eb3cd8a 100644
--- a/plugins/common/gsd-input-helper.h
+++ b/plugins/common/gsd-input-helper.h
@@ -27,9 +27,18 @@ G_BEGIN_DECLS
 #include <X11/extensions/XInput.h>
 #include <X11/extensions/XIproto.h>
 
+typedef enum {
+	COMMAND_DEVICE_ADDED,
+	COMMAND_DEVICE_REMOVED,
+	COMMAND_DEVICE_PRESENT
+} CustomCommand;
+
 XDevice * device_is_touchpad  (XDeviceInfo deviceinfo);
 gboolean  touchpad_is_present (void);
 
+gboolean  run_custom_command  (GdkDevice              *device,
+			       CustomCommand           command);
+
 G_END_DECLS
 
 #endif /* __GSD_INPUT_HELPER_H */
diff --git a/plugins/common/input-device-example.sh b/plugins/common/input-device-example.sh
new file mode 100644
index 0000000..0b065c5
--- /dev/null
+++ b/plugins/common/input-device-example.sh
@@ -0,0 +1,66 @@
+#!/bin/sh
+#
+# This script is an example hotplug script for use with the various
+# input devices plugins.
+#
+# The script is called with the arguments:
+# -t [added|present|removed] <device name>
+#       added ... device was just plugged in
+#       present.. device was present at gnome-settings-daemon startup
+#       removed.. device was just removed
+# -i <device ID>
+#       device ID being the XInput device ID
+# <device name> The name of the device
+#
+# The script should return 0 if the device is to be
+# ignored from future configuration.
+#
+
+args=`getopt "t:" $*`
+
+set -- $args
+
+while [ $# -gt 0 ]
+do
+    case $1 in
+    -t)
+        shift;
+        type="$1"
+        ;;
+     -i)
+        shift;
+        id="$1"
+        ;;
+     --)
+        shift;
+        device="$@"
+        break;
+        ;;
+    *)
+        echo "Unknown option $1";
+        exit 1
+        ;;
+    esac
+    shift
+done
+
+retval=0
+
+case $type in
+        added)
+                echo "Device '$device' (ID=$id) was added"
+                ;;
+        present)
+                echo "Device '$device' (ID=$id) was already present at startup"
+                ;;
+        removed)
+                echo "Device '$device' (ID=$id) was removed"
+                ;;
+        *)
+                echo "Unknown operation"
+                retval=1
+                ;;
+esac
+
+# All further processing will be disabled if $retval == 0
+return $retval



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