Code

Try harder to fix the tablet configuration problem
[inkscape.git] / src / dialogs / input.cpp
index 0b4587f55aeb9a074b7e12bdcb780af16bf6e847..a8892bde428e5039c0a4c9de7470ab8757c606e5 100644 (file)
@@ -63,10 +63,39 @@ sp_input_dialog_delete (GtkObject */*object*/, GdkEvent */*event*/, gpointer /*d
 
 }
 
-static const gchar *axis_use_strings[GDK_AXIS_LAST] = {
+static gchar const *axis_use_strings[GDK_AXIS_LAST] = {
     "ignore", "x", "y", "pressure", "xtilt", "ytilt", "wheel"
 };
 
+static Glib::ustring sanitized_device_path(gchar const *str)
+{
+    // LP #334800: tablet device names on Windows sometimes contain funny junk like
+    // \x03, \xf2, etc. Moreover this junk changes between runs.
+    // If the tablet name contains unprintable or non-ASCII characters,
+    // we use some default name.
+    // This might break if someone has two tablets with broken names, but it's
+    // not possible to do anything 100% correct then.
+    bool broken = false;
+    if (!str || *str == 0) {
+        broken = true;
+    } else {
+        for (gchar const *s = str; *s; ++s) {
+            if (*s < 0x20 || *s >= 0x7f) {
+                broken = true;
+                break;
+            }
+        }
+    }
+
+    Glib::ustring device_path = "/devices/";
+    if (broken) {
+        device_path += "Tablet";
+    } else {
+        device_path += str;
+    }
+    return device_path;
+}
+
 void
 sp_input_load_from_preferences (void)
 {
@@ -74,60 +103,59 @@ sp_input_load_from_preferences (void)
 
     for (GList *list_ptr = gdk_devices_list(); list_ptr != NULL; list_ptr = list_ptr->next) {
         GdkDevice *device = static_cast<GdkDevice *>(list_ptr->data);
-        //repr = sp_repr_lookup_child(devices, "id", device->name);
-        Glib::ustring device_path = Glib::ustring("/devices/") + device->name;
-        if (/*repr != NULL*/ 1) {
-            GdkInputMode mode;
-            Glib::ustring device_mode = prefs->getString(device_path + "/mode");
-
-            if (device_mode.empty())
-                mode = GDK_MODE_DISABLED;
-            else if (device_mode == "screen")
-                mode = GDK_MODE_SCREEN;
-            else if (device_mode == "window")
-                mode = GDK_MODE_WINDOW;
-            else
-                mode = GDK_MODE_DISABLED;
-
-            if (device->mode != mode) {
-                gdk_device_set_mode(device, mode);
-            }
 
-            Glib::ustring::size_type pos0, pos1;
-            GdkAxisUse axis_use;
-
-            //temp_ptr = repr->attribute("axes");
-            Glib::ustring const axes_str = prefs->getString(device_path + "/axes");
-            pos0 = pos1 = 0;
-            for (gint i=0; i < device->num_axes; i++) {
-                pos1 = axes_str.find(';', pos0);
-                if (pos1 == Glib::ustring::npos)
-                    break;  // Too few axis specifications
-
-                axis_use = GDK_AXIS_IGNORE;
-                for (gint j=0; j < GDK_AXIS_LAST; j++)
-                    if (!strcmp(axes_str.substr(pos0, pos1-pos0).c_str(), axis_use_strings[j])) {
-                        axis_use = static_cast<GdkAxisUse>(j);
-                        break;
-                    }
-                gdk_device_set_axis_use(device, i, axis_use);
-                pos0 = pos1 + 1;
-            }
+        Glib::ustring device_path = sanitized_device_path(device->name);
 
-            guint keyval;
-            GdkModifierType modifier;
+        GdkInputMode mode;
+        Glib::ustring device_mode = prefs->getString(device_path + "/mode");
 
-            Glib::ustring const keys_str = prefs->getString(device_path + "/keys");
-            pos0 = pos1 = 0;
-            for (gint i=0; i < device->num_keys; i++) {
-                pos1 = keys_str.find(';', pos0);
-                if (pos1 == Glib::ustring::npos)
-                    break;  // Too few key specifications
+        if (device_mode.empty())
+            mode = GDK_MODE_DISABLED;
+        else if (device_mode == "screen")
+            mode = GDK_MODE_SCREEN;
+        else if (device_mode == "window")
+            mode = GDK_MODE_WINDOW;
+        else
+            mode = GDK_MODE_DISABLED;
 
-                gtk_accelerator_parse(keys_str.substr(pos0, pos1-pos0).c_str(), &keyval, &modifier);
-                gdk_device_set_key(device, i, keyval, modifier);
-                pos0 = pos1 + 1;
-            }
+        if (device->mode != mode) {
+            gdk_device_set_mode(device, mode);
+        }
+
+        Glib::ustring::size_type pos0, pos1;
+        GdkAxisUse axis_use;
+
+        //temp_ptr = repr->attribute("axes");
+        Glib::ustring const axes_str = prefs->getString(device_path + "/axes");
+        pos0 = pos1 = 0;
+        for (gint i=0; i < device->num_axes; i++) {
+            pos1 = axes_str.find(';', pos0);
+            if (pos1 == Glib::ustring::npos)
+                break;  // Too few axis specifications
+
+            axis_use = GDK_AXIS_IGNORE;
+            for (gint j=0; j < GDK_AXIS_LAST; j++)
+                if (!strcmp(axes_str.substr(pos0, pos1-pos0).c_str(), axis_use_strings[j])) {
+                    axis_use = static_cast<GdkAxisUse>(j);
+                    break;
+                }
+            gdk_device_set_axis_use(device, i, axis_use);
+            pos0 = pos1 + 1;
+        }
+
+        guint keyval;
+        GdkModifierType modifier;
+
+        Glib::ustring const keys_str = prefs->getString(device_path + "/keys");
+        pos0 = pos1 = 0;
+        for (gint i=0; i < device->num_keys; i++) {
+            pos1 = keys_str.find(';', pos0);
+            if (pos1 == Glib::ustring::npos)
+                break;  // Too few key specifications
+
+            gtk_accelerator_parse(keys_str.substr(pos0, pos1-pos0).c_str(), &keyval, &modifier);
+            gdk_device_set_key(device, i, keyval, modifier);
+            pos0 = pos1 + 1;
         }
     }
 }
@@ -140,8 +168,7 @@ sp_input_save_to_preferences (void)
     for (GList *list_ptr = gdk_devices_list(); list_ptr != NULL; list_ptr = list_ptr->next) {
         GdkDevice *device = static_cast<GdkDevice *>(list_ptr->data);
 
-        //repr = sp_repr_lookup_child(devices, "id", device->name);
-        Glib::ustring device_path = Glib::ustring("/devices/") + device->name;
+        Glib::ustring device_path = sanitized_device_path(device->name);
 
         switch (device->mode) {
             default: