summaryrefslogtreecommitdiffstats
path: root/src/dialogs/input.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dialogs/input.cpp')
-rw-r--r--src/dialogs/input.cpp273
1 files changed, 273 insertions, 0 deletions
diff --git a/src/dialogs/input.cpp b/src/dialogs/input.cpp
new file mode 100644
index 000000000..da8eba196
--- /dev/null
+++ b/src/dialogs/input.cpp
@@ -0,0 +1,273 @@
+#define __SP_INPUT_C__
+
+/*
+ * Extended input devices dialog
+ *
+ * Authors:
+ * Nicklas Lindgren <nili@lysator.liu.se>
+ *
+ * Copyright (C) 2005 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <gtk/gtk.h>
+
+#include "../inkscape.h"
+#include "../macros.h"
+#include "../verbs.h"
+#include "../interface.h"
+#include "../xml/repr.h"
+
+#include "dialog-events.h"
+#include "../prefs-utils.h"
+
+
+static GtkWidget *dlg = NULL;
+static win_data wd;
+
+// impossible original values to make sure they are read from prefs
+static gint x = -1000, y = -1000, w = 0, h = 0;
+static gchar *prefs_path = "dialogs.input";
+
+static void
+sp_input_dialog_destroy (GtkObject *object, gpointer data)
+{
+ sp_signal_disconnect_by_data (INKSCAPE, dlg);
+ wd.win = dlg = NULL;
+ wd.stop = 0;
+}
+
+static gboolean
+sp_input_dialog_delete (GtkObject *object, GdkEvent *event, gpointer data)
+{
+ gtk_window_get_position ((GtkWindow *) dlg, &x, &y);
+ gtk_window_get_size ((GtkWindow *) dlg, &w, &h);
+
+ prefs_set_int_attribute (prefs_path, "x", x);
+ prefs_set_int_attribute (prefs_path, "y", y);
+ prefs_set_int_attribute (prefs_path, "w", w);
+ prefs_set_int_attribute (prefs_path, "h", h);
+
+ return FALSE; // which means, go ahead and destroy it
+
+}
+
+static gchar *axis_use_strings[GDK_AXIS_LAST] = {
+ "ignore", "x", "y", "pressure", "xtilt", "ytilt", "wheel"
+};
+
+void
+sp_input_load_from_preferences (void)
+{
+ Inkscape::XML::Node *devices = inkscape_get_repr(INKSCAPE, "devices");
+ if (devices == NULL)
+ return;
+
+ Inkscape::XML::Node *repr;
+ GList *list_ptr;
+
+ for (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);
+ if (repr != NULL) {
+ GdkInputMode mode;
+ const gchar *attribute = repr->attribute("mode");
+
+ if (attribute == NULL)
+ mode = GDK_MODE_DISABLED;
+ else if (!strcmp(attribute, "screen"))
+ mode = GDK_MODE_SCREEN;
+ else if (!strcmp(attribute, "window"))
+ mode = GDK_MODE_WINDOW;
+ else
+ mode = GDK_MODE_DISABLED;
+
+ if (device->mode != mode) {
+ gdk_device_set_mode(device, mode);
+ }
+
+ const gchar *temp_ptr;
+ std::string::size_type pos0;
+ std::string::size_type pos1;
+ gint i;
+ gint j;
+
+ GdkAxisUse axis_use;
+
+ temp_ptr = repr->attribute("axes");
+ if (temp_ptr != NULL) {
+ const std::string temp_str = temp_ptr;
+ pos0 = pos1 = 0;
+ for (i=0; i < device->num_axes; i++) {
+ pos1 = temp_str.find(";", pos0);
+ if (pos1 == std::string::npos)
+ break; // Too few axis specifications
+
+ axis_use = GDK_AXIS_IGNORE;
+ for (j=0; j < GDK_AXIS_LAST; j++)
+ if (!strcmp(temp_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;
+
+ temp_ptr = repr->attribute("keys");
+ if (temp_ptr != NULL) {
+ const std::string temp_str = temp_ptr;
+ pos0 = pos1 = 0;
+ for (i=0; i < device->num_keys; i++) {
+ pos1 = temp_str.find(";", pos0);
+ if (pos1 == std::string::npos)
+ break; // Too few key specifications
+
+ gtk_accelerator_parse(temp_str.substr(pos0, pos1-pos0).c_str(), &keyval, &modifier);
+ gdk_device_set_key(device, i, keyval, modifier);
+ pos0 = pos1 + 1;
+ }
+ }
+ }
+ }
+}
+
+void
+sp_input_save_to_preferences (void)
+{
+ Inkscape::XML::Node *devices = inkscape_get_repr(INKSCAPE, "devices");
+ if (devices == NULL)
+ // TODO: find a clean way to add a node to the preferences root, or
+ // give an error message
+ return;
+
+ Inkscape::XML::Node *repr;
+ GList *list_ptr;
+
+ for (list_ptr = gdk_devices_list(); list_ptr != NULL; list_ptr = list_ptr->next) {
+ gint i;
+ std::string temp_attribute;
+ GdkDevice *device = static_cast<GdkDevice *>(list_ptr->data);
+
+ repr = sp_repr_lookup_child(devices, "id", device->name);
+ if (repr == NULL) {
+ repr = sp_repr_new("group");
+ repr->setAttribute("id", device->name);
+ devices->appendChild(repr);
+ Inkscape::GC::release(repr);
+ }
+ switch (device->mode) {
+ default:
+ case GDK_MODE_DISABLED: {
+ repr->setAttribute("mode", "disabled");
+ break;
+ }
+ case GDK_MODE_SCREEN: {
+ repr->setAttribute("mode", "screen");
+ break;
+ }
+ case GDK_MODE_WINDOW: {
+ repr->setAttribute("mode", "window");
+ break;
+ }
+ }
+
+ temp_attribute = "";
+ for (i=0; i < device->num_axes; i++) {
+ temp_attribute += axis_use_strings[device->axes[i].use];
+ temp_attribute += ";";
+ }
+ repr->setAttribute("axes", temp_attribute.c_str());
+
+ temp_attribute = "";
+ for (i=0; i < device->num_keys; i++) {
+ temp_attribute += gtk_accelerator_name(device->keys[i].keyval, device->keys[i].modifiers);
+ temp_attribute += ";";
+ }
+ repr->setAttribute("keys", temp_attribute.c_str());
+ }
+}
+
+static void
+sp_input_save_button (GtkObject *object, gpointer data)
+{
+ sp_input_save_to_preferences();
+}
+
+/**
+ * \brief Dialog
+ *
+ */
+void
+sp_input_dialog (void)
+{
+ if (dlg == NULL) {
+
+ gchar title[500];
+ sp_ui_dialog_title_string (Inkscape::Verb::get(SP_VERB_DIALOG_INPUT), title);
+
+ dlg = gtk_input_dialog_new();
+
+ if (x == -1000 || y == -1000) {
+ x = prefs_get_int_attribute (prefs_path, "x", 0);
+ y = prefs_get_int_attribute (prefs_path, "y", 0);
+ }
+
+ if (w ==0 || h == 0) {
+ w = prefs_get_int_attribute (prefs_path, "w", 0);
+ h = prefs_get_int_attribute (prefs_path, "h", 0);
+ }
+
+ if (x != 0 || y != 0) {
+ gtk_window_move ((GtkWindow *) dlg, x, y);
+ } else {
+ gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
+ }
+
+ if (w && h) {
+ gtk_window_resize ((GtkWindow *) dlg, w, h);
+ }
+
+ sp_transientize (dlg);
+ wd.win = dlg;
+ wd.stop = 0;
+
+ g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_transientize_callback), &wd);
+ gtk_signal_connect ( GTK_OBJECT (dlg), "event", GTK_SIGNAL_FUNC (sp_dialog_event_handler), dlg);
+ gtk_signal_connect ( GTK_OBJECT (dlg), "destroy", G_CALLBACK (sp_input_dialog_destroy), dlg);
+ gtk_signal_connect ( GTK_OBJECT (dlg), "delete_event", G_CALLBACK (sp_input_dialog_delete), dlg);
+ g_signal_connect ( G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (sp_input_dialog_delete), dlg);
+ g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_hide", G_CALLBACK (sp_dialog_hide), dlg);
+ g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_unhide", G_CALLBACK (sp_dialog_unhide), dlg);
+
+ // Dialog-specific stuff
+ gtk_signal_connect_object (GTK_OBJECT(GTK_INPUT_DIALOG(dlg)->close_button),
+ "clicked",
+ (GtkSignalFunc)gtk_widget_destroy,
+ GTK_OBJECT(dlg));
+ gtk_signal_connect (GTK_OBJECT(GTK_INPUT_DIALOG(dlg)->save_button),
+ "clicked",
+ (GtkSignalFunc)sp_input_save_button, NULL);
+ }
+
+ gtk_window_present ((GtkWindow *) dlg);
+}
+
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :