From 1eae564882f64b739bb98b9aae52b58c2370f860 Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Tue, 27 Jan 2009 19:52:50 -0600 Subject: [PATCH 1/6] Add a GConf key to rotate tablets when the monitor rotates Signed-off-by: Federico Mena Quintero --- data/apps_gnome_settings_daemon_xrandr.schemas.in | 25 +++++++++++++++++++++ 1 files changed, 25 insertions(+), 0 deletions(-) diff --git a/data/apps_gnome_settings_daemon_xrandr.schemas.in b/data/apps_gnome_settings_daemon_xrandr.schemas.in index c9f59fd..80324ca 100644 --- a/data/apps_gnome_settings_daemon_xrandr.schemas.in +++ b/data/apps_gnome_settings_daemon_xrandr.schemas.in @@ -14,5 +14,30 @@ + + + /schemas/apps/gnome_settings_daemon/xrandr/rotate_tablet_with_monitor + /apps/gnome_settings_daemon/xrandr/rotate_tablet_with_monitor + gnome + bool + true + + Rotate pressure-sensitive tablet along with the + monitor + For internal pressure-sensitive + tablets which are part of the display (such as the + ones in tablet PCs), you want the tablet's cursor to + rotate when the monitor is rotated, so that the + orientation of the stylus will match the orientation + of the monitor; use "true" in this case. But for + external tablets, you may prefer to keep the tablet in + the same orientation even if you rotate the monitor; + use "false" in this case. + + This option will only be used if the xsetwacom binary + is in your PATH. + + + -- 1.6.0.2 From c2668abfa744b67a5ad6d49aca5c3683638e7712 Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Wed, 28 Jan 2009 11:38:37 -0600 Subject: [PATCH 2/6] Change a define for a GConf key name Signed-off-by: Federico Mena Quintero --- plugins/xrandr/gsd-xrandr-manager.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c index d9e5671..2e5a8ea 100644 --- a/plugins/xrandr/gsd-xrandr-manager.c +++ b/plugins/xrandr/gsd-xrandr-manager.c @@ -63,7 +63,7 @@ #define GSD_XRANDR_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_XRANDR_MANAGER, GsdXrandrManagerPrivate)) #define CONF_DIR "/apps/gnome_settings_daemon/xrandr" -#define CONF_KEY "show_notification_icon" +#define CONF_KEY_SHOW_NOTIFICATION_ICON (CONF_DIR "/show_notification_icon") #define VIDEO_KEYSYM "XF86Display" @@ -1374,7 +1374,7 @@ status_icon_stop (GsdXrandrManager *manager) static void start_or_stop_icon (GsdXrandrManager *manager) { - if (gconf_client_get_bool (manager->priv->client, CONF_DIR "/" CONF_KEY, NULL)) { + if (gconf_client_get_bool (manager->priv->client, CONF_KEY_SHOW_NOTIFICATION_ICON, NULL)) { status_icon_start (manager); } else { @@ -1388,7 +1388,8 @@ on_config_changed (GConfClient *client, GConfEntry *entry, GsdXrandrManager *manager) { - start_or_stop_icon (manager); + if (strcmp (entry->key, CONF_KEY_SHOW_NOTIFICATION_ICON) == 0) + start_or_stop_icon (manager); } static void -- 1.6.0.2 From a1235e7af87966bfaad3631661abc73513e1fb26 Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Thu, 29 Jan 2009 18:37:53 -0600 Subject: [PATCH 3/6] Framework to handle the new GConf key to rotate the tablet Signed-off-by: Federico Mena Quintero --- plugins/xrandr/gsd-xrandr-manager.c | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletions(-) diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c index 2e5a8ea..dbe4a8e 100644 --- a/plugins/xrandr/gsd-xrandr-manager.c +++ b/plugins/xrandr/gsd-xrandr-manager.c @@ -63,7 +63,8 @@ #define GSD_XRANDR_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_XRANDR_MANAGER, GsdXrandrManagerPrivate)) #define CONF_DIR "/apps/gnome_settings_daemon/xrandr" -#define CONF_KEY_SHOW_NOTIFICATION_ICON (CONF_DIR "/show_notification_icon") +#define CONF_KEY_SHOW_NOTIFICATION_ICON (CONF_DIR "/show_notification_icon") +#define CONF_KEY_ROTATE_TABLET_WITH_MONITOR (CONF_DIR "/rotate_tablet_with_monitor") #define VIDEO_KEYSYM "XF86Display" @@ -114,6 +115,12 @@ G_DEFINE_TYPE (GsdXrandrManager, gsd_xrandr_manager, G_TYPE_OBJECT) static gpointer manager_object = NULL; +static void +handle_tablet_rotation (GsdXrandrManager *manager) +{ + /* FMQ: implement */ +} + /* Filters out GNOME_RR_ERROR_NO_MATCHING_CONFIG from * gnome_rr_config_apply_from_filename(), since that is not usually an error. */ @@ -1390,6 +1397,8 @@ on_config_changed (GConfClient *client, { if (strcmp (entry->key, CONF_KEY_SHOW_NOTIFICATION_ICON) == 0) start_or_stop_icon (manager); + else if (strcmp (entry->key, CONF_KEY_ROTATE_TABLET_WITH_MONITOR) == 0) + handle_tablet_rotation (manager); } static void -- 1.6.0.2 From d3f2bd5f11c83d40dc2f363da17effccc81477d4 Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Thu, 29 Jan 2009 18:42:40 -0600 Subject: [PATCH 4/6] Handle rotation of the tablet every time we apply a RANDR configuration Signed-off-by: Federico Mena Quintero --- plugins/xrandr/gsd-xrandr-manager.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c index dbe4a8e..325f39f 100644 --- a/plugins/xrandr/gsd-xrandr-manager.c +++ b/plugins/xrandr/gsd-xrandr-manager.c @@ -133,8 +133,10 @@ apply_configuration_from_filename (GsdXrandrManager *manager, const char *filena my_error = NULL; success = gnome_rr_config_apply_from_filename (priv->rw_screen, filename, &my_error); - if (success) + if (success) { + handle_tablet_rotation (manager); return TRUE; + } if (g_error_matches (my_error, GNOME_RR_ERROR, GNOME_RR_ERROR_NO_MATCHING_CONFIG)) { /* This is not an error; the user probably changed his monitors -- 1.6.0.2 From 27d2fe2de5738d309ff8cfc7e206297397dee52c Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Thu, 29 Jan 2009 19:13:33 -0600 Subject: [PATCH 5/6] Find the rotation to use for the tablet Signed-off-by: Federico Mena Quintero --- plugins/xrandr/gsd-xrandr-manager.c | 49 ++++++++++++++++++++++++++++++++++- 1 files changed, 48 insertions(+), 1 deletions(-) diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c index 325f39f..63142c9 100644 --- a/plugins/xrandr/gsd-xrandr-manager.c +++ b/plugins/xrandr/gsd-xrandr-manager.c @@ -115,10 +115,57 @@ G_DEFINE_TYPE (GsdXrandrManager, gsd_xrandr_manager, G_TYPE_OBJECT) static gpointer manager_object = NULL; +static GnomeRRRotation +find_rotation_for_tablet (GnomeRRConfig *configuration) +{ + int i; + + /* The stupid heuristic is to find the first rotated output, and use its rotation. + * The rationale is: + * + * - If you have a built-in tablet (like a tablet PC), then you want the + * stylus to match the built-in monitor's orientation. Your external + * monitor has no relationship to your stylus. + * + * - If you have a single swivel monitor, that's the one which corresponds to + * your external tablet. + * + * - If you have two swivel monitors, well, I want your setup at my home, too. + */ + + for (i = 0; configuration->outputs[i] != NULL; i++) { + GnomeOutputInfo *output; + + output = configuration->outputs[i]; + if (output->on && output->connected && output->rotation != GNOME_RR_ROTATION_0) + return output->rotation; + } + + return GNOME_RR_ROTATION_0; +} + static void handle_tablet_rotation (GsdXrandrManager *manager) { - /* FMQ: implement */ + struct GsdXrandrManagerPrivate *priv = manager->priv; + GnomeRRConfig *configuration; + GnomeRRRotation rotation; + + if (!gconf_client_get_bool (priv->client, CONF_KEY_ROTATE_TABLET_WITH_MONITOR, NULL)) { + rotate_tablet (manager, GNOME_RR_ROTATION_0); /* un-rotate the tablet when the GConf key is turned off */ + return; + } + + /* Re-creating the current configuration is probably not the most + * efficient thing, but it should give us an accurate view of the world. + */ + configuration = gnome_rr_config_new_current (priv->rw_screen); + + rotation = find_rotation_for_tablet (configuration); + + gnome_rr_config_free (configuration); + + rotate_tablet (manager, rotation); } /* Filters out GNOME_RR_ERROR_NO_MATCHING_CONFIG from -- 1.6.0.2 From 8df5eafa8f72178516d5e3c1489333d571f487e6 Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Fri, 30 Jan 2009 13:46:57 -0600 Subject: [PATCH 6/6] Call xsetwacom(1) to rotate the stylus Signed-off-by: Federico Mena Quintero --- plugins/xrandr/gsd-xrandr-manager.c | 74 +++++++++++++++++++++++++++++++++++ 1 files changed, 74 insertions(+), 0 deletions(-) diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c index 63142c9..ad42235 100644 --- a/plugins/xrandr/gsd-xrandr-manager.c +++ b/plugins/xrandr/gsd-xrandr-manager.c @@ -145,6 +145,80 @@ find_rotation_for_tablet (GnomeRRConfig *configuration) } static void +rotate_tablet (GsdXrandrManager *manager, GnomeRRRotation rotation) +{ + char *stdout_str; + int status; + char *p; + char *newline; + const char *arg; + + /* We really don't do error checking. If xsetwacom(1) doesn't exist, + * well, too bad. Maybe that means that the user doesn't have a tablet. + */ + + stdout_str = NULL; + if (!g_spawn_command_line_sync ("xsetwacom list", + &stdout_str, + NULL, + &status, + NULL)) + goto out; + + if (!(WIFEXITED (status) && WEXITSTATUS (status) == 0 && stdout_str != NULL)) + goto out; + + switch (rotation) { + case GNOME_RR_ROTATION_90: + arg = "CW"; + break; + + case GNOME_RR_ROTATION_180: + arg = "HALF"; + break; + + case GNOME_RR_ROTATION_270: + arg = "CCW"; + break; + + default: /* this also catches GNOME_RR_ROTATION_0 */ + arg = "NONE"; + break; + } + + for (p = stdout_str; *p != '\0'; p = newline + 1) { + char *end; + char *device_name; + char *command; + + newline = strchr (p, '\n'); + if (!newline) + break; + + *newline = '\0'; + + if (!strstr (p, "stylus")) + continue; + + device_name = p; + for (end = device_name; *end != '\0' && !g_ascii_isspace (*end); end++); + + *end = '\0'; + + if (strlen (device_name) == 0) + continue; + + command = g_strconcat ("xsetwacom set ", device_name, " Rotate ", arg, NULL); + g_spawn_command_line_sync (command, NULL, NULL, NULL, NULL); + g_free (command); + } + +out: + + g_free (stdout_str); +} + +static void handle_tablet_rotation (GsdXrandrManager *manager) { struct GsdXrandrManagerPrivate *priv = manager->priv; -- 1.6.0.2