Code

moving trunk for module inkscape
[inkscape.git] / src / dialogs / input.cpp
1 #define __SP_INPUT_C__
3 /*
4  * Extended input devices dialog
5  *
6  * Authors:
7  *   Nicklas Lindgren <nili@lysator.liu.se>
8  *
9  * Copyright (C) 2005 Authors
10  *
11  * Released under GNU GPL, read the file 'COPYING' for more information
12  */
14 #ifdef HAVE_CONFIG_H
15 # include "config.h"
16 #endif
17 #include <gtk/gtk.h>
19 #include "../inkscape.h"
20 #include "../macros.h"
21 #include "../verbs.h"
22 #include "../interface.h"
23 #include "../xml/repr.h"
25 #include "dialog-events.h"
26 #include "../prefs-utils.h"
29 static GtkWidget *dlg = NULL;
30 static win_data wd;
32 // impossible original values to make sure they are read from prefs
33 static gint x = -1000, y = -1000, w = 0, h = 0;
34 static gchar *prefs_path = "dialogs.input";
36 static void
37 sp_input_dialog_destroy (GtkObject *object, gpointer data)
38 {
39     sp_signal_disconnect_by_data (INKSCAPE, dlg);
40     wd.win = dlg = NULL;
41     wd.stop = 0;
42 }
44 static gboolean
45 sp_input_dialog_delete (GtkObject *object, GdkEvent *event, gpointer data)
46 {
47     gtk_window_get_position ((GtkWindow *) dlg, &x, &y);
48     gtk_window_get_size ((GtkWindow *) dlg, &w, &h);
50     prefs_set_int_attribute (prefs_path, "x", x);
51     prefs_set_int_attribute (prefs_path, "y", y);
52     prefs_set_int_attribute (prefs_path, "w", w);
53     prefs_set_int_attribute (prefs_path, "h", h);
55     return FALSE; // which means, go ahead and destroy it
57 }
59 static gchar *axis_use_strings[GDK_AXIS_LAST] = {
60     "ignore", "x", "y", "pressure", "xtilt", "ytilt", "wheel"
61 };
63 void
64 sp_input_load_from_preferences (void)
65 {
66     Inkscape::XML::Node *devices = inkscape_get_repr(INKSCAPE, "devices");
67     if (devices == NULL)
68         return;
70     Inkscape::XML::Node *repr;
71     GList *list_ptr;
73     for (list_ptr = gdk_devices_list(); list_ptr != NULL; list_ptr = list_ptr->next) {
74         GdkDevice *device = static_cast<GdkDevice *>(list_ptr->data);
75         repr = sp_repr_lookup_child(devices, "id", device->name);
76         if (repr != NULL) {
77             GdkInputMode mode;
78             const gchar *attribute = repr->attribute("mode");
80             if (attribute == NULL)
81                 mode = GDK_MODE_DISABLED;
82             else if (!strcmp(attribute, "screen"))
83                 mode = GDK_MODE_SCREEN;
84             else if (!strcmp(attribute, "window"))
85                 mode = GDK_MODE_WINDOW;
86             else
87                 mode = GDK_MODE_DISABLED;
89             if (device->mode != mode) {
90                 gdk_device_set_mode(device, mode);
91             }
93             const gchar *temp_ptr;
94             std::string::size_type pos0;
95             std::string::size_type pos1;
96             gint i;
97             gint j;
99             GdkAxisUse axis_use;
101             temp_ptr = repr->attribute("axes");
102             if (temp_ptr != NULL) {
103                 const std::string temp_str = temp_ptr;
104                 pos0 = pos1 = 0;
105                 for (i=0; i < device->num_axes; i++) {
106                     pos1 = temp_str.find(";", pos0);
107                     if (pos1 == std::string::npos)
108                         break;  // Too few axis specifications
110                     axis_use = GDK_AXIS_IGNORE;
111                     for (j=0; j < GDK_AXIS_LAST; j++)
112                         if (!strcmp(temp_str.substr(pos0, pos1-pos0).c_str(), axis_use_strings[j])) {
113                             axis_use = static_cast<GdkAxisUse>(j);
114                             break;
115                         }
116                     gdk_device_set_axis_use(device, i, axis_use);
117                     pos0 = pos1 + 1;
118                 }
119             }
121             guint keyval;
122             GdkModifierType modifier;
124             temp_ptr = repr->attribute("keys");
125             if (temp_ptr != NULL) {
126                 const std::string temp_str = temp_ptr;
127                 pos0 = pos1 = 0;
128                 for (i=0; i < device->num_keys; i++) {
129                     pos1 = temp_str.find(";", pos0);
130                     if (pos1 == std::string::npos)
131                         break;  // Too few key specifications
133                     gtk_accelerator_parse(temp_str.substr(pos0, pos1-pos0).c_str(), &keyval, &modifier);
134                     gdk_device_set_key(device, i, keyval, modifier);
135                     pos0 = pos1 + 1;
136                 }
137             }
138         }
139     }
142 void
143 sp_input_save_to_preferences (void)
145     Inkscape::XML::Node *devices = inkscape_get_repr(INKSCAPE, "devices");
146     if (devices == NULL)
147         // TODO: find a clean way to add a node to the preferences root, or
148         // give an error message
149         return;
151     Inkscape::XML::Node *repr;
152     GList *list_ptr;
154     for (list_ptr = gdk_devices_list(); list_ptr != NULL; list_ptr = list_ptr->next) {
155         gint i;
156         std::string temp_attribute;
157         GdkDevice *device = static_cast<GdkDevice *>(list_ptr->data);
159         repr = sp_repr_lookup_child(devices, "id", device->name);
160         if (repr == NULL) {
161             repr = sp_repr_new("group");
162             repr->setAttribute("id", device->name);
163             devices->appendChild(repr);
164             Inkscape::GC::release(repr);
165         }
166         switch (device->mode) {
167             default:
168             case GDK_MODE_DISABLED: {
169                 repr->setAttribute("mode", "disabled");
170                 break;
171             }
172             case GDK_MODE_SCREEN: {
173                 repr->setAttribute("mode", "screen");
174                 break;
175             }
176             case GDK_MODE_WINDOW: {
177                 repr->setAttribute("mode", "window");
178                 break;
179             }
180         }
182         temp_attribute = "";
183         for (i=0; i < device->num_axes; i++) {
184             temp_attribute += axis_use_strings[device->axes[i].use];
185             temp_attribute += ";";
186         }
187         repr->setAttribute("axes", temp_attribute.c_str());
189         temp_attribute = "";
190         for (i=0; i < device->num_keys; i++) {
191             temp_attribute += gtk_accelerator_name(device->keys[i].keyval, device->keys[i].modifiers);
192             temp_attribute += ";";
193         }
194         repr->setAttribute("keys", temp_attribute.c_str());
195     }
198 static void
199 sp_input_save_button (GtkObject *object, gpointer data)
201     sp_input_save_to_preferences();
204 /**
205  * \brief  Dialog
206  *
207  */
208 void
209 sp_input_dialog (void)
211     if (dlg == NULL) {
213         gchar title[500];
214         sp_ui_dialog_title_string (Inkscape::Verb::get(SP_VERB_DIALOG_INPUT), title);
216         dlg = gtk_input_dialog_new();
218         if (x == -1000 || y == -1000) {
219             x = prefs_get_int_attribute (prefs_path, "x", 0);
220             y = prefs_get_int_attribute (prefs_path, "y", 0);
221         }
223         if (w ==0 || h == 0) {
224             w = prefs_get_int_attribute (prefs_path, "w", 0);
225             h = prefs_get_int_attribute (prefs_path, "h", 0);
226         }
228         if (x != 0 || y != 0) {
229             gtk_window_move ((GtkWindow *) dlg, x, y);
230         } else {
231             gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
232         }
234         if (w && h) {
235             gtk_window_resize ((GtkWindow *) dlg, w, h);
236         }
238         sp_transientize (dlg);
239         wd.win = dlg;
240         wd.stop = 0;
242         g_signal_connect   ( G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_transientize_callback), &wd);
243         gtk_signal_connect ( GTK_OBJECT (dlg), "event", GTK_SIGNAL_FUNC (sp_dialog_event_handler), dlg);
244         gtk_signal_connect ( GTK_OBJECT (dlg), "destroy", G_CALLBACK (sp_input_dialog_destroy), dlg);
245         gtk_signal_connect ( GTK_OBJECT (dlg), "delete_event", G_CALLBACK (sp_input_dialog_delete), dlg);
246         g_signal_connect   ( G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (sp_input_dialog_delete), dlg);
247         g_signal_connect   ( G_OBJECT (INKSCAPE), "dialogs_hide", G_CALLBACK (sp_dialog_hide), dlg);
248         g_signal_connect   ( G_OBJECT (INKSCAPE), "dialogs_unhide", G_CALLBACK (sp_dialog_unhide), dlg);
250         // Dialog-specific stuff
251         gtk_signal_connect_object (GTK_OBJECT(GTK_INPUT_DIALOG(dlg)->close_button),
252                                    "clicked",
253                                    (GtkSignalFunc)gtk_widget_destroy,
254                                    GTK_OBJECT(dlg));
255         gtk_signal_connect (GTK_OBJECT(GTK_INPUT_DIALOG(dlg)->save_button),
256                             "clicked",
257                             (GtkSignalFunc)sp_input_save_button, NULL);
258     }
260     gtk_window_present ((GtkWindow *) dlg);
264 /*
265   Local Variables:
266   mode:c++
267   c-file-style:"stroustrup"
268   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
269   indent-tabs-mode:nil
270   fill-column:99
271   End:
272 */
273 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :