f5746dbdecb413eece434b7b71a4f5755551d0e5
3 /* XPM */
4 static char * core_xpm[] = {
5 "16 16 4 1",
6 " c None",
7 ". c #808080",
8 "+ c #000000",
9 "@ c #FFFFFF",
10 " ",
11 " ",
12 " ",
13 " .++++++. ",
14 " +@+@@+@+ ",
15 " +@+@@+@+ ",
16 " +.+..+.+ ",
17 " +@@@@@@+ ",
18 " +@@@@@@+ ",
19 " +@@@@@@+ ",
20 " +@@@@@@+ ",
21 " +@@@@@@+ ",
22 " .++++++. ",
23 " ",
24 " ",
25 " "};
27 /* XPM */
28 static char *eraser[] = {
29 /* columns rows colors chars-per-pixel */
30 "16 16 5 1",
31 " c black",
32 ". c green",
33 "X c #808080",
34 "o c gray100",
35 "O c None",
36 /* pixels */
37 "OOOOOOOOOOOOOOOO",
38 "OOOOOOOOOOOOO OO",
39 "OOOOOOOOOOOO . O",
40 "OOOOOOOOOOO . OO",
41 "OOOOOOOOOO . OOO",
42 "OOOOOOOOO . OOOO",
43 "OOOOOOOO . OOOOO",
44 "OOOOOOOXo OOOOOO",
45 "OOOOOOXoXOOOOOOO",
46 "OOOOOXoXOOOOOOOO",
47 "OOOOXoXOOOOOOOOO",
48 "OOOXoXOOOOOOOOOO",
49 "OOXoXOOOOOOOOOOO",
50 "OOXXOOOOOOOOOOOO",
51 "OOOOOOOOOOOOOOOO",
52 "OOOOOOOOOOOOOOOO"
53 };
55 /* XPM */
56 static char *mouse[] = {
57 /* columns rows colors chars-per-pixel */
58 "16 16 3 1",
59 " c black",
60 ". c gray100",
61 "X c None",
62 /* pixels */
63 "XXXXXXXXXXXXXXXX",
64 "XXXXXXXXXXXXXXXX",
65 "XXXXXXXXXXXXXXXX",
66 "XXXXXXXXXXXXXXXX",
67 "XXXXXXX XXXXXXX",
68 "XXXXX . XXXXXXX",
69 "XXXX .... XXXXXX",
70 "XXXX .... XXXXXX",
71 "XXXXX .... XXXXX",
72 "XXXXX .... XXXXX",
73 "XXXXXX .... XXXX",
74 "XXXXXX .... XXXX",
75 "XXXXXXX . XXXXX",
76 "XXXXXXX XXXXXXX",
77 "XXXXXXXXXXXXXXXX",
78 "XXXXXXXXXXXXXXXX"
79 };
81 /* XPM */
82 static char *pen[] = {
83 /* columns rows colors chars-per-pixel */
84 "16 16 3 1",
85 " c black",
86 ". c gray100",
87 "X c None",
88 /* pixels */
89 "XXXXXXXXXXXXXXXX",
90 "XXXXXXXXXXXXX XX",
91 "XXXXXXXXXXXX . X",
92 "XXXXXXXXXXX . XX",
93 "XXXXXXXXXX . XXX",
94 "XXXXXXXXX . XXXX",
95 "XXXXXXXX . XXXXX",
96 "XXXXXXX . XXXXXX",
97 "XXXXXX . XXXXXXX",
98 "XXXXX . XXXXXXXX",
99 "XXXX . XXXXXXXXX",
100 "XXX . XXXXXXXXXX",
101 "XX . XXXXXXXXXXX",
102 "XX XXXXXXXXXXXX",
103 "XXXXXXXXXXXXXXXX",
104 "XXXXXXXXXXXXXXXX"
105 };
107 /* XPM */
108 static char *sidebuttons[] = {
109 /* columns rows colors chars-per-pixel */
110 "16 16 4 1",
111 " c black",
112 ". c #808080",
113 "o c green",
114 "O c None",
115 /* pixels */
116 "OOOOOOOOOOOOOOOO",
117 "OOOOOOOOOOOOOOOO",
118 "O..............O",
119 "O.OOOOOOOOOOOO.O",
120 "O OOOOOOOO O",
121 "O o OOOOOOOO o O",
122 "O o OOOOOOOO o O",
123 "O OOOOOOOO O",
124 "O.OOOOOOOOOOOO.O",
125 "O.OOOOOOOOOOOO.O",
126 "O.OOOOOOOOOOOO.O",
127 "O.OOOOOOOOOOOO.O",
128 "O.OOOOOOOOOOOO.O",
129 "O..............O",
130 "OOOOOOOOOOOOOOOO",
131 "OOOOOOOOOOOOOOOO"
132 };
134 /* XPM */
135 static char *tablet[] = {
136 /* columns rows colors chars-per-pixel */
137 "16 16 3 1",
138 " c black",
139 ". c gray100",
140 "X c None",
141 /* pixels */
142 "XXXXXXXXXXXXXXXX",
143 "XXXXXXXXXXXXXXXX",
144 "X X",
145 "X ............ X",
146 "X ............ X",
147 "X ............ X",
148 "X ............ X",
149 "X ............ X",
150 "X ............ X",
151 "X ............ X",
152 "X ............ X",
153 "X ............ X",
154 "X ............ X",
155 "X X",
156 "XXXXXXXXXXXXXXXX",
157 "XXXXXXXXXXXXXXXX"
158 };
160 /* XPM */
161 static char *tip[] = {
162 /* columns rows colors chars-per-pixel */
163 "16 16 5 1",
164 " c black",
165 ". c green",
166 "X c #808080",
167 "o c gray100",
168 "O c None",
169 /* pixels */
170 "OOOOOOOOOOOOOOOO",
171 "OOOOOOOOOOOOOXOO",
172 "OOOOOOOOOOOOXoXO",
173 "OOOOOOOOOOOXoXOO",
174 "OOOOOOOOOOXoXOOO",
175 "OOOOOOOOOXoXOOOO",
176 "OOOOOOOOXoXOOOOO",
177 "OOOOOOO oXOOOOOO",
178 "OOOOOO . OOOOOOO",
179 "OOOOO . OOOOOOOO",
180 "OOOO . OOOOOOOOO",
181 "OOO . OOOOOOOOOO",
182 "OO . OOOOOOOOOOO",
183 "OO OOOOOOOOOOOO",
184 "OOOOXXXXXOOOOOOO",
185 "OOOOOOOOOXXXXXOO"
186 };
188 /* XPM */
189 static char *button_none[] = {
190 /* columns rows colors chars-per-pixel */
191 "8 8 3 1",
192 " c black",
193 ". c #808080",
194 "X c None",
195 /* pixels */
196 "XXXXXXXX",
197 "XX .. XX",
198 "X .XX. X",
199 "X.XX X.X",
200 "X.X XX.X",
201 "X .XX. X",
202 "XX .. XX",
203 "XXXXXXXX"
204 };
205 /* XPM */
206 static char *button_off[] = {
207 /* columns rows colors chars-per-pixel */
208 "8 8 4 1",
209 " c black",
210 ". c #808080",
211 "X c gray100",
212 "o c None",
213 /* pixels */
214 "oooooooo",
215 "oo. .oo",
216 "o. XX .o",
217 "o XXXX o",
218 "o XXXX o",
219 "o. XX .o",
220 "oo. .oo",
221 "oooooooo"
222 };
223 /* XPM */
224 static char *button_on[] = {
225 /* columns rows colors chars-per-pixel */
226 "8 8 3 1",
227 " c black",
228 ". c green",
229 "X c None",
230 /* pixels */
231 "XXXXXXXX",
232 "XX XX",
233 "X .. X",
234 "X .... X",
235 "X .... X",
236 "X .. X",
237 "XX XX",
238 "XXXXXXXX"
239 };
246 #include <map>
247 #include <set>
248 #include <glib/gprintf.h>
249 #include <glibmm/i18n.h>
250 #include <gtkmm/comboboxtext.h>
251 #include <gtkmm/enums.h>
252 #include <gtkmm/frame.h>
253 #include <gtkmm/image.h>
254 #include <gtkmm/menubar.h>
255 #include <gtkmm/notebook.h>
256 #include <gtkmm/paned.h>
257 #include <gtkmm/scrolledwindow.h>
258 #include <gtkmm/table.h>
259 #include <gtkmm/eventbox.h>
260 #include <gtkmm/treemodel.h>
261 #include <gtkmm/treemodelcolumn.h>
262 #include <gtkmm/treestore.h>
263 #include <gtkmm/treeview.h>
265 #include "ui/widget/panel.h"
266 #include "device-manager.h"
268 #include "input.h"
270 using Inkscape::InputDevice;
272 namespace Inkscape {
273 namespace UI {
274 namespace Dialog {
278 class MyModelColumns : public Gtk::TreeModel::ColumnRecord
279 {
280 public:
281 Gtk::TreeModelColumn<Glib::ustring> filename;
282 Gtk::TreeModelColumn<Glib::ustring> description;
283 Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> > thumbnail;
284 Gtk::TreeModelColumn<InputDevice const *> device;
286 MyModelColumns() { add(filename); add(description); add(thumbnail); add(device); }
287 };
289 class InputDialogImpl : public InputDialog {
290 public:
291 InputDialogImpl();
292 virtual ~InputDialogImpl() {}
294 private:
295 Glib::RefPtr<Gdk::Pixbuf> corePix;
296 Glib::RefPtr<Gdk::Pixbuf> penPix;
297 Glib::RefPtr<Gdk::Pixbuf> mousePix;
298 Glib::RefPtr<Gdk::Pixbuf> tipPix;
299 Glib::RefPtr<Gdk::Pixbuf> tabletPix;
300 Glib::RefPtr<Gdk::Pixbuf> eraserPix;
301 Glib::RefPtr<Gdk::Pixbuf> sidebuttonsPix;
303 Glib::RefPtr<Gdk::Pixbuf> buttonsNonePix;
304 Glib::RefPtr<Gdk::Pixbuf> buttonsOnPix;
305 Glib::RefPtr<Gdk::Pixbuf> buttonsOffPix;
307 std::map<Glib::ustring, std::set<guint> > buttonMap;
309 GdkInputSource lastSourceSeen;
310 Glib::ustring lastDevnameSeen;
312 MyModelColumns cols;
313 Glib::RefPtr<Gtk::TreeStore> store;
314 Gtk::TreeView tree;
315 Gtk::Frame frame2;
316 Gtk::Frame testFrame;
317 Gtk::ScrolledWindow treeScroller;
318 Gtk::ScrolledWindow detailScroller;
319 Gtk::HPaned splitter;
320 Gtk::VPaned split2;
321 Gtk::Label devName;
322 Gtk::Label devKeyCount;
323 Gtk::Label devAxesCount;
324 Gtk::ComboBoxText axesCombo;
325 Gtk::ComboBoxText buttonCombo;
326 Gtk::ComboBoxText linkCombo;
327 sigc::connection linkConnection;
328 Gtk::Label keyVal;
329 Gtk::Entry keyEntry;
330 Gtk::Table devDetails;
331 Gtk::HPaned confSplitter;
332 Gtk::Notebook topHolder;
333 Gtk::Image testThumb;
334 Gtk::Image testButtons[24];
335 Gtk::Table imageTable;
336 Gtk::EventBox testDetector;
338 void setupValueAndCombo( gint reported, gint actual, Gtk::Label& label, Gtk::ComboBoxText& combo );
339 void updateTestButtons( Glib::ustring const& key, gint hotButton );
340 Glib::ustring getKeyFor( GdkDevice* device );
341 bool eventSnoop(GdkEvent* event);
342 void linkComboChanged();
343 void resyncToSelection();
344 void handleDeviceChange(const Glib::RefPtr<InputDevice>& device);
345 void updateDeviceButtons(const Glib::RefPtr<InputDevice>& device);
346 void updateDeviceLinks(const Glib::RefPtr<InputDevice>& device);
347 };
350 // Now that we've defined the *Impl class, we can do the method to aquire one.
351 InputDialog &InputDialog::getInstance()
352 {
353 InputDialog *dialog = new InputDialogImpl();
354 return *dialog;
355 }
358 InputDialogImpl::InputDialogImpl() :
359 InputDialog(),
361 corePix(Gdk::Pixbuf::create_from_xpm_data(core_xpm)),
362 penPix(Gdk::Pixbuf::create_from_xpm_data(pen)),
363 mousePix(Gdk::Pixbuf::create_from_xpm_data(mouse)),
364 tipPix(Gdk::Pixbuf::create_from_xpm_data(tip)),
365 tabletPix(Gdk::Pixbuf::create_from_xpm_data(tablet)),
366 eraserPix(Gdk::Pixbuf::create_from_xpm_data(eraser)),
367 sidebuttonsPix(Gdk::Pixbuf::create_from_xpm_data(sidebuttons)),
369 buttonsNonePix(Gdk::Pixbuf::create_from_xpm_data(button_none)),
370 buttonsOnPix(Gdk::Pixbuf::create_from_xpm_data(button_on)),
371 buttonsOffPix(Gdk::Pixbuf::create_from_xpm_data(button_off)),
373 lastSourceSeen((GdkInputSource)-1),
374 lastDevnameSeen(""),
375 cols(),
376 store(Gtk::TreeStore::create(cols)),
377 tree(store),
378 frame2(),
379 testFrame("Test Area"),
380 treeScroller(),
381 detailScroller(),
382 splitter(),
383 split2(),
384 linkCombo(),
385 devDetails(6, 2),
386 confSplitter(),
387 topHolder(),
388 imageTable(8, 4)
389 {
390 Gtk::Box *contents = _getContents();
393 treeScroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
394 treeScroller.add(tree);
395 split2.pack1(testFrame);
396 split2.pack2(frame2);
397 splitter.pack1(treeScroller);
398 splitter.pack2(split2);
400 testDetector.add(imageTable);
401 testFrame.add(testDetector);
402 testThumb.set(tabletPix);
403 testThumb.set_padding(24, 24);
404 imageTable.attach(testThumb, 0, 8, 0, 1, ::Gtk::EXPAND, ::Gtk::EXPAND);
405 {
406 guint col = 0;
407 guint row = 1;
408 for ( guint num = 0; num < 24; num++ ) {
409 testButtons[num].set(buttonsNonePix);
410 imageTable.attach(testButtons[num], col, col + 1, row, row + 1, ::Gtk::FILL, ::Gtk::FILL);
411 col++;
412 if (col > 7) {
413 col = 0;
414 row++;
415 }
416 }
417 }
420 topHolder.append_page(confSplitter, "Configuration");
421 topHolder.append_page(splitter, "Hardware");
422 // confSplitter.show_all();
423 // splitter.show_all();
424 topHolder.show_all();
425 topHolder.set_current_page(1);
427 contents->pack_start(topHolder);
429 int rowNum = 0;
431 Gtk::Label* lbl = Gtk::manage(new Gtk::Label("Name:"));
432 devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
433 ::Gtk::FILL,
434 ::Gtk::SHRINK);
435 devDetails.attach(devName, 1, 2, rowNum, rowNum + 1,
436 ::Gtk::SHRINK,
437 ::Gtk::SHRINK);
439 rowNum++;
441 lbl = Gtk::manage(new Gtk::Label("Link:"));
442 devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
443 ::Gtk::FILL,
444 ::Gtk::SHRINK);
446 linkCombo.append_text("None");
447 linkCombo.set_active_text("None");
448 linkCombo.set_sensitive(false);
449 linkConnection = linkCombo.signal_changed().connect(sigc::mem_fun(*this, &InputDialogImpl::linkComboChanged));
451 devDetails.attach(linkCombo, 1, 2, rowNum, rowNum + 1,
452 ::Gtk::FILL,
453 ::Gtk::SHRINK);
454 rowNum++;
456 lbl = Gtk::manage(new Gtk::Label("Reported axes count:"));
457 devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
458 ::Gtk::FILL,
459 ::Gtk::SHRINK);
460 devDetails.attach(devAxesCount, 1, 2, rowNum, rowNum + 1,
461 ::Gtk::SHRINK,
462 ::Gtk::SHRINK);
464 rowNum++;
466 lbl = Gtk::manage(new Gtk::Label("Actual axes count:"));
467 devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
468 ::Gtk::FILL,
469 ::Gtk::SHRINK);
470 devDetails.attach(axesCombo, 1, 2, rowNum, rowNum + 1,
471 ::Gtk::SHRINK,
472 ::Gtk::SHRINK);
474 rowNum++;
476 lbl = Gtk::manage(new Gtk::Label("Reported button count:"));
477 devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
478 ::Gtk::FILL,
479 ::Gtk::SHRINK);
480 devDetails.attach(devKeyCount, 1, 2, rowNum, rowNum + 1,
481 ::Gtk::SHRINK,
482 ::Gtk::SHRINK);
484 rowNum++;
486 /*
487 lbl = Gtk::manage(new Gtk::Label("Actual button count:"));
488 devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
489 ::Gtk::FILL,
490 ::Gtk::SHRINK);
491 devDetails.attach(buttonCombo, 1, 2, rowNum, rowNum + 1,
492 ::Gtk::SHRINK,
493 ::Gtk::SHRINK);
495 rowNum++;
496 */
498 devDetails.attach(keyVal, 0, 2, rowNum, rowNum + 1,
499 ::Gtk::FILL,
500 ::Gtk::SHRINK);
501 rowNum++;
504 testDetector.signal_event().connect(sigc::mem_fun(*this, &InputDialogImpl::eventSnoop));
506 // void gdk_input_set_extension_events (GdkWindow *window,
507 // gint mask,
508 // GdkExtensionMode mode);
510 gtk_widget_set_extension_events( GTK_WIDGET(testDetector.gobj()), GDK_EXTENSION_EVENTS_ALL );
511 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);
513 devDetails.attach(keyEntry, 0, 2, rowNum, rowNum + 1,
514 ::Gtk::FILL,
515 ::Gtk::SHRINK);
516 rowNum++;
519 devDetails.set_sensitive(false);
520 detailScroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
521 detailScroller.add(devDetails);
522 frame2.add(detailScroller);
524 //- 16x16/devices
525 // gnome-dev-mouse-optical
526 // input-mouse
527 // input-tablet
528 // mouse
532 Gtk::TreeModel::Row row;
533 Gtk::TreeModel::Row childrow;
534 Gtk::TreeModel::Row deviceRow;
537 //Add the TreeView's view columns:
538 tree.append_column("I", cols.thumbnail);
539 tree.append_column("Bar", cols.description);
541 tree.set_enable_tree_lines();
542 tree.set_headers_visible(false);
543 tree.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &InputDialogImpl::resyncToSelection));
547 std::list<InputDevice const *> devList = Inkscape::DeviceManager::getManager().getDevices();
548 if ( !devList.empty() ) {
549 {
550 GdkModifierType defaultModMask = static_cast<GdkModifierType>(gtk_accelerator_get_default_mod_mask());
551 gchar* name = gtk_accelerator_name(GDK_a, defaultModMask);
552 gchar* label = gtk_accelerator_get_label(GDK_a, defaultModMask);
553 g_message("Name: [%s] label:[%s]", name, label);
554 g_free(name);
555 g_free(label);
556 }
558 row = *(store->append());
559 row[cols.description] = "Hardware";
561 childrow = *(store->append(row.children()));
562 childrow[cols.description] = "Tablet";
563 childrow[cols.thumbnail] = tabletPix;
565 for ( std::list<InputDevice const *>::iterator it = devList.begin(); it != devList.end(); ++it ) {
566 InputDevice const* dev = *it;
567 if ( dev ) {
568 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(),
569 dev->hasCursor() ? "Yes":"no", dev->getNumAxes(), dev->getNumKeys());
571 // if ( dev->getSource() != Gdk::SOURCE_MOUSE ) {
572 if ( dev ) {
573 deviceRow = *(store->append(childrow.children()));
574 deviceRow[cols.description] = dev->getName();
575 deviceRow[cols.device] = dev;
576 switch ( dev->getSource() ) {
577 case GDK_SOURCE_MOUSE:
578 deviceRow[cols.thumbnail] = corePix;
579 break;
580 case GDK_SOURCE_PEN:
581 if (deviceRow[cols.description] == "pad") {
582 deviceRow[cols.thumbnail] = sidebuttonsPix;
583 } else {
584 deviceRow[cols.thumbnail] = tipPix;
585 }
586 break;
587 case GDK_SOURCE_CURSOR:
588 deviceRow[cols.thumbnail] = mousePix;
589 break;
590 case GDK_SOURCE_ERASER:
591 deviceRow[cols.thumbnail] = eraserPix;
592 break;
593 default:
594 ; // nothing
595 }
596 }
597 } else {
598 g_warning("Null device in list");
599 }
600 }
601 } else {
602 g_message("NO DEVICES FOUND");
603 }
604 Inkscape::DeviceManager::getManager().signalDeviceChanged().connect(sigc::mem_fun(*this, &InputDialogImpl::handleDeviceChange));
605 Inkscape::DeviceManager::getManager().signalButtonsChanged().connect(sigc::mem_fun(*this, &InputDialogImpl::updateDeviceButtons));
606 Inkscape::DeviceManager::getManager().signalLinkChanged().connect(sigc::mem_fun(*this, &InputDialogImpl::updateDeviceLinks));
608 tree.expand_all();
609 show_all_children();
610 }
612 void InputDialogImpl::handleDeviceChange(const Glib::RefPtr<InputDevice>& /*device*/)
613 {
614 // g_message("OUCH!!!! for %p hits %s", &device, device->getId().c_str());
615 }
617 void InputDialogImpl::updateDeviceButtons(const Glib::RefPtr<InputDevice>& device)
618 {
619 gint live = device->getLiveButtons();
620 std::set<guint> existing = buttonMap[device->getId()];
621 gint mask = 0x1;
622 for ( gint num = 0; num < 32; num++, mask <<= 1) {
623 if ( (mask & live) != 0 ) {
624 if ( existing.find(num) == existing.end() ) {
625 buttonMap[device->getId()].insert(num);
626 }
627 }
628 }
629 updateTestButtons(device->getId(), -1);
630 }
632 void InputDialogImpl::updateDeviceLinks(const Glib::RefPtr<InputDevice>& /*device*/)
633 {
634 // g_message("Links!!!! for %p hits %s with link of %s", &device, device->getId().c_str(), device->getLink().c_str());
635 }
637 void InputDialogImpl::linkComboChanged() {
638 Glib::RefPtr<Gtk::TreeSelection> treeSel = tree.get_selection();
639 Gtk::TreeModel::iterator iter = treeSel->get_selected();
640 if (iter) {
641 Gtk::TreeModel::Row row = *iter;
642 Glib::ustring val = row[cols.description];
643 InputDevice const * dev = row[cols.device];
644 if ( dev ) {
645 Glib::ustring linkName = linkCombo.get_active_text();
646 std::list<InputDevice const *> devList = Inkscape::DeviceManager::getManager().getDevices();
647 for ( std::list<InputDevice const *>::const_iterator it = devList.begin(); it != devList.end(); ++it ) {
648 if ( linkName == (*it)->getName() ) {
649 DeviceManager::getManager().setLinkedTo(dev->getId(), (*it)->getId());
650 break;
651 }
652 }
653 }
654 }
655 }
657 void InputDialogImpl::resyncToSelection() {
658 bool clear = true;
659 Glib::RefPtr<Gtk::TreeSelection> treeSel = tree.get_selection();
660 Gtk::TreeModel::iterator iter = treeSel->get_selected();
661 if (iter) {
662 Gtk::TreeModel::Row row = *iter;
663 Glib::ustring val = row[cols.description];
664 InputDevice const * dev = row[cols.device];
665 if ( dev ) {
666 devDetails.set_sensitive(true);
668 linkConnection.block();
669 linkCombo.clear_items();
670 linkCombo.append_text("None");
671 linkCombo.set_active(0);
672 if ( dev->getSource() != Gdk::SOURCE_MOUSE ) {
673 Glib::ustring linked = dev->getLink();
674 std::list<InputDevice const *> devList = Inkscape::DeviceManager::getManager().getDevices();
675 for ( std::list<InputDevice const *>::const_iterator it = devList.begin(); it != devList.end(); ++it ) {
676 if ( ((*it)->getSource() != Gdk::SOURCE_MOUSE) && ((*it) != dev) ) {
677 linkCombo.append_text((*it)->getName().c_str());
678 if ( (linked.length() > 0) && (linked == (*it)->getId()) ) {
679 linkCombo.set_active_text((*it)->getName().c_str());
680 }
681 }
682 }
683 linkCombo.set_sensitive(true);
684 } else {
685 linkCombo.set_sensitive(false);
686 }
687 linkConnection.unblock();
689 clear = false;
690 devName.set_label(row[cols.description]);
691 setupValueAndCombo( dev->getNumAxes(), dev->getNumAxes(), devAxesCount, axesCombo);
692 setupValueAndCombo( dev->getNumKeys(), dev->getNumKeys(), devKeyCount, buttonCombo);
693 }
694 }
696 devDetails.set_sensitive(!clear);
697 if (clear) {
698 devName.set_label("");
699 devAxesCount.set_label("");
700 devKeyCount.set_label("");
701 }
702 }
704 void InputDialogImpl::setupValueAndCombo( gint reported, gint actual, Gtk::Label& label, Gtk::ComboBoxText& combo )
705 {
706 gchar *tmp = g_strdup_printf("%d", reported);
707 label.set_label(tmp);
708 g_free(tmp);
710 combo.clear_items();
711 for ( gint i = 1; i <= reported; ++i ) {
712 tmp = g_strdup_printf("%d", i);
713 combo.append_text(tmp);
714 g_free(tmp);
715 }
717 if ( (1 <= actual) && (actual <= reported) ) {
718 combo.set_active(actual - 1);
719 }
720 }
722 void InputDialogImpl::updateTestButtons( Glib::ustring const& key, gint hotButton )
723 {
724 for ( gint i = 0; i < 24; i++ ) {
725 if ( buttonMap[key].find(i) != buttonMap[key].end() ) {
726 if ( i == hotButton ) {
727 testButtons[i].set(buttonsOnPix);
728 } else {
729 testButtons[i].set(buttonsOffPix);
730 }
731 } else {
732 testButtons[i].set(buttonsNonePix);
733 }
734 }
735 }
737 Glib::ustring InputDialogImpl::getKeyFor( GdkDevice* device )
738 {
739 Glib::ustring key;
740 switch ( device->source ) {
741 case GDK_SOURCE_MOUSE:
742 key = "M:";
743 break;
744 case GDK_SOURCE_CURSOR:
745 key = "C:";
746 break;
747 case GDK_SOURCE_PEN:
748 key = "P:";
749 break;
750 case GDK_SOURCE_ERASER:
751 key = "E:";
752 break;
753 default:
754 key = "?:";
755 }
756 key += device->name;
758 return key;
759 }
761 bool InputDialogImpl::eventSnoop(GdkEvent* event)
762 {
763 int modmod = 0;
765 GdkInputSource source = lastSourceSeen;
766 Glib::ustring devName = lastDevnameSeen;
767 Glib::ustring key;
768 gint hotButton = -1;
770 switch ( event->type ) {
771 case GDK_KEY_PRESS:
772 case GDK_KEY_RELEASE:
773 {
774 GdkEventKey* keyEvt = reinterpret_cast<GdkEventKey*>(event);
775 gchar* name = gtk_accelerator_name(keyEvt->keyval, static_cast<GdkModifierType>(keyEvt->state));
776 keyVal.set_label(name);
777 g_message("%d KEY state:0x%08x 0x%04x [%s]", keyEvt->type, keyEvt->state, keyEvt->keyval, name);
778 g_free(name);
779 }
780 break;
781 case GDK_BUTTON_PRESS:
782 modmod = 1;
783 // fallthrough
784 case GDK_BUTTON_RELEASE:
785 {
786 GdkEventButton* btnEvt = reinterpret_cast<GdkEventButton*>(event);
787 if ( btnEvt->device ) {
788 key = getKeyFor(btnEvt->device);
789 source = btnEvt->device->source;
790 devName = btnEvt->device->name;
792 if ( buttonMap[key].find(btnEvt->button) == buttonMap[key].end() ) {
793 g_message("New button found for %s = %d", key.c_str(), btnEvt->button);
794 buttonMap[key].insert(btnEvt->button);
795 DeviceManager::getManager().addButton(key, btnEvt->button);
796 }
797 hotButton = modmod ? btnEvt->button : -1;
798 updateTestButtons(key, hotButton);
799 }
800 gchar* name = gtk_accelerator_name(0, static_cast<GdkModifierType>(btnEvt->state));
801 keyVal.set_label(name);
802 g_message("%d BTN state:0x%08x %c %4d [%s] dev:%p [%s] ",
803 btnEvt->type, btnEvt->state,
804 (modmod ? '+':'-'),
805 btnEvt->button, name, btnEvt->device,
806 (btnEvt->device ? btnEvt->device->name : "null")
808 );
809 g_free(name);
810 }
811 break;
812 case GDK_MOTION_NOTIFY:
813 {
814 GdkEventMotion* btnMtn = reinterpret_cast<GdkEventMotion*>(event);
815 if ( btnMtn->device ) {
816 key = getKeyFor(btnMtn->device);
817 source = btnMtn->device->source;
818 devName = btnMtn->device->name;
819 }
820 gchar* name = gtk_accelerator_name(0, static_cast<GdkModifierType>(btnMtn->state));
821 keyVal.set_label(name);
822 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,
823 name, btnMtn->device,
824 (btnMtn->device ? btnMtn->device->name : "null"),
825 ((btnMtn->device && btnMtn->axes && (btnMtn->device->num_axes > 0)) ? btnMtn->axes[0]:0),
826 ((btnMtn->device && btnMtn->axes && (btnMtn->device->num_axes > 1)) ? btnMtn->axes[1]:0),
827 ((btnMtn->device && btnMtn->axes && (btnMtn->device->num_axes > 2)) ? btnMtn->axes[2]:0),
828 ((btnMtn->device && btnMtn->axes && (btnMtn->device->num_axes > 3)) ? btnMtn->axes[3]:0),
829 ((btnMtn->device && btnMtn->axes && (btnMtn->device->num_axes > 4)) ? btnMtn->axes[4]:0),
830 ((btnMtn->device && btnMtn->axes && (btnMtn->device->num_axes > 5)) ? btnMtn->axes[5]:0)
831 );
832 g_free(name);
833 }
834 break;
835 default:
836 ;// nothing
837 }
840 if ( (lastSourceSeen != source) || (lastDevnameSeen != devName) ) {
841 switch (source) {
842 case GDK_SOURCE_MOUSE:
843 {
844 testThumb.set(corePix);
845 }
846 break;
847 case GDK_SOURCE_CURSOR:
848 {
849 g_message("flip to cursor");
850 testThumb.set(mousePix);
851 }
852 break;
853 case GDK_SOURCE_PEN:
854 {
855 if (devName == "pad") {
856 g_message("flip to pad");
857 testThumb.set(sidebuttonsPix);
858 } else {
859 g_message("flip to pen");
860 testThumb.set(tipPix);
861 }
862 }
863 break;
864 case GDK_SOURCE_ERASER:
865 {
866 g_message("flip to eraser");
867 testThumb.set(eraserPix);
868 }
869 break;
870 default:
871 g_message("gurgle");
872 }
873 updateTestButtons(key, hotButton);
874 lastSourceSeen = source;
875 lastDevnameSeen = devName;
876 }
878 return false;
879 }
882 } // end namespace Inkscape
883 } // end namespace UI
884 } // end namespace Dialog
887 /*
888 Local Variables:
889 mode:c++
890 c-file-style:"stroustrup"
891 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
892 indent-tabs-mode:nil
893 fill-column:99
894 End:
895 */
896 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :