From bf6db039afcd3370d8c8c2c216b7a3348c4ac1b9 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sat, 13 Mar 2010 18:18:39 -0800 Subject: [PATCH] Minor cleanup and addition of tablet debugging code. --- src/dialogs/input.cpp | 319 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 296 insertions(+), 23 deletions(-) diff --git a/src/dialogs/input.cpp b/src/dialogs/input.cpp index a8892bde4..d34655ecc 100644 --- a/src/dialogs/input.cpp +++ b/src/dialogs/input.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include "macros.h" #include "verbs.h" @@ -36,6 +37,74 @@ static win_data wd; static gint x = -1000, y = -1000, w = 0, h = 0; static Glib::ustring const prefs_path = "/dialogs/input/"; +#define noTEST_WITH_GOOD_TABLET 1 +#define noTEST_WITH_BAD_TABLET 1 + +#if defined(TEST_WITH_GOOD_TABLET) || defined(TEST_WITH_BAD_TABLET) +static int testDeviceCount = 0; +static GdkDevice* testDevices = 0; + +// Defined at the end of the file to keep debugging out of the way. +static void initTestDevices(); +#endif + +static std::list getInputDevices() +{ + std::list devices; + +#if defined(TEST_WITH_GOOD_TABLET) || defined(TEST_WITH_BAD_TABLET) + initTestDevices(); + for (int i = 0; i < testDeviceCount; i++) { + devices.push_back(&testDevices[i]); + } +#else + for (GList *ptr = gdk_devices_list(); ptr; ptr = ptr->next) { + GdkDevice *device = static_cast(ptr->data); + devices.push_back(device); + } +#endif + + return devices; +} + +// wrap these GDK calls to be able to intercept for testing. + +static bool setDeviceMode( GdkDevice *device, GdkInputMode mode ) +{ +#if defined(TEST_WITH_GOOD_TABLET) || defined(TEST_WITH_BAD_TABLET) + (void)device; + (void)mode; + bool retVal = true; // Can't let the Gdk call be called with bad data +#else + bool retVal = gdk_device_set_mode(device, mode); +#endif + return retVal; +} + +static void setDeviceAxisUse( GdkDevice *device, guint index, GdkAxisUse use ) +{ +#if defined(TEST_WITH_GOOD_TABLET) && !defined(TEST_WITH_BAD_TABLET) + (void)device; + (void)index; + (void)use; +#else + gdk_device_set_axis_use(device, index, use); +#endif +} + +static void setDeviceKey( GdkDevice* device, guint index, guint keyval, GdkModifierType modifiers ) +{ +#if defined(TEST_WITH_GOOD_TABLET) && !defined(TEST_WITH_BAD_TABLET) + (void)device; + (void)index; + (void)keyval; + (void)modifiers; +#else + gdk_device_set_key(device, index, keyval, modifiers); +#endif +} + + static void sp_input_dialog_destroy (GtkObject */*object*/, gpointer /*data*/) { @@ -76,11 +145,12 @@ static Glib::ustring sanitized_device_path(gchar const *str) // 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) { + + if (!str || (*str == 0)) { broken = true; } else { for (gchar const *s = str; *s; ++s) { - if (*s < 0x20 || *s >= 0x7f) { + if ((*s < 0x20) || (*s >= 0x7f)) { broken = true; break; } @@ -96,30 +166,36 @@ static Glib::ustring sanitized_device_path(gchar const *str) return device_path; } -void -sp_input_load_from_preferences (void) +void sp_input_load_from_preferences(void) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - for (GList *list_ptr = gdk_devices_list(); list_ptr != NULL; list_ptr = list_ptr->next) { - GdkDevice *device = static_cast(list_ptr->data); + std::list devices = getInputDevices(); + for (std::list::iterator it = devices.begin(); it != devices.end(); ++it) { + GdkDevice *device = *it; + +// g_message(" s:%d m:%d hc:%d a:%d k:%d [%s]", device->source, device->mode, device->has_cursor, device->num_axes, device->num_keys, device->name); +// for (int i = 0; i < device->num_axes; i++) { +// GdkDeviceAxis &axis = device->axes[i]; +// g_message(" axis[%d] u:%d min:%f max:%f", i, axis.use, axis.min, axis.max); +// } Glib::ustring device_path = sanitized_device_path(device->name); +// if (device_path != (Glib::ustring("/devices/") + device->name)) { +// g_message(" re-name [%s]", device_path.c_str()); +// } - GdkInputMode mode; Glib::ustring device_mode = prefs->getString(device_path + "/mode"); - if (device_mode.empty()) - mode = GDK_MODE_DISABLED; - else if (device_mode == "screen") + GdkInputMode mode = GDK_MODE_DISABLED; + if (device_mode == "screen") { mode = GDK_MODE_SCREEN; - else if (device_mode == "window") + } else if (device_mode == "window") { mode = GDK_MODE_WINDOW; - else - mode = GDK_MODE_DISABLED; + } if (device->mode != mode) { - gdk_device_set_mode(device, mode); + setDeviceMode(device, mode); } Glib::ustring::size_type pos0, pos1; @@ -130,16 +206,18 @@ sp_input_load_from_preferences (void) pos0 = pos1 = 0; for (gint i=0; i < device->num_axes; i++) { pos1 = axes_str.find(';', pos0); - if (pos1 == Glib::ustring::npos) + if (pos1 == Glib::ustring::npos) { break; // Too few axis specifications + } axis_use = GDK_AXIS_IGNORE; - for (gint j=0; j < GDK_AXIS_LAST; j++) + 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(j); break; } - gdk_device_set_axis_use(device, i, axis_use); + } + setDeviceAxisUse(device, i, axis_use); pos0 = pos1 + 1; } @@ -150,23 +228,24 @@ sp_input_load_from_preferences (void) pos0 = pos1 = 0; for (gint i=0; i < device->num_keys; i++) { pos1 = keys_str.find(';', pos0); - if (pos1 == Glib::ustring::npos) + 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); + setDeviceKey(device, i, keyval, modifier); pos0 = pos1 + 1; } } } -void -sp_input_save_to_preferences (void) +void sp_input_save_to_preferences(void) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - for (GList *list_ptr = gdk_devices_list(); list_ptr != NULL; list_ptr = list_ptr->next) { - GdkDevice *device = static_cast(list_ptr->data); + std::list devices = getInputDevices(); + for (std::list::iterator it = devices.begin(); it != devices.end(); ++it) { + GdkDevice *device = *it; Glib::ustring device_path = sanitized_device_path(device->name); @@ -267,6 +346,200 @@ sp_input_dialog (void) gtk_window_present ((GtkWindow *) dlg); } +// ///////////////////////////////// +// For debugging: +// ///////////////////////////////// + + +#if defined(TEST_WITH_GOOD_TABLET) +static void initTestDevices() +{ + static bool init = false; + if (!init) { + static GdkDevice devs[5] = {}; + int i = 0; // use variable instead of constant to allow devices to be moved around, commented out, etc. + + { + // Laptop trackpad + devs[i].name = g_strdup("pointer"); + devs[i].source = GDK_SOURCE_MOUSE; + devs[i].mode = GDK_MODE_DISABLED; + devs[i].has_cursor = 0; + static GdkDeviceAxis tmp[] = {{GDK_AXIS_X, 0, 0}, + {GDK_AXIS_Y, 0, 0}}; + devs[i].num_axes = G_N_ELEMENTS(tmp); + devs[i].axes = tmp; + devs[i].num_keys = 0; + devs[i].keys = 0; + i++; + } + + { + // Tablet stylus + devs[i].name = g_strdup("pen"); + devs[i].source = GDK_SOURCE_PEN; + devs[i].mode = GDK_MODE_DISABLED; + devs[i].has_cursor = 0; + static GdkDeviceAxis tmp[] = {{GDK_AXIS_X, 0, 0}, + {GDK_AXIS_Y, 0, 0}, + {GDK_AXIS_PRESSURE, 0, 1}, + {GDK_AXIS_XTILT, -1, 1}, + {GDK_AXIS_YTILT, -1, 1}}; + devs[i].num_axes = G_N_ELEMENTS(tmp); + devs[i].axes = tmp; + devs[i].num_keys = 0; + devs[i].keys = 0; + i++; + } + + { + // Puck + devs[i].name = g_strdup("cursor"); + devs[i].source = GDK_SOURCE_CURSOR; + devs[i].mode = GDK_MODE_DISABLED; + devs[i].has_cursor = 0; + static GdkDeviceAxis tmp[] = {{GDK_AXIS_X, 0, 0}, + {GDK_AXIS_Y, 0, 0}, + {GDK_AXIS_PRESSURE, 0, 1}, + {GDK_AXIS_XTILT, -1, 1}, + {GDK_AXIS_YTILT, -1, 1}}; + devs[i].num_axes = G_N_ELEMENTS(tmp); + devs[i].axes = tmp; + devs[i].num_keys = 0; + devs[i].keys = 0; + i++; + } + + { + // Back of tablet stylus + devs[i].name = g_strdup("eraser"); + devs[i].source = GDK_SOURCE_ERASER; + devs[i].mode = GDK_MODE_DISABLED; + devs[i].has_cursor = 0; + static GdkDeviceAxis tmp[] = {{GDK_AXIS_X, 0, 0}, + {GDK_AXIS_Y, 0, 0}, + {GDK_AXIS_PRESSURE, 0, 1}, + {GDK_AXIS_XTILT, -1, 1}, + {GDK_AXIS_YTILT, -1, 1}}; + devs[i].num_axes = G_N_ELEMENTS(tmp); + devs[i].axes = tmp; + devs[i].num_keys = 0; + devs[i].keys = 0; + i++; + } + + { + // Main (composit) mouse device + devs[i].name = g_strdup("Core Pointer"); + devs[i].source = GDK_SOURCE_MOUSE; + devs[i].mode = GDK_MODE_SCREEN; + devs[i].has_cursor = 1; + static GdkDeviceAxis tmp[] = {{GDK_AXIS_X, 0, 0}, + {GDK_AXIS_Y, 0, 0}}; + devs[i].num_axes = G_N_ELEMENTS(tmp); + devs[i].axes = tmp; + devs[i].num_keys = 0; + devs[i].keys = 0; + i++; + } + + testDeviceCount = i; + testDevices = devs; + init = true; + } +} +#elif defined(TEST_WITH_BAD_TABLET) + +/** + * Uses the current time in seconds to change a name to be unique from one + * run of the program to the next. + */ +void perturbName(gchar *str) +{ + if (str) { + GTimeVal when = {0,0}; + g_get_current_time(&when); + gchar *tmp = g_strdup_printf("%ld", when.tv_sec); + + size_t partLen = strlen(tmp); + size_t len = strlen(str); + if (len > (partLen + 4)) { + size_t pos = (len - partLen) / 2; + for (size_t i = 0; i < partLen; i++) { + str[pos + i] = tmp[i]; + } + } + g_free(tmp); + } +} + +static void initTestDevices() +{ + static bool init = false; + if (!init) { + static GdkDevice devs[5] = {}; + int i = 0; // use variable instead of constant to allow devices to be moved around, commented out, etc. + + { + // Main (composit) mouse device + devs[i].name = g_strdup("Core Pointer"); + devs[i].source = GDK_SOURCE_MOUSE; + devs[i].mode = GDK_MODE_SCREEN; + devs[i].has_cursor = 1; + static GdkDeviceAxis tmp[] = {{GDK_AXIS_X, 0, 0}, + {GDK_AXIS_Y, 0, 0}}; + devs[i].num_axes = G_N_ELEMENTS(tmp); + devs[i].axes = tmp; + devs[i].num_keys = 0; + devs[i].keys = 0; + i++; + } + + { + // Back of tablet stylus + devs[i].name = g_strdup("\346\205\227\347\221\254\347\201\257\345\220\240\346\211\241\346\225\254t\303\265\006 \347\211\220\347\215\245\347\225\263\346\225\262\345\214\240\347\245\264\347\225\254s\357\227\230#\354\234\274C\356\232\210\307\255\350\271\214\310\201\350\222\200\310\201\356\202\250\310\200\350\223\260\310\201\356\202\250\310\200"); + perturbName(devs[i].name); + devs[i].source = GDK_SOURCE_ERASER; + devs[i].mode = GDK_MODE_DISABLED; + devs[i].has_cursor = 0; + static GdkDeviceAxis tmp[] = {{GDK_AXIS_X, 0, 0}, + {GDK_AXIS_Y, 0, 0}, + {GDK_AXIS_PRESSURE, 0, 1}, + {GDK_AXIS_XTILT, -1, 1}, + {GDK_AXIS_YTILT, -1, 1}}; + devs[i].num_axes = G_N_ELEMENTS(tmp); + devs[i].axes = tmp; + devs[i].num_keys = 0; + devs[i].keys = 0; + i++; + } + + { + // Tablet stylus + devs[i].name = g_strdup("\346\205\227\347\221\254\347\201\257\345\220\240\346\211\241\346\225\254t\303\265\006 \347\211\220\347\215\245\347\225\263\346\225\262\345\214\240\347\245\264\347\225\254s\357\227\230#\354\234\274C\341\221\230\307\255\343\277\214\310\202\343\230\200\310\202\331\270\310\202\343\231\260\310\202\331\270\310\202"); + perturbName(devs[i].name); + devs[i].source = GDK_SOURCE_PEN; + devs[i].mode = GDK_MODE_DISABLED; + devs[i].has_cursor = 0; + static GdkDeviceAxis tmp[] = {{GDK_AXIS_X, 0, 0}, + {GDK_AXIS_Y, 0, 0}, + {GDK_AXIS_PRESSURE, 0, 1}, + {GDK_AXIS_XTILT, -1, 1}, + {GDK_AXIS_YTILT, -1, 1}}; + devs[i].num_axes = G_N_ELEMENTS(tmp); + devs[i].axes = tmp; + devs[i].num_keys = 0; + devs[i].keys = 0; + i++; + } + + testDeviceCount = i; + testDevices = devs; + init = true; + } +} +#endif + /* Local Variables: -- 2.30.2