diff options
Diffstat (limited to 'gtk2_ardour/keyboard.cc')
-rw-r--r-- | gtk2_ardour/keyboard.cc | 519 |
1 files changed, 23 insertions, 496 deletions
diff --git a/gtk2_ardour/keyboard.cc b/gtk2_ardour/keyboard.cc index a6a14ad55b..517ef973d4 100644 --- a/gtk2_ardour/keyboard.cc +++ b/gtk2_ardour/keyboard.cc @@ -25,8 +25,6 @@ #include <ctype.h> -#include <X11/keysymdef.h> -#include <gdk/gdkx.h> #include <gdk/gdkkeysyms.h> #include <pbd/error.h> @@ -49,14 +47,13 @@ guint Keyboard::snap_mod = GDK_MOD3_MASK; uint32_t Keyboard::Control = GDK_CONTROL_MASK; uint32_t Keyboard::Shift = GDK_SHIFT_MASK; uint32_t Keyboard::Alt = GDK_MOD1_MASK; -uint32_t Keyboard::Meta = GDK_MOD2_MASK; +uint32_t Keyboard::Meta; Keyboard* Keyboard::_the_keyboard = 0; /* set this to initially contain the modifiers we care about, then track changes in ::set_edit_modifier() etc. */ -GdkModifierType Keyboard::RelevantModifierKeyMask = - GdkModifierType (GDK_SHIFT_MASK|GDK_CONTROL_MASK|GDK_MOD1_MASK|GDK_MOD3_MASK); +GdkModifierType Keyboard::RelevantModifierKeyMask; Keyboard::Keyboard () @@ -65,9 +62,25 @@ Keyboard::Keyboard () _the_keyboard = this; } - collecting_prefix = false; + RelevantModifierKeyMask = (GdkModifierType) gtk_accelerator_get_default_mod_mask (); - get_modifier_masks (); + /* figure out Meta */ + + uint32_t possible_meta[] = { GDK_MOD2_MASK, GDK_MOD3_MASK, GDK_MOD4_MASK, GDK_MOD5_MASK, 0}; + int i; + + for (i = 0; possible_meta[i]; ++i) { + if (!(RelevantModifierKeyMask & possible_meta[i])) { + break; + } + } + Meta = possible_meta[i]; + + if (Meta) { + cerr << "Using " << possible_meta[i] << " for Meta\n"; + } else { + cerr << "NO Meta\n"; + } snooper_id = gtk_key_snooper_install (_snooper, (gpointer) this); @@ -78,7 +91,6 @@ Keyboard::Keyboard () Keyboard::~Keyboard () { gtk_key_snooper_remove (snooper_id); - delete [] modifier_masks; } XMLNode& @@ -158,60 +170,6 @@ Keyboard::snooper (GtkWidget *widget, GdkEventKey *event) } if (event->type == GDK_KEY_PRESS) { - bool was_prefix = false; - - if (collecting_prefix) { - switch (keyval) { - case GDK_0: - current_prefix += '0'; - was_prefix = true; - break; - case GDK_1: - current_prefix += '1'; - was_prefix = true; - break; - case GDK_2: - current_prefix += '2'; - was_prefix = true; - break; - case GDK_3: - current_prefix += '3'; - was_prefix = true; - break; - case GDK_4: - current_prefix += '4'; - was_prefix = true; - break; - case GDK_5: - current_prefix += '5'; - was_prefix = true; - break; - case GDK_6: - current_prefix += '6'; - was_prefix = true; - break; - case GDK_7: - current_prefix += '7'; - was_prefix = true; - break; - case GDK_8: - current_prefix += '8'; - was_prefix = true; - break; - case GDK_9: - current_prefix += '9'; - was_prefix = true; - break; - case GDK_period: - current_prefix += '.'; - was_prefix = true; - break; - default: - was_prefix = false; - collecting_prefix = false; - break; - } - } if (find (state.begin(), state.end(), keyval) == state.end()) { state.push_back (keyval); @@ -238,441 +196,10 @@ Keyboard::key_is_down (uint32_t keyval) return find (state.begin(), state.end(), keyval) != state.end(); } -Keyboard::State -Keyboard::translate_key_name (const string& name) - -{ - string::size_type i; - string::size_type len; - bool at_end; - string::size_type hyphen; - string keyname; - string whatevers_left; - State result; - guint keycode; - - i = 0; - len = name.length(); - at_end = (len == 0); - - while (!at_end) { - - whatevers_left = name.substr (i); - - if ((hyphen = whatevers_left.find_first_of ('-')) == string::npos) { - - /* no hyphen, so use the whole thing */ - - keyname = whatevers_left; - at_end = true; - - } else { - - /* There is a hyphen. */ - - if (hyphen == 0 && whatevers_left.length() == 1) { - /* its the first and only character */ - - keyname = "-"; - at_end = true; - - } else { - - /* use the text before the hypen */ - - keyname = whatevers_left.substr (0, hyphen); - - if (hyphen == len - 1) { - at_end = true; - } else { - i += hyphen + 1; - at_end = (i >= len); - } - } - } - - if (keyname.length() == 1 && isupper (keyname[0])) { - result.push_back (GDK_Shift_L); - } - - if ((keycode = gdk_keyval_from_name(get_real_keyname (keyname).c_str())) == GDK_VoidSymbol) { - error << string_compose(_("KeyboardTarget: keyname \"%1\" is unknown."), keyname) << endmsg; - result.clear(); - return result; - } - - result.push_back (keycode); - } - - sort (result.begin(), result.end()); - - return result; -} - -string -Keyboard::get_real_keyname (const string& name) -{ - - if (name == "Control" || name == "Ctrl") { - return "Control_L"; - } - if (name == "Meta" || name == "MetaL") { - return "Meta_L"; - } - if (name == "MetaR") { - return "Meta_R"; - } - if (name == "Alt" || name == "AltL") { - return "Alt_L"; - } - if (name == "AltR") { - return "Alt_R"; - } - if (name == "Shift") { - return "Shift_L"; - } - if (name == "Shift_R") { - return "Shift_L"; - } - if (name == " ") { - return "space"; - } - if (name == "!") { - return "exclam"; - } - if (name == "\"") { - return "quotedbl"; - } - if (name == "#") { - return "numbersign"; - } - if (name == "$") { - return "dollar"; - } - if (name == "%") { - return "percent"; - } - if (name == "&") { - return "ampersand"; - } - if (name == "'") { - return "apostrophe"; - } - if (name == "'") { - return "quoteright"; - } - if (name == "(") { - return "parenleft"; - } - if (name == ")") { - return "parenright"; - } - if (name == "*") { - return "asterisk"; - } - if (name == "+") { - return "plus"; - } - if (name == ",") { - return "comma"; - } - if (name == "-") { - return "minus"; - } - if (name == ".") { - return "period"; - } - if (name == "/") { - return "slash"; - } - if (name == ":") { - return "colon"; - } - if (name == ";") { - return "semicolon"; - } - if (name == "<") { - return "less"; - } - if (name == "=") { - return "equal"; - } - if (name == ">") { - return "greater"; - } - if (name == "?") { - return "question"; - } - if (name == "@") { - return "at"; - } - if (name == "[") { - return "bracketleft"; - } - if (name == "\\") { - return "backslash"; - } - if (name == "]") { - return "bracketright"; - } - if (name == "^") { - return "asciicircum"; - } - if (name == "_") { - return "underscore"; - } - if (name == "`") { - return "grave"; - } - if (name == "`") { - return "quoteleft"; - } - if (name == "{") { - return "braceleft"; - } - if (name == "|") { - return "bar"; - } - if (name == "}") { - return "braceright"; - } - if (name == "~") { - return "asciitilde"; - } - - return name; -} - -int -Keyboard::get_prefix (float& val, bool& was_floating) -{ - if (current_prefix.length()) { - if (current_prefix.find ('.') != string::npos) { - was_floating = true; - } else { - was_floating = false; - } - if (sscanf (current_prefix.c_str(), "%f", &val) == 1) { - return 0; - } - current_prefix = ""; - } - return -1; -} - -void -Keyboard::start_prefix () -{ - collecting_prefix = true; - current_prefix = ""; -} - -void -Keyboard::clear_modifier_state () -{ - modifier_mask = 0; -} - -void -Keyboard::check_modifier_state () -{ - char keys[32]; - int i, j; - - clear_modifier_state (); - XQueryKeymap (GDK_DISPLAY(), keys); - - for (i = 0; i < 32; ++i) { - for (j = 0; j < 8; ++j) { - - if (keys[i] & (1<<j)) { - modifier_mask |= modifier_masks[(i*8)+j]; - } - } - } -} - -void -Keyboard::check_meta_numlock (char keycode, guint mod, string modname) -{ - guint alternate_meta_mod; - string alternate_meta_modname; - - if (mod == Meta) { - - guint keysym = XKeycodeToKeysym (GDK_DISPLAY(), keycode, 0); - - if (keysym == GDK_Num_Lock) { - - switch (mod) { - case GDK_MOD2_MASK: - alternate_meta_mod = GDK_MOD3_MASK; - alternate_meta_modname = "Mod3"; - break; - case GDK_MOD3_MASK: - alternate_meta_mod = GDK_MOD2_MASK; - alternate_meta_modname = "Mod2"; - break; - case GDK_MOD4_MASK: - alternate_meta_mod = GDK_MOD2_MASK; - alternate_meta_modname = "Mod2"; - break; - case GDK_MOD5_MASK: - alternate_meta_mod = GDK_MOD2_MASK; - alternate_meta_modname = "Mod2"; - break; - default: - error << string_compose (_("Your system is completely broken - NumLock uses \"%1\"" - "as its modifier. This is madness - see the man page " - "for xmodmap to find out how to fix this."), - modname) - << endmsg; - return; - } - - warning << string_compose (_("Your system generates \"%1\" when the NumLock key " - "is pressed. This can cause problems when editing " - "so Ardour will use %2 to mean Meta rather than %1"), - modname, alternate_meta_modname) - << endmsg; - - set_meta_modifier (alternate_meta_mod); - } - } -} - -void -Keyboard::get_modifier_masks () -{ - XModifierKeymap *modifiers; - KeyCode *keycode; - int i; - int bound; - - XDisplayKeycodes (GDK_DISPLAY(), &min_keycode, &max_keycode); - - /* This function builds a lookup table to provide rapid answers to - the question: what, if any, modmask, is associated with a given - keycode ? - */ - - modifiers = XGetModifierMapping (GDK_DISPLAY()); - - modifier_masks = new int32_t [max_keycode+1]; - - keycode = modifiers->modifiermap; - - for (i = 0; i < modifiers->max_keypermod; ++i) { /* shift */ - if (*keycode) { - modifier_masks[*keycode] = GDK_SHIFT_MASK; - // cerr << "Shift = " << XKeysymToString (XKeycodeToKeysym (GDK_DISPLAY(), *keycode, 0)) << endl; - } - keycode++; - } - - for (i = 0; i < modifiers->max_keypermod; ++i) keycode++; /* skip lock */ - - for (i = 0; i < modifiers->max_keypermod; ++i) { /* control */ - if (*keycode) { - modifier_masks[*keycode] = GDK_CONTROL_MASK; - // cerr << "Control = " << XKeysymToString (XKeycodeToKeysym (GDK_DISPLAY(), *keycode, 0)) << endl; - } - keycode++; - } - - bound = 0; - for (i = 0; i < modifiers->max_keypermod; ++i) { /* mod 1 */ - if (*keycode) { - modifier_masks[*keycode] = GDK_MOD1_MASK; - // cerr << "Mod1 = " << XKeysymToString (XKeycodeToKeysym (GDK_DISPLAY(), *keycode, 0)) << endl; - bound++; - } - keycode++; - } -#ifdef WARN_ABOUT_DUPLICATE_MODIFIERS - if (bound > 1) { - warning << string_compose (_("You have %1 keys bound to \"mod1\""), bound) << endmsg; - } -#endif - bound = 0; - for (i = 0; i < modifiers->max_keypermod; ++i) { /* mod2 */ - if (*keycode) { - modifier_masks[*keycode] = GDK_MOD2_MASK; - check_meta_numlock (*keycode, GDK_MOD2_MASK, "Mod2"); - //cerr << "Mod2 = " << std::hex << (int) *keycode << std::dec << " = " << XKeysymToString (XKeycodeToKeysym (GDK_DISPLAY(), *keycode, 0)) << endl; - bound++; - } - keycode++; - } -#ifdef WARN_ABOUT_DUPLICATE_MODIFIERS - if (bound > 1) { - warning << string_compose (_("You have %1 keys bound to \"mod2\""), bound) << endmsg; - } -#endif - bound = 0; - for (i = 0; i < modifiers->max_keypermod; ++i) { /* mod3 */ - if (*keycode) { - modifier_masks[*keycode] = GDK_MOD3_MASK; - check_meta_numlock (*keycode, GDK_MOD3_MASK, "Mod3"); - // cerr << "Mod3 = " << XKeysymToString (XKeycodeToKeysym (GDK_DISPLAY(), *keycode, 0)) << endl; - bound++; - } - keycode++; - } -#ifdef WARN_ABOUT_DUPLICATE_MODIFIERS - if (bound > 1) { - warning << string_compose (_("You have %1 keys bound to \"mod3\""), bound) << endmsg; - } -#endif - bound = 0; - for (i = 0; i < modifiers->max_keypermod; ++i) { /* mod 4 */ - if (*keycode) { - modifier_masks[*keycode] = GDK_MOD4_MASK; - check_meta_numlock (*keycode, GDK_MOD4_MASK, "Mod4"); - // cerr << "Mod4 = " << XKeysymToString (XKeycodeToKeysym (GDK_DISPLAY(), *keycode, 0)) << endl; - bound++; - } - keycode++; - } -#ifdef WARN_ABOUT_DUPLICATE_MODIFIERS - if (bound > 1) { - warning << string_compose (_("You have %1 keys bound to \"mod4\""), bound) << endmsg; - } -#endif - bound = 0; - for (i = 0; i < modifiers->max_keypermod; ++i) { /* mod 5 */ - if (*keycode) { - modifier_masks[*keycode] = GDK_MOD5_MASK; - check_meta_numlock (*keycode, GDK_MOD5_MASK, "Mod5"); - // cerr << "Mod5 = " << XKeysymToString (XKeycodeToKeysym (GDK_DISPLAY(), *keycode, 0)) << endl; - bound++; - } - keycode++; - } -#ifdef WARN_ABOUT_DUPLICATE_MODIFIERS - if (bound > 1) { - warning << string_compose (_("You have %1 keys bound to \"mod5\""), bound) << endmsg; - } -#endif - - XFreeModifiermap (modifiers); -} - bool Keyboard::enter_window (GdkEventCrossing *ev, Gtk::Window* win) { - switch (ev->detail) { - case GDK_NOTIFY_INFERIOR: - break; - - case GDK_NOTIFY_VIRTUAL: - /* fallthru */ - - default: - check_modifier_state (); - } - - return FALSE; + return false; } bool @@ -697,10 +224,9 @@ Keyboard::leave_window (GdkEventCrossing *ev, Gtk::Window* win) cerr << "clearing current target\n"; } state.clear (); - clear_modifier_state (); } - return FALSE; + return false; } void @@ -754,6 +280,7 @@ Keyboard::set_snap_modifier (guint mod) bool Keyboard::is_edit_event (GdkEventButton *ev) { + return (ev->type == GDK_BUTTON_PRESS || ev->type == GDK_BUTTON_RELEASE) && (ev->button == Keyboard::edit_button()) && ((ev->state & RelevantModifierKeyMask) == Keyboard::edit_modifier()); |