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/gtksignal.h>
18 #include <gtk/gtkinputdialog.h>
19 #include <glibmm/ustring.h>
21 #include "../inkscape.h"
22 #include "../macros.h"
23 #include "../verbs.h"
24 #include "../interface.h"
25 #include "../xml/repr.h"
27 #include "dialog-events.h"
28 #include "../prefs-utils.h"
31 static GtkWidget *dlg = NULL;
32 static win_data wd;
34 // impossible original values to make sure they are read from prefs
35 static gint x = -1000, y = -1000, w = 0, h = 0;
36 static gchar *prefs_path = "dialogs.input";
38 static void
39 sp_input_dialog_destroy (GtkObject *object, gpointer data)
40 {
41 sp_signal_disconnect_by_data (INKSCAPE, dlg);
42 wd.win = dlg = NULL;
43 wd.stop = 0;
44 }
46 static gboolean
47 sp_input_dialog_delete (GtkObject *object, GdkEvent *event, gpointer data)
48 {
49 gtk_window_get_position ((GtkWindow *) dlg, &x, &y);
50 gtk_window_get_size ((GtkWindow *) dlg, &w, &h);
52 prefs_set_int_attribute (prefs_path, "x", x);
53 prefs_set_int_attribute (prefs_path, "y", y);
54 prefs_set_int_attribute (prefs_path, "w", w);
55 prefs_set_int_attribute (prefs_path, "h", h);
57 return FALSE; // which means, go ahead and destroy it
59 }
61 static gchar *axis_use_strings[GDK_AXIS_LAST] = {
62 "ignore", "x", "y", "pressure", "xtilt", "ytilt", "wheel"
63 };
65 void
66 sp_input_load_from_preferences (void)
67 {
68 Inkscape::XML::Node *devices = inkscape_get_repr(INKSCAPE, "devices");
69 if (devices == NULL)
70 return;
72 Inkscape::XML::Node *repr;
73 GList *list_ptr;
75 for (list_ptr = gdk_devices_list(); list_ptr != NULL; list_ptr = list_ptr->next) {
76 GdkDevice *device = static_cast<GdkDevice *>(list_ptr->data);
77 repr = sp_repr_lookup_child(devices, "id", device->name);
78 if (repr != NULL) {
79 GdkInputMode mode;
80 const gchar *attribute = repr->attribute("mode");
82 if (attribute == NULL)
83 mode = GDK_MODE_DISABLED;
84 else if (!strcmp(attribute, "screen"))
85 mode = GDK_MODE_SCREEN;
86 else if (!strcmp(attribute, "window"))
87 mode = GDK_MODE_WINDOW;
88 else
89 mode = GDK_MODE_DISABLED;
91 if (device->mode != mode) {
92 gdk_device_set_mode(device, mode);
93 }
95 const gchar *temp_ptr;
96 Glib::ustring::size_type pos0;
97 Glib::ustring::size_type pos1;
98 gint i;
99 gint j;
101 GdkAxisUse axis_use;
103 temp_ptr = repr->attribute("axes");
104 if (temp_ptr != NULL) {
105 const Glib::ustring temp_str = temp_ptr;
106 pos0 = pos1 = 0;
107 for (i=0; i < device->num_axes; i++) {
108 pos1 = temp_str.find(";", pos0);
109 if (pos1 == Glib::ustring::npos)
110 break; // Too few axis specifications
112 axis_use = GDK_AXIS_IGNORE;
113 for (j=0; j < GDK_AXIS_LAST; j++)
114 if (!strcmp(temp_str.substr(pos0, pos1-pos0).c_str(), axis_use_strings[j])) {
115 axis_use = static_cast<GdkAxisUse>(j);
116 break;
117 }
118 gdk_device_set_axis_use(device, i, axis_use);
119 pos0 = pos1 + 1;
120 }
121 }
123 guint keyval;
124 GdkModifierType modifier;
126 temp_ptr = repr->attribute("keys");
127 if (temp_ptr != NULL) {
128 const Glib::ustring temp_str = temp_ptr;
129 pos0 = pos1 = 0;
130 for (i=0; i < device->num_keys; i++) {
131 pos1 = temp_str.find(";", pos0);
132 if (pos1 == Glib::ustring::npos)
133 break; // Too few key specifications
135 gtk_accelerator_parse(temp_str.substr(pos0, pos1-pos0).c_str(), &keyval, &modifier);
136 gdk_device_set_key(device, i, keyval, modifier);
137 pos0 = pos1 + 1;
138 }
139 }
140 }
141 }
142 }
144 void
145 sp_input_save_to_preferences (void)
146 {
147 Inkscape::XML::Node *devices = inkscape_get_repr(INKSCAPE, "devices");
148 if (devices == NULL)
149 // TODO: find a clean way to add a node to the preferences root, or
150 // give an error message
151 return;
153 Inkscape::XML::Node *repr;
154 GList *list_ptr;
156 for (list_ptr = gdk_devices_list(); list_ptr != NULL; list_ptr = list_ptr->next) {
157 gint i;
158 Glib::ustring temp_attribute;
159 GdkDevice *device = static_cast<GdkDevice *>(list_ptr->data);
161 repr = sp_repr_lookup_child(devices, "id", device->name);
162 if (repr == NULL) {
163 repr = sp_repr_new("group");
164 repr->setAttribute("id", device->name);
165 devices->appendChild(repr);
166 Inkscape::GC::release(repr);
167 }
168 switch (device->mode) {
169 default:
170 case GDK_MODE_DISABLED: {
171 repr->setAttribute("mode", "disabled");
172 break;
173 }
174 case GDK_MODE_SCREEN: {
175 repr->setAttribute("mode", "screen");
176 break;
177 }
178 case GDK_MODE_WINDOW: {
179 repr->setAttribute("mode", "window");
180 break;
181 }
182 }
184 temp_attribute = "";
185 for (i=0; i < device->num_axes; i++) {
186 temp_attribute += axis_use_strings[device->axes[i].use];
187 temp_attribute += ";";
188 }
189 repr->setAttribute("axes", temp_attribute.c_str());
191 temp_attribute = "";
192 for (i=0; i < device->num_keys; i++) {
193 temp_attribute += gtk_accelerator_name(device->keys[i].keyval, device->keys[i].modifiers);
194 temp_attribute += ";";
195 }
196 repr->setAttribute("keys", temp_attribute.c_str());
197 }
198 }
200 static void
201 sp_input_save_button (GtkObject *object, gpointer data)
202 {
203 sp_input_save_to_preferences();
204 }
206 /**
207 * \brief Dialog
208 *
209 */
210 void
211 sp_input_dialog (void)
212 {
213 if (dlg == NULL) {
215 gchar title[500];
216 sp_ui_dialog_title_string (Inkscape::Verb::get(SP_VERB_DIALOG_INPUT), title);
218 dlg = gtk_input_dialog_new();
220 if (x == -1000 || y == -1000) {
221 x = prefs_get_int_attribute (prefs_path, "x", 0);
222 y = prefs_get_int_attribute (prefs_path, "y", 0);
223 }
225 if (w ==0 || h == 0) {
226 w = prefs_get_int_attribute (prefs_path, "w", 0);
227 h = prefs_get_int_attribute (prefs_path, "h", 0);
228 }
230 if (x != 0 || y != 0) {
231 gtk_window_move ((GtkWindow *) dlg, x, y);
232 } else {
233 gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
234 }
236 if (w && h) {
237 gtk_window_resize ((GtkWindow *) dlg, w, h);
238 }
240 sp_transientize (dlg);
241 wd.win = dlg;
242 wd.stop = 0;
244 g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_transientize_callback), &wd);
245 gtk_signal_connect ( GTK_OBJECT (dlg), "event", GTK_SIGNAL_FUNC (sp_dialog_event_handler), dlg);
246 gtk_signal_connect ( GTK_OBJECT (dlg), "destroy", G_CALLBACK (sp_input_dialog_destroy), dlg);
247 gtk_signal_connect ( GTK_OBJECT (dlg), "delete_event", G_CALLBACK (sp_input_dialog_delete), dlg);
248 g_signal_connect ( G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (sp_input_dialog_delete), dlg);
249 g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_hide", G_CALLBACK (sp_dialog_hide), dlg);
250 g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_unhide", G_CALLBACK (sp_dialog_unhide), dlg);
252 // Dialog-specific stuff
253 gtk_signal_connect_object (GTK_OBJECT(GTK_INPUT_DIALOG(dlg)->close_button),
254 "clicked",
255 (GtkSignalFunc)gtk_widget_destroy,
256 GTK_OBJECT(dlg));
257 gtk_signal_connect (GTK_OBJECT(GTK_INPUT_DIALOG(dlg)->save_button),
258 "clicked",
259 (GtkSignalFunc)sp_input_save_button, NULL);
260 }
262 gtk_window_present ((GtkWindow *) dlg);
263 }
266 /*
267 Local Variables:
268 mode:c++
269 c-file-style:"stroustrup"
270 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
271 indent-tabs-mode:nil
272 fill-column:99
273 End:
274 */
275 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :