Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1:kernel-2.6.32
gnome-settings-daemon
gnome-settings-daemon-bnc461755-randr-rotate-wa...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File gnome-settings-daemon-bnc461755-randr-rotate-wacom.diff of Package gnome-settings-daemon
diff --git a/ChangeLog b/ChangeLog index ec6af64..fd47f34 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2009-01-28 Federico Mena Quintero <federico@novell.com> + + https://bugzilla.novell.com/show_bug.cgi?id=461755 - For tablets, + call xsetwacom to rotate the stylus when the monitor is rotated. + + This is not really the right way to do things --- the X server + should take care of this. In the meantime, we'll offer this + option here and in gnome-display-properties from + gnome-control-center. + + * data/apps_gnome_settings_daemon_xrandr.schemas.in: New key + /apps/gnome_settings_daemon/xrandr/rotate_tablet_with_monitor to + select whether the stylus will be rotated when the monitor is + rotated. See the key's description for information about why this + needs to be an option (it depends on built-in vs. external + tablets). + + Sanitize GConf key: + + * plugins/xrandr/gsd-xrandr-manager.c + (CONF_KEY_SHOW_NOTIFICATION_ICON): renamed from CONF_KEY. + (on_config_changed): Only frob the tray icon if its corresponding + GConf key changes. + 2009-01-27 Federico Mena Quintero <federico@novell.com> http://bugzilla.gnome.org/show_bug.cgi?id=545115 - Ask for 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 @@ </long> </locale> </schema> + + <schema> + <key>/schemas/apps/gnome_settings_daemon/xrandr/rotate_tablet_with_monitor</key> + <applyto>/apps/gnome_settings_daemon/xrandr/rotate_tablet_with_monitor</applyto> + <owner>gnome</owner> + <type>bool</type> + <default>true</default> + <locale name="C"> + <short>Rotate pressure-sensitive tablet along with the + monitor</short> + <long>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. + </long> + </locale> + </schema> </schemalist> </gconfschemafile> diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c index d2eba18..911eb1b 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" +#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" @@ -109,6 +110,147 @@ 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 +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; + 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); +} + +static gboolean +apply_stored_configuration_and_rotate_tablet (GsdXrandrManager *manager, const char *filename, GError **error) +{ + struct GsdXrandrManagerPrivate *priv = manager->priv; + gboolean success; + + success = gnome_rr_config_apply_from_filename (priv->rw_screen, filename, error); + + if (success) + handle_tablet_rotation (manager); + + return success; +} + static void restore_backup_configuration_without_messages (const char *backup_filename, const char *intended_filename) { @@ -119,7 +261,6 @@ restore_backup_configuration_without_messages (const char *backup_filename, cons static void restore_backup_configuration (GsdXrandrManager *manager, const char *backup_filename, const char *intended_filename) { - struct GsdXrandrManagerPrivate *priv = manager->priv; int saved_errno; char *msg; @@ -127,7 +268,7 @@ restore_backup_configuration (GsdXrandrManager *manager, const char *backup_file GError *error; error = NULL; - if (!gnome_rr_config_apply_from_filename (priv->rw_screen, intended_filename, &error)) { + if (!apply_stored_configuration_and_rotate_tablet (manager, intended_filename, &error)) { error_message (manager, _("Could not restore the display's configuration"), error, NULL); if (error) @@ -241,7 +382,6 @@ user_says_things_are_ok (GsdXrandrManager *manager) static gboolean try_to_apply_intended_configuration (GsdXrandrManager *manager, GError **error) { - struct GsdXrandrManagerPrivate *priv = manager->priv; char *backup_filename; char *intended_filename; gboolean result; @@ -251,7 +391,7 @@ try_to_apply_intended_configuration (GsdXrandrManager *manager, GError **error) backup_filename = gnome_rr_config_get_backup_filename (); intended_filename = gnome_rr_config_get_intended_filename (); - result = gnome_rr_config_apply_from_filename (priv->rw_screen, intended_filename, error); + result = apply_stored_configuration_and_rotate_tablet (manager, intended_filename, error); if (!result) { error_message (manager, _("The selected configuration for displays could not be applied"), error ? *error : NULL, NULL); restore_backup_configuration_without_messages (backup_filename, intended_filename); @@ -1268,7 +1408,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 { @@ -1282,7 +1422,10 @@ 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); + else if (strcmp (entry->key, CONF_KEY_ROTATE_TABLET_WITH_MONITOR) == 0) + handle_tablet_rotation (manager); } static void @@ -1291,7 +1434,7 @@ apply_intended_configuration (GsdXrandrManager *manager, const char *intended_fi GError *my_error; my_error = NULL; - if (!gnome_rr_config_apply_from_filename (manager->priv->rw_screen, intended_filename, &my_error)) { + if (!apply_stored_configuration_and_rotate_tablet (manager, intended_filename, &my_error)) { if (my_error) { if (g_error_matches (my_error, GNOME_RR_ERROR, GNOME_RR_ERROR_NO_MATCHING_CONFIG)) { /* This is not an error; the user probably @@ -1325,7 +1468,7 @@ apply_stored_configuration_at_startup (GsdXrandrManager *manager) my_error = NULL; - success = gnome_rr_config_apply_from_filename (manager->priv->rw_screen, backup_filename, &my_error); + success = apply_stored_configuration_and_rotate_tablet (manager, backup_filename, &my_error); if (success) { /* The backup configuration existed, and could be applied * successfully, so we must restore it on top of the
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor