1 /** @file
2 * @brief Extended input devices dialog
3 */
4 /* Authors:
5 * Nicklas Lindgren <nili@lysator.liu.se>
6 * Johan Engelen <goejendaagh@zonnet.nl>
7 *
8 * Copyright (C) 2005-2006 Authors
9 *
10 * Released under GNU GPL, read the file 'COPYING' for more information
11 */
13 #ifdef HAVE_CONFIG_H
14 # include <config.h>
15 #endif
17 #include <gtk/gtksignal.h>
18 #include <gtk/gtkinputdialog.h>
19 #include <glibmm/ustring.h>
21 #include "macros.h"
22 #include "verbs.h"
23 #include "inkscape.h"
24 #include "interface.h"
25 #include "xml/repr.h"
27 #include "dialogs/dialog-events.h"
28 #include "preferences.h"
30 #define MIN_ONSCREEN_DISTANCE 50
32 static GtkWidget *dlg = NULL;
33 static win_data wd;
35 // impossible original values to make sure they are read from prefs
36 static gint x = -1000, y = -1000, w = 0, h = 0;
37 static Glib::ustring const prefs_path = "/dialogs/input/";
39 static void
40 sp_input_dialog_destroy (GtkObject */*object*/, gpointer /*data*/)
41 {
42 sp_signal_disconnect_by_data (INKSCAPE, dlg);
43 wd.win = dlg = NULL;
44 wd.stop = 0;
45 }
47 static gboolean
48 sp_input_dialog_delete (GtkObject */*object*/, GdkEvent */*event*/, gpointer /*data*/)
49 {
50 Inkscape::Preferences *prefs = Inkscape::Preferences::get();
51 gtk_window_get_position ((GtkWindow *) dlg, &x, &y);
52 gtk_window_get_size ((GtkWindow *) dlg, &w, &h);
54 if (x<0) x=0;
55 if (y<0) y=0;
57 prefs->setInt(prefs_path + "x", x);
58 prefs->setInt(prefs_path + "y", y);
59 prefs->setInt(prefs_path + "w", w);
60 prefs->setInt(prefs_path + "h", h);
62 return FALSE; // which means, go ahead and destroy it
64 }
66 static const gchar *axis_use_strings[GDK_AXIS_LAST] = {
67 "ignore", "x", "y", "pressure", "xtilt", "ytilt", "wheel"
68 };
70 void
71 sp_input_load_from_preferences (void)
72 {
73 Inkscape::Preferences *prefs = Inkscape::Preferences::get();
75 for (GList *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 Glib::ustring device_path = Glib::ustring("/devices/") + device->name;
79 if (/*repr != NULL*/ 1) {
80 GdkInputMode mode;
81 Glib::ustring device_mode = prefs->getString(device_path + "/mode");
83 if (device_mode.empty())
84 mode = GDK_MODE_DISABLED;
85 else if (device_mode == "screen")
86 mode = GDK_MODE_SCREEN;
87 else if (device_mode == "window")
88 mode = GDK_MODE_WINDOW;
89 else
90 mode = GDK_MODE_DISABLED;
92 if (device->mode != mode) {
93 gdk_device_set_mode(device, mode);
94 }
96 Glib::ustring::size_type pos0, pos1;
97 GdkAxisUse axis_use;
99 //temp_ptr = repr->attribute("axes");
100 Glib::ustring const axes_str = prefs->getString(device_path + "/axes");
101 pos0 = pos1 = 0;
102 for (gint i=0; i < device->num_axes; i++) {
103 pos1 = axes_str.find(';', pos0);
104 if (pos1 == Glib::ustring::npos)
105 break; // Too few axis specifications
107 axis_use = GDK_AXIS_IGNORE;
108 for (gint j=0; j < GDK_AXIS_LAST; j++)
109 if (!strcmp(axes_str.substr(pos0, pos1-pos0).c_str(), axis_use_strings[j])) {
110 axis_use = static_cast<GdkAxisUse>(j);
111 break;
112 }
113 gdk_device_set_axis_use(device, i, axis_use);
114 pos0 = pos1 + 1;
115 }
117 guint keyval;
118 GdkModifierType modifier;
120 Glib::ustring const keys_str = prefs->getString(device_path + "/keys");
121 pos0 = pos1 = 0;
122 for (gint i=0; i < device->num_keys; i++) {
123 pos1 = keys_str.find(';', pos0);
124 if (pos1 == Glib::ustring::npos)
125 break; // Too few key specifications
127 gtk_accelerator_parse(keys_str.substr(pos0, pos1-pos0).c_str(), &keyval, &modifier);
128 gdk_device_set_key(device, i, keyval, modifier);
129 pos0 = pos1 + 1;
130 }
131 }
132 }
133 }
135 void
136 sp_input_save_to_preferences (void)
137 {
138 Inkscape::Preferences *prefs = Inkscape::Preferences::get();
140 for (GList *list_ptr = gdk_devices_list(); list_ptr != NULL; list_ptr = list_ptr->next) {
141 GdkDevice *device = static_cast<GdkDevice *>(list_ptr->data);
143 //repr = sp_repr_lookup_child(devices, "id", device->name);
144 Glib::ustring device_path = Glib::ustring("/devices/") + device->name;
146 switch (device->mode) {
147 default:
148 case GDK_MODE_DISABLED: {
149 prefs->setString(device_path + "/mode", "disabled");
150 break;
151 }
152 case GDK_MODE_SCREEN: {
153 prefs->setString(device_path + "/mode", "screen");
154 break;
155 }
156 case GDK_MODE_WINDOW: {
157 prefs->setString(device_path + "/mode", "window");
158 break;
159 }
160 }
162 Glib::ustring temp_attribute = "";
163 for (gint i=0; i < device->num_axes; i++) {
164 temp_attribute += axis_use_strings[device->axes[i].use];
165 temp_attribute += ";";
166 }
167 prefs->setString(device_path + "/axes", temp_attribute);
169 temp_attribute = "";
170 for (gint i=0; i < device->num_keys; i++) {
171 temp_attribute += gtk_accelerator_name(device->keys[i].keyval, device->keys[i].modifiers);
172 temp_attribute += ";";
173 }
174 prefs->setString(device_path + "/keys", temp_attribute);
175 }
176 }
178 static void
179 sp_input_save_button (GtkObject */*object*/, gpointer /*data*/)
180 {
181 sp_input_save_to_preferences();
182 }
184 void
185 sp_input_dialog (void)
186 {
187 if (dlg == NULL) {
188 Inkscape::Preferences *prefs = Inkscape::Preferences::get();
190 gchar title[500];
191 sp_ui_dialog_title_string (Inkscape::Verb::get(SP_VERB_DIALOG_INPUT), title);
193 dlg = gtk_input_dialog_new();
195 if (x == -1000 || y == -1000) {
196 x = prefs->getInt(prefs_path + "x", -1000);
197 y = prefs->getInt(prefs_path + "y", -1000);
198 }
200 if (w ==0 || h == 0) {
201 w = prefs->getInt(prefs_path + "w", 0);
202 h = prefs->getInt(prefs_path + "h", 0);
203 }
205 // if (x<0) x=0;
206 // if (y<0) y=0;
208 if (w && h) {
209 gtk_window_resize ((GtkWindow *) dlg, w, h);
210 }
211 if (x >= 0 && y >= 0 && (x < (gdk_screen_width()-MIN_ONSCREEN_DISTANCE)) && (y < (gdk_screen_height()-MIN_ONSCREEN_DISTANCE))) {
212 gtk_window_move ((GtkWindow *) dlg, x, y);
213 } else {
214 gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
215 }
218 sp_transientize (dlg);
219 wd.win = dlg;
220 wd.stop = 0;
222 g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_transientize_callback), &wd);
223 gtk_signal_connect ( GTK_OBJECT (dlg), "event", GTK_SIGNAL_FUNC (sp_dialog_event_handler), dlg);
224 gtk_signal_connect ( GTK_OBJECT (dlg), "destroy", G_CALLBACK (sp_input_dialog_destroy), dlg);
225 gtk_signal_connect ( GTK_OBJECT (dlg), "delete_event", G_CALLBACK (sp_input_dialog_delete), dlg);
226 g_signal_connect ( G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (sp_input_dialog_delete), dlg);
227 g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_hide", G_CALLBACK (sp_dialog_hide), dlg);
228 g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_unhide", G_CALLBACK (sp_dialog_unhide), dlg);
230 // Dialog-specific stuff
231 gtk_signal_connect_object (GTK_OBJECT(GTK_INPUT_DIALOG(dlg)->close_button),
232 "clicked",
233 (GtkSignalFunc)gtk_widget_destroy,
234 GTK_OBJECT(dlg));
235 gtk_signal_connect (GTK_OBJECT(GTK_INPUT_DIALOG(dlg)->save_button),
236 "clicked",
237 (GtkSignalFunc)sp_input_save_button, NULL);
238 }
240 gtk_window_present ((GtkWindow *) dlg);
241 }
244 /*
245 Local Variables:
246 mode:c++
247 c-file-style:"stroustrup"
248 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
249 indent-tabs-mode:nil
250 fill-column:99
251 End:
252 */
253 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :