Code

8e132a2f5bc560764f8bd6a38610ae74bca0123c
[inkscape.git] / src / ui / dialog / input.cpp
3 /* XPM */
4 static char *eraser[] = {
5 /* columns rows colors chars-per-pixel */
6 "16 16 5 1",
7 "  c black",
8 ". c green",
9 "X c #808080",
10 "o c gray100",
11 "O c None",
12 /* pixels */
13 "OOOOOOOOOOOOOOOO",
14 "OOOOOOOOOOOOO OO",
15 "OOOOOOOOOOOO . O",
16 "OOOOOOOOOOO . OO",
17 "OOOOOOOOOO . OOO",
18 "OOOOOOOOO . OOOO",
19 "OOOOOOOO . OOOOO",
20 "OOOOOOOXo OOOOOO",
21 "OOOOOOXoXOOOOOOO",
22 "OOOOOXoXOOOOOOOO",
23 "OOOOXoXOOOOOOOOO",
24 "OOOXoXOOOOOOOOOO",
25 "OOXoXOOOOOOOOOOO",
26 "OOXXOOOOOOOOOOOO",
27 "OOOOOOOOOOOOOOOO",
28 "OOOOOOOOOOOOOOOO"
29 };
31 /* XPM */
32 static char *mouse[] = {
33 /* columns rows colors chars-per-pixel */
34 "16 16 3 1",
35 "  c black",
36 ". c gray100",
37 "X c None",
38 /* pixels */
39 "XXXXXXXXXXXXXXXX",
40 "XXXXXXXXXXXXXXXX",
41 "XXXXXXXXXXXXXXXX",
42 "XXXXXXXXXXXXXXXX",
43 "XXXXXXX  XXXXXXX",
44 "XXXXX  . XXXXXXX",
45 "XXXX .... XXXXXX",
46 "XXXX .... XXXXXX",
47 "XXXXX .... XXXXX",
48 "XXXXX .... XXXXX",
49 "XXXXXX .... XXXX",
50 "XXXXXX .... XXXX",
51 "XXXXXXX .  XXXXX",
52 "XXXXXXX  XXXXXXX",
53 "XXXXXXXXXXXXXXXX",
54 "XXXXXXXXXXXXXXXX"
55 };
57 /* XPM */
58 static char *pen[] = {
59 /* columns rows colors chars-per-pixel */
60 "16 16 3 1",
61 "  c black",
62 ". c gray100",
63 "X c None",
64 /* pixels */
65 "XXXXXXXXXXXXXXXX",
66 "XXXXXXXXXXXXX XX",
67 "XXXXXXXXXXXX . X",
68 "XXXXXXXXXXX . XX",
69 "XXXXXXXXXX . XXX",
70 "XXXXXXXXX . XXXX",
71 "XXXXXXXX . XXXXX",
72 "XXXXXXX . XXXXXX",
73 "XXXXXX . XXXXXXX",
74 "XXXXX . XXXXXXXX",
75 "XXXX . XXXXXXXXX",
76 "XXX . XXXXXXXXXX",
77 "XX . XXXXXXXXXXX",
78 "XX  XXXXXXXXXXXX",
79 "XXXXXXXXXXXXXXXX",
80 "XXXXXXXXXXXXXXXX"
81 };
83 /* XPM */
84 static char *sidebuttons[] = {
85 /* columns rows colors chars-per-pixel */
86 "16 16 4 1",
87 "  c black",
88 ". c #808080",
89 "o c green",
90 "O c None",
91 /* pixels */
92 "OOOOOOOOOOOOOOOO",
93 "OOOOOOOOOOOOOOOO",
94 "O..............O",
95 "O.OOOOOOOOOOOO.O",
96 "O   OOOOOOOO   O",
97 "O o OOOOOOOO o O",
98 "O o OOOOOOOO o O",
99 "O   OOOOOOOO   O",
100 "O.OOOOOOOOOOOO.O",
101 "O.OOOOOOOOOOOO.O",
102 "O.OOOOOOOOOOOO.O",
103 "O.OOOOOOOOOOOO.O",
104 "O.OOOOOOOOOOOO.O",
105 "O..............O",
106 "OOOOOOOOOOOOOOOO",
107 "OOOOOOOOOOOOOOOO"
108 };
110 /* XPM */
111 static char *tablet[] = {
112 /* columns rows colors chars-per-pixel */
113 "16 16 3 1",
114 "  c black",
115 ". c gray100",
116 "X c None",
117 /* pixels */
118 "XXXXXXXXXXXXXXXX",
119 "XXXXXXXXXXXXXXXX",
120 "X              X",
121 "X ............ X",
122 "X ............ X",
123 "X ............ X",
124 "X ............ X",
125 "X ............ X",
126 "X ............ X",
127 "X ............ X",
128 "X ............ X",
129 "X ............ X",
130 "X ............ X",
131 "X              X",
132 "XXXXXXXXXXXXXXXX",
133 "XXXXXXXXXXXXXXXX"
134 };
136 /* XPM */
137 static char *tip[] = {
138 /* columns rows colors chars-per-pixel */
139 "16 16 5 1",
140 "  c black",
141 ". c green",
142 "X c #808080",
143 "o c gray100",
144 "O c None",
145 /* pixels */
146 "OOOOOOOOOOOOOOOO",
147 "OOOOOOOOOOOOOXOO",
148 "OOOOOOOOOOOOXoXO",
149 "OOOOOOOOOOOXoXOO",
150 "OOOOOOOOOOXoXOOO",
151 "OOOOOOOOOXoXOOOO",
152 "OOOOOOOOXoXOOOOO",
153 "OOOOOOO oXOOOOOO",
154 "OOOOOO . OOOOOOO",
155 "OOOOO . OOOOOOOO",
156 "OOOO . OOOOOOOOO",
157 "OOO . OOOOOOOOOO",
158 "OO . OOOOOOOOOOO",
159 "OO  OOOOOOOOOOOO",
160 "OOOOXXXXXOOOOOOO",
161 "OOOOOOOOOXXXXXOO"
162 };
164 /* XPM */
165 static char *button_none[] = {
166 /* columns rows colors chars-per-pixel */
167 "8 8 3 1",
168 "  c black",
169 ". c #808080",
170 "X c None",
171 /* pixels */
172 "XXXXXXXX",
173 "XX .. XX",
174 "X .XX. X",
175 "X.XX X.X",
176 "X.X XX.X",
177 "X .XX. X",
178 "XX .. XX",
179 "XXXXXXXX"
180 };
181 /* XPM */
182 static char *button_off[] = {
183 /* columns rows colors chars-per-pixel */
184 "8 8 4 1",
185 "  c black",
186 ". c #808080",
187 "X c gray100",
188 "o c None",
189 /* pixels */
190 "oooooooo",
191 "oo.  .oo",
192 "o. XX .o",
193 "o XXXX o",
194 "o XXXX o",
195 "o. XX .o",
196 "oo.  .oo",
197 "oooooooo"
198 };
199 /* XPM */
200 static char *button_on[] = {
201 /* columns rows colors chars-per-pixel */
202 "8 8 3 1",
203 "  c black",
204 ". c green",
205 "X c None",
206 /* pixels */
207 "XXXXXXXX",
208 "XX    XX",
209 "X  ..  X",
210 "X .... X",
211 "X .... X",
212 "X  ..  X",
213 "XX    XX",
214 "XXXXXXXX"
215 };
222 #include <map>
223 #include <set>
224 #include <glib/gprintf.h>
225 #include <glibmm/i18n.h>
226 #include <gtkmm/comboboxtext.h>
227 #include <gtkmm/enums.h>
228 #include <gtkmm/frame.h>
229 #include <gtkmm/image.h>
230 #include <gtkmm/menubar.h>
231 #include <gtkmm/notebook.h>
232 #include <gtkmm/paned.h>
233 #include <gtkmm/scrolledwindow.h>
234 #include <gtkmm/table.h>
235 #include <gtkmm/eventbox.h>
236 #include <gtkmm/treemodel.h>
237 #include <gtkmm/treemodelcolumn.h>
238 #include <gtkmm/treestore.h>
239 #include <gtkmm/treeview.h>
241 #include "ui/widget/panel.h"
242 #include "device-manager.h"
244 #include "input.h"
246 using Inkscape::InputDevice;
248 namespace Inkscape {
249 namespace UI {
250 namespace Dialog {
254 class MyModelColumns : public Gtk::TreeModel::ColumnRecord
256 public:
257     Gtk::TreeModelColumn<Glib::ustring>                filename;
258     Gtk::TreeModelColumn<Glib::ustring>                description;
259     Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> >  thumbnail;
260     Gtk::TreeModelColumn<InputDevice const *>          device;
262     MyModelColumns() { add(filename); add(description); add(thumbnail); add(device); }
263 };
265 class InputDialogImpl : public InputDialog {
266 public:
267     InputDialogImpl();
268     virtual ~InputDialogImpl() {}
270 private:
271     Glib::RefPtr<Gdk::Pixbuf> penPix;
272     Glib::RefPtr<Gdk::Pixbuf> mousePix;
273     Glib::RefPtr<Gdk::Pixbuf> tipPix;
274     Glib::RefPtr<Gdk::Pixbuf> tabletPix;
275     Glib::RefPtr<Gdk::Pixbuf> eraserPix;
276     Glib::RefPtr<Gdk::Pixbuf> sidebuttonsPix;
278     Glib::RefPtr<Gdk::Pixbuf> buttonsNonePix;
279     Glib::RefPtr<Gdk::Pixbuf> buttonsOnPix;
280     Glib::RefPtr<Gdk::Pixbuf> buttonsOffPix;
282     std::map<Glib::ustring, std::set<guint> > buttonMap;
284     GdkInputSource lastSourceSeen;
285     Glib::ustring lastDevnameSeen;
287     MyModelColumns cols;
288     Glib::RefPtr<Gtk::TreeStore> store;
289     Gtk::TreeView tree;
290     Gtk::Frame frame2;
291     Gtk::Frame testFrame;
292     Gtk::ScrolledWindow treeScroller;
293     Gtk::ScrolledWindow detailScroller;
294     Gtk::HPaned splitter;
295     Gtk::VPaned split2;
296     Gtk::Label devName;
297     Gtk::Label devKeyCount;
298     Gtk::Label devAxesCount;
299     Gtk::ComboBoxText axesCombo;
300     Gtk::ComboBoxText buttonCombo;
301     Gtk::ComboBoxText modeCombo;
302     Gtk::Label keyVal;
303     Gtk::Entry keyEntry;
304     Gtk::Table devDetails;
305     Gtk::HPaned confSplitter;
306     Gtk::Notebook topHolder;
307     Gtk::Image testThumb;
308     Gtk::Image testButtons[24];
309     Gtk::Table imageTable;
310     Gtk::EventBox testDetector;
312     void setupValueAndCombo( gint reported, gint actual, Gtk::Label& label, Gtk::ComboBoxText& combo );
313     void updateTestButtons( Glib::ustring const& key, gint hotButton );
314     Glib::ustring getKeyFor( GdkDevice* device );
315     bool eventSnoop(GdkEvent* event);
316     void foo();
317 };
320 // Now that we've defined the *Impl class, we can do the method to aquire one.
321 InputDialog &InputDialog::getInstance()
323     InputDialog *dialog = new InputDialogImpl();
324     return *dialog;
328 InputDialogImpl::InputDialogImpl() :
329     InputDialog(),
331     penPix(Gdk::Pixbuf::create_from_xpm_data(pen)),
332     mousePix(Gdk::Pixbuf::create_from_xpm_data(mouse)),
333     tipPix(Gdk::Pixbuf::create_from_xpm_data(tip)),
334     tabletPix(Gdk::Pixbuf::create_from_xpm_data(tablet)),
335     eraserPix(Gdk::Pixbuf::create_from_xpm_data(eraser)),
336     sidebuttonsPix(Gdk::Pixbuf::create_from_xpm_data(sidebuttons)),
338     buttonsNonePix(Gdk::Pixbuf::create_from_xpm_data(button_none)),
339     buttonsOnPix(Gdk::Pixbuf::create_from_xpm_data(button_on)),
340     buttonsOffPix(Gdk::Pixbuf::create_from_xpm_data(button_off)),
342     lastSourceSeen((GdkInputSource)-1),
343     lastDevnameSeen(""),
344     cols(),
345     store(Gtk::TreeStore::create(cols)),
346     tree(store),
347     frame2(),
348     testFrame("Test Area"),
349     treeScroller(),
350     detailScroller(),
351     splitter(),
352     split2(),
353     modeCombo(),
354     devDetails(6, 2),
355     confSplitter(),
356     topHolder(),
357     imageTable(8, 4)
359     Gtk::Box *contents = _getContents();
362     treeScroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
363     treeScroller.add(tree);
364     split2.pack1(testFrame);
365     split2.pack2(frame2);
366     splitter.pack1(treeScroller);
367     splitter.pack2(split2);
369     testDetector.add(imageTable);
370     testFrame.add(testDetector);
371     testThumb.set(tabletPix);
372     testThumb.set_padding(24, 24);
373     imageTable.attach(testThumb, 0, 8, 0, 1, ::Gtk::EXPAND, ::Gtk::EXPAND);
374     {
375         guint col = 0;
376         guint row = 1;
377         for ( guint num = 0; num < 24; num++ ) {
378             testButtons[num].set(buttonsNonePix);
379             imageTable.attach(testButtons[num], col, col + 1, row, row + 1, ::Gtk::FILL, ::Gtk::FILL);
380             col++;
381             if (col > 7) {
382                 col = 0;
383                 row++;
384             }
385         }
386     }
389     topHolder.append_page(confSplitter, "Configuration");
390     topHolder.append_page(splitter, "Hardware");
391 //     confSplitter.show_all();
392 //     splitter.show_all();
393     topHolder.show_all();
394     topHolder.set_current_page(1);
396     contents->pack_start(topHolder);
398     int rowNum = 0;
400     Gtk::Label* lbl = Gtk::manage(new Gtk::Label("Name:"));
401     devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
402                       ::Gtk::FILL,
403                       ::Gtk::SHRINK);
404     devDetails.attach(devName, 1, 2, rowNum, rowNum + 1,
405                       ::Gtk::SHRINK,
406                       ::Gtk::SHRINK);
408     rowNum++;
410     lbl = Gtk::manage(new Gtk::Label("Mode:"));
411     devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
412                       ::Gtk::FILL,
413                       ::Gtk::SHRINK);
415     modeCombo.append_text("Disabled");
416     modeCombo.append_text("Screen");
417     modeCombo.append_text("Window");
418     modeCombo.set_active_text("Disabled");
419     modeCombo.set_sensitive(false);
421     devDetails.attach(modeCombo, 1, 2, rowNum, rowNum + 1,
422                       ::Gtk::FILL,
423                       ::Gtk::SHRINK);
424     rowNum++;
426     lbl = Gtk::manage(new Gtk::Label("Reported axes count:"));
427     devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
428                       ::Gtk::FILL,
429                       ::Gtk::SHRINK);
430     devDetails.attach(devAxesCount, 1, 2, rowNum, rowNum + 1,
431                       ::Gtk::SHRINK,
432                       ::Gtk::SHRINK);
434     rowNum++;
436     lbl = Gtk::manage(new Gtk::Label("Actual axes count:"));
437     devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
438                       ::Gtk::FILL,
439                       ::Gtk::SHRINK);
440     devDetails.attach(axesCombo, 1, 2, rowNum, rowNum + 1,
441                       ::Gtk::SHRINK,
442                       ::Gtk::SHRINK);
444     rowNum++;
446     lbl = Gtk::manage(new Gtk::Label("Reported button count:"));
447     devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
448                       ::Gtk::FILL,
449                       ::Gtk::SHRINK);
450     devDetails.attach(devKeyCount, 1, 2, rowNum, rowNum + 1,
451                       ::Gtk::SHRINK,
452                       ::Gtk::SHRINK);
454     rowNum++;
456     lbl = Gtk::manage(new Gtk::Label("Actual button count:"));
457     devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
458                       ::Gtk::FILL,
459                       ::Gtk::SHRINK);
460     devDetails.attach(buttonCombo, 1, 2, rowNum, rowNum + 1,
461                       ::Gtk::SHRINK,
462                       ::Gtk::SHRINK);
464     rowNum++;
466     devDetails.attach(keyVal, 0, 2, rowNum, rowNum + 1,
467                       ::Gtk::FILL,
468                       ::Gtk::SHRINK);
469     rowNum++;
472     testDetector.signal_event().connect(sigc::mem_fun(*this, &InputDialogImpl::eventSnoop));
474 //     void gdk_input_set_extension_events (GdkWindow        *window,
475 //                                          gint              mask,
476 //                                          GdkExtensionMode  mode);
478     gtk_widget_set_extension_events( GTK_WIDGET(testDetector.gobj()), GDK_EXTENSION_EVENTS_ALL );
479     testDetector.add_events(Gdk::POINTER_MOTION_MASK|Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK |Gdk::PROXIMITY_IN_MASK|Gdk::PROXIMITY_OUT_MASK|Gdk::SCROLL_MASK);
481     devDetails.attach(keyEntry, 0, 2, rowNum, rowNum + 1,
482                       ::Gtk::FILL,
483                       ::Gtk::SHRINK);
484     rowNum++;
487     devDetails.set_sensitive(false);
488     detailScroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
489     detailScroller.add(devDetails);
490     frame2.add(detailScroller);
492 //- 16x16/devices
493 // gnome-dev-mouse-optical
494 // input-mouse
495 // input-tablet
496 // mouse
500     Gtk::TreeModel::Row row;
501     Gtk::TreeModel::Row childrow;
502     Gtk::TreeModel::Row deviceRow;
505     //Add the TreeView's view columns:
506     tree.append_column("I", cols.thumbnail);
507     tree.append_column("Bar", cols.description);
509     tree.set_enable_tree_lines();
510     tree.set_headers_visible(false);
511     tree.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &InputDialogImpl::foo));
515     std::list<InputDevice const *> devList = Inkscape::DeviceManager::getManager().getDevices();
516     if ( !devList.empty() ) {
517         g_message("Found some");
519         {
520             GdkModifierType  defaultModMask = static_cast<GdkModifierType>(gtk_accelerator_get_default_mod_mask());
521             gchar* name = gtk_accelerator_name(GDK_a, defaultModMask);
522             gchar* label = gtk_accelerator_get_label(GDK_a, defaultModMask);
523             g_message("Name: [%s]  label:[%s]", name, label);
524             g_free(name);
525             g_free(label);
526         }
528         row = *(store->append());
529         row[cols.description] = "Hardware";
531         childrow = *(store->append(row.children()));
532         childrow[cols.description] = "Tablet";
533         childrow[cols.thumbnail] = tabletPix;
535         for ( std::list<InputDevice const *>::iterator it = devList.begin(); it != devList.end(); ++it ) {
536             InputDevice const* dev = *it;
537             if ( dev ) {
538                 g_message("device: name[%s] source[0x%x] mode[0x%x] cursor[%s] axis count[%d] key count[%d]", dev->getName().c_str(), dev->getSource(), dev->getMode(),
539                           dev->hasCursor() ? "Yes":"no", dev->getNumAxes(), dev->getNumKeys());
541                 if ( dev->getSource() != Gdk::SOURCE_MOUSE ) {
542                     deviceRow = *(store->append(childrow.children()));
543                     deviceRow[cols.description] = dev->getName();
544                     deviceRow[cols.device] = dev;
545                     switch ( dev->getSource() ) {
546                         case GDK_SOURCE_PEN:
547                             if (deviceRow[cols.description] == "pad") {
548                                 deviceRow[cols.thumbnail] = sidebuttonsPix;
549                             } else {
550                                 deviceRow[cols.thumbnail] = tipPix;
551                             }
552                             break;
553                         case GDK_SOURCE_CURSOR:
554                             deviceRow[cols.thumbnail] = mousePix;
555                             break;
556                         case GDK_SOURCE_ERASER:
557                             deviceRow[cols.thumbnail] = eraserPix;
558                             break;
559                         default:
560                             ; // nothing
561                     }
562                 }
563             } else {
564                 g_warning("Null device in list");
565             }
566         }
567     } else {
568         g_message("NO DEVICES FOUND");
569     }
572     tree.expand_all();
573     show_all_children();
576 void InputDialogImpl::foo() {
577     bool clear = true;
578     Glib::RefPtr<Gtk::TreeSelection> treeSel = tree.get_selection();
579     Gtk::TreeModel::iterator iter = treeSel->get_selected();
580     if (iter) {
581         Gtk::TreeModel::Row row = *iter;
582         Glib::ustring val = row[cols.description];
583         InputDevice const * dev = row[cols.device];
584         if ( dev ) {
585             devDetails.set_sensitive(true);
586             modeCombo.set_sensitive(true);
587             switch( dev->getMode() ) {
588                 case GDK_MODE_DISABLED:
589                     modeCombo.set_active(0);
590                     break;
591                 case GDK_MODE_SCREEN:
592                     modeCombo.set_active(1);
593                     break;
594                 case GDK_MODE_WINDOW:
595                     modeCombo.set_active(2);
596                     break;
597                 default:
598                     ;
599             }
600             clear = false;
601             devName.set_label(row[cols.description]);
602             setupValueAndCombo( dev->getNumAxes(), dev->getNumAxes(), devAxesCount, axesCombo);
603             setupValueAndCombo( dev->getNumKeys(), dev->getNumKeys(), devKeyCount, buttonCombo);
604         }
605     }
607     devDetails.set_sensitive(!clear);
608     if (clear) {
609         devName.set_label("");
610         devAxesCount.set_label("");
611         devKeyCount.set_label("");
612     }
615 void InputDialogImpl::setupValueAndCombo( gint reported, gint actual, Gtk::Label& label, Gtk::ComboBoxText& combo )
617     gchar *tmp = g_strdup_printf("%d", reported);
618     label.set_label(tmp);
619     g_free(tmp);
621     combo.clear_items();
622     for ( gint i = 1; i <= reported; ++i ) {
623         tmp = g_strdup_printf("%d", i);
624         combo.append_text(tmp);
625         g_free(tmp);
626     }
628     if ( (1 <= actual) && (actual <= reported) ) {
629         combo.set_active(actual - 1);
630     }
633 void InputDialogImpl::updateTestButtons( Glib::ustring const& key, gint hotButton )
635     for ( gint i = 0; i < 24; i++ ) {
636         if ( buttonMap[key].find(i) != buttonMap[key].end() ) {
637             if ( i == hotButton ) {
638                 testButtons[i].set(buttonsOnPix);
639             } else {
640                 testButtons[i].set(buttonsOffPix);
641             }
642         } else {
643             testButtons[i].set(buttonsNonePix);
644         }
645     }
648 Glib::ustring InputDialogImpl::getKeyFor( GdkDevice* device )
650     Glib::ustring key;
651     switch ( device->source ) {
652         case GDK_SOURCE_MOUSE:
653             key = "M:";
654             break;
655         case GDK_SOURCE_CURSOR:
656             key = "C:";
657             break;
658         case GDK_SOURCE_PEN:
659             key = "P:";
660             break;
661         case GDK_SOURCE_ERASER:
662             key = "E:";
663             break;
664         default:
665             key = "?:";
666     }
667     key += device->name;
669     return key;
672 bool InputDialogImpl::eventSnoop(GdkEvent* event)
674     int modmod = 0;
676     GdkInputSource source = lastSourceSeen;
677     Glib::ustring devName = lastDevnameSeen;
678     Glib::ustring key;
679     gint hotButton = -1;
681     switch ( event->type ) {
682         case GDK_KEY_PRESS:
683         case GDK_KEY_RELEASE:
684         {
685             GdkEventKey* keyEvt = reinterpret_cast<GdkEventKey*>(event);
686             gchar* name = gtk_accelerator_name(keyEvt->keyval, static_cast<GdkModifierType>(keyEvt->state));
687             keyVal.set_label(name);
688             g_message("%d KEY    state:0x%08x  0x%04x [%s]", keyEvt->type, keyEvt->state, keyEvt->keyval, name);
689             g_free(name);
690         }
691         break;
692         case GDK_BUTTON_PRESS:
693             modmod = 1;
694             // fallthrough
695         case GDK_BUTTON_RELEASE:
696         {
697             GdkEventButton* btnEvt = reinterpret_cast<GdkEventButton*>(event);
698             if ( btnEvt->device ) {
699                 key = getKeyFor(btnEvt->device);
700                 source = btnEvt->device->source;
701                 devName = btnEvt->device->name;
703                 if ( buttonMap[key].find(btnEvt->button) == buttonMap[key].end() ) {
704                     g_message("New button found for %s = %d", key.c_str(), btnEvt->button);
705                     buttonMap[key].insert(btnEvt->button);
706                 }
707                 hotButton = modmod ? btnEvt->button : -1;
708                 updateTestButtons(key, hotButton);
709             }
710             gchar* name = gtk_accelerator_name(0, static_cast<GdkModifierType>(btnEvt->state));
711             keyVal.set_label(name);
712             g_message("%d BTN    state:0x%08x %c  %4d [%s] dev:%p [%s]  ",
713                       btnEvt->type, btnEvt->state,
714                       (modmod ? '+':'-'),
715                       btnEvt->button, name, btnEvt->device,
716                       (btnEvt->device ? btnEvt->device->name : "null")
718                 );
719             g_free(name);
720         }
721         break;
722         case GDK_MOTION_NOTIFY:
723         {
724             GdkEventMotion* btnMtn = reinterpret_cast<GdkEventMotion*>(event);
725             if ( btnMtn->device ) {
726                 key = getKeyFor(btnMtn->device);
727                 source = btnMtn->device->source;
728                 devName = btnMtn->device->name;
729             }
730             gchar* name = gtk_accelerator_name(0, static_cast<GdkModifierType>(btnMtn->state));
731             keyVal.set_label(name);
732             g_message("%d MOV    state:0x%08x         [%s] dev:%p [%s] %3.2f %3.2f %3.2f %3.2f %3.2f %3.2f", btnMtn->type, btnMtn->state,
733                       name, btnMtn->device,
734                       (btnMtn->device ? btnMtn->device->name : "null"),
735                       ((btnMtn->device && btnMtn->axes && (btnMtn->device->num_axes > 0)) ? btnMtn->axes[0]:0),
736                       ((btnMtn->device && btnMtn->axes && (btnMtn->device->num_axes > 1)) ? btnMtn->axes[1]:0),
737                       ((btnMtn->device && btnMtn->axes && (btnMtn->device->num_axes > 2)) ? btnMtn->axes[2]:0),
738                       ((btnMtn->device && btnMtn->axes && (btnMtn->device->num_axes > 3)) ? btnMtn->axes[3]:0),
739                       ((btnMtn->device && btnMtn->axes && (btnMtn->device->num_axes > 4)) ? btnMtn->axes[4]:0),
740                       ((btnMtn->device && btnMtn->axes && (btnMtn->device->num_axes > 5)) ? btnMtn->axes[5]:0)
741                 );
742             g_free(name);
743         }
744         break;
745         default:
746             ;// nothing
747     }
750     if ( (lastSourceSeen != source) || (lastDevnameSeen != devName) ) {
751         g_message("FLIPPIES  %d => %d", lastSourceSeen, source);
752         switch (source) {
753             case GDK_SOURCE_MOUSE:
754             {
755                 testThumb.set(mousePix);
756             }
757             break;
758             case GDK_SOURCE_CURSOR:
759             {
760                 g_message("flip to cursor");
761                 testThumb.set(mousePix);
762             }
763             break;
764             case GDK_SOURCE_PEN:
765             {
766                 if (devName == "pad") {
767                     g_message("flip to pad");
768                     testThumb.set(sidebuttonsPix);
769                 } else {
770                     g_message("flip to pen");
771                     testThumb.set(tipPix);
772                 }
773             }
774             break;
775             case GDK_SOURCE_ERASER:
776             {
777                 g_message("flip to eraser");
778                 testThumb.set(eraserPix);
779             }
780             break;
781             default:
782                 g_message("gurgle");
783         }
784         updateTestButtons(key, hotButton);
785         lastSourceSeen = source;
786         lastDevnameSeen = devName;
787     }
789     return false;
793 } // end namespace Inkscape
794 } // end namespace UI
795 } // end namespace Dialog
798 /*
799   Local Variables:
800   mode:c++
801   c-file-style:"stroustrup"
802   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
803   indent-tabs-mode:nil
804   fill-column:99
805   End:
806 */
807 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :