1 #ifndef _keymapper__hpp__included__
2 #define _keymapper__hpp__included__
13 * \brief Fixup command according to key polarity.
15 * Takes in a raw command and returns the command that should be actually executed given the key polarity.
17 * \param cmd Raw command.
18 * \param polarity Polarity (True => Being pressed, False => Being released).
19 * \return The fixed command, "" if no command should be executed.
20 * \throws std::bad_alloc Not enough memory.
22 std::string
fixup_command_polarity(std::string cmd
, bool polarity
) throw(std::bad_alloc
);
26 * \brief Keyboard mapper.
28 * This class handles internals of mapping events from keyboard buttons and pseudo-buttons. The helper class T has
29 * to have the following:
31 * unsigned T::mod_str(const std::string& mod): Translate modifiers set mod into modifier mask.
32 * typedef T::internal_keysymbol: Key symbol to match against. Needs to have == operator available.
33 * T::internal_keysymbol key_str(const std::string& keyname): Translate key name to key to match against.
34 * typedef T::keysymbol: Key symbol from keyboard (or pseudo-button). Carries modifiers too.
35 * unsigned mod_key(T::keysymbol key): Get modifier mask for keyboard key.
36 * T::internal_keysymbol key_key(T::keysymbol key): Get key symbol to match against for given keyboard key.
37 * std::string T::name_key(unsigned mod, unsigned modmask, T::internal_keysymbol key): Print name of key with mods.
46 * Binds a key, erroring out if binding would conflict with existing one.
48 * \param mod Modifier set to require to be pressed.
49 * \param modmask Modifier set to take into account.
50 * \param keyname Key to bind the action to.
51 * \param command The command to bind.
52 * \throws std::bad_alloc Not enough memory.
53 * \throws std::runtime_error The binding would conflict with existing one.
55 void bind(std::string mod
, std::string modmask
, std::string keyname
, std::string command
) throw(std::bad_alloc
,
58 unsigned _mod
= T::mod_str(mod
);
59 unsigned _modmask
= T::mod_str(modmask
);
61 throw std::runtime_error("Mod must be subset of modmask");
62 typename
T::internal_keysymbol _keyname
= T::key_str(keyname
);
63 /* Check for collisions. */
64 for(auto i
= bindings
.begin(); i
!= bindings
.end(); i
++) {
65 if(!(_keyname
== i
->symbol
))
67 if((_mod
& _modmask
& i
->modmask
) != (i
->mod
& _modmask
& i
->modmask
))
69 throw std::runtime_error("Would conflict with " + T::name_key(i
->mod
, i
->modmask
, i
->symbol
));
76 bindings
.push_back(k
);
80 * \brief Unbind a key.
82 * Unbinds a key, erroring out if binding does not exist..
84 * \param mod Modifier set to require to be pressed.
85 * \param modmask Modifier set to take into account.
86 * \param keyname Key to bind the action to.
87 * \throws std::bad_alloc Not enough memory.
88 * \throws std::runtime_error The binding does not exist.
90 void unbind(std::string mod
, std::string modmask
, std::string keyname
) throw(std::bad_alloc
,
93 unsigned _mod
= T::mod_str(mod
);
94 unsigned _modmask
= T::mod_str(modmask
);
95 typename
T::internal_keysymbol _keyname
= T::key_str(keyname
);
96 for(auto i
= bindings
.begin(); i
!= bindings
.end(); i
++) {
97 if(!(_keyname
== i
->symbol
) || _mod
!= i
->mod
|| _modmask
!= i
->modmask
)
102 throw std::runtime_error("No such binding");
106 * \brief Map key symbol from keyboard + polarity into a command.
108 * Takes in symbol from keyboard and polarity. Outputs command to run.
110 * \param sym Symbol from keyboard (with its mods).
111 * \param polarity True if key is being pressed, false if being released.
112 * \return The command to run. "" if none.
113 * \throws std::bad_alloc Not enough memory.
115 std::string
map(typename
T::keysymbol sym
, bool polarity
) throw(std::bad_alloc
)
117 unsigned _mod
= T::mod_key(sym
);
118 typename
T::internal_keysymbol _keyname
= T::key_key(sym
);
119 for(auto i
= bindings
.begin(); i
!= bindings
.end(); i
++) {
120 if((!(_keyname
== i
->symbol
)) || ((_mod
& i
->modmask
) != (i
->mod
& i
->modmask
)))
122 std::string x
= fixup_command_polarity(i
->command
, polarity
);
131 * \brief Dump list of bindigns as messages to specified graphics handle.
133 * \throws std::bad_alloc Not enough memory.
135 void dumpbindings() throw(std::bad_alloc
)
137 for(auto i
= bindings
.begin(); i
!= bindings
.end(); i
++)
138 messages
<< "bind " << T::name_key(i
->mod
, i
->modmask
, i
->symbol
) << " " << i
->command
146 typename
T::internal_keysymbol symbol
;
149 std::list
<kdata
> bindings
;