1 #ifndef _keymapper__hpp__included__
2 #define _keymapper__hpp__included__
14 * \brief Fixup command according to key polarity.
16 * Takes in a raw command and returns the command that should be actually executed given the key polarity.
18 * \param cmd Raw command.
19 * \param polarity Polarity (True => Being pressed, False => Being released).
20 * \return The fixed command, "" if no command should be executed.
21 * \throws std::bad_alloc Not enough memory.
23 std::string
fixup_command_polarity(std::string cmd
, bool polarity
) throw(std::bad_alloc
);
27 * \brief Keyboard mapper.
29 * This class handles internals of mapping events from keyboard buttons and pseudo-buttons. The helper class T has
30 * to have the following:
32 * unsigned T::mod_str(const std::string& mod): Translate modifiers set mod into modifier mask.
33 * typedef T::internal_keysymbol: Key symbol to match against. Needs to have == operator available.
34 * T::internal_keysymbol key_str(const std::string& keyname): Translate key name to key to match against.
35 * typedef T::keysymbol: Key symbol from keyboard (or pseudo-button). Carries modifiers too.
36 * unsigned mod_key(T::keysymbol key): Get modifier mask for keyboard key.
37 * T::internal_keysymbol key_key(T::keysymbol key): Get key symbol to match against for given keyboard key.
38 * std::string T::name_key(unsigned mod, unsigned modmask, T::internal_keysymbol key): Print name of key with mods.
47 * Binds a key, erroring out if binding would conflict with existing one.
49 * \param mod Modifier set to require to be pressed.
50 * \param modmask Modifier set to take into account.
51 * \param keyname Key to bind the action to.
52 * \param command The command to bind.
53 * \throws std::bad_alloc Not enough memory.
54 * \throws std::runtime_error The binding would conflict with existing one.
56 void bind(std::string mod
, std::string modmask
, std::string keyname
, std::string command
) throw(std::bad_alloc
,
59 unsigned _mod
= T::mod_str(mod
);
60 unsigned _modmask
= T::mod_str(modmask
);
62 throw std::runtime_error("Mod must be subset of modmask");
63 typename
T::internal_keysymbol _keyname
= T::key_str(keyname
);
64 /* Check for collisions. */
65 for(auto i
= bindings
.begin(); i
!= bindings
.end(); i
++) {
66 if(!(_keyname
== i
->symbol
))
68 if((_mod
& _modmask
& i
->modmask
) != (i
->mod
& _modmask
& i
->modmask
))
70 throw std::runtime_error("Would conflict with " + T::name_key(i
->mod
, i
->modmask
, i
->symbol
));
77 bindings
.push_back(k
);
81 * \brief Unbind a key.
83 * Unbinds a key, erroring out if binding does not exist..
85 * \param mod Modifier set to require to be pressed.
86 * \param modmask Modifier set to take into account.
87 * \param keyname Key to bind the action to.
88 * \throws std::bad_alloc Not enough memory.
89 * \throws std::runtime_error The binding does not exist.
91 void unbind(std::string mod
, std::string modmask
, std::string keyname
) throw(std::bad_alloc
,
94 unsigned _mod
= T::mod_str(mod
);
95 unsigned _modmask
= T::mod_str(modmask
);
96 typename
T::internal_keysymbol _keyname
= T::key_str(keyname
);
97 for(auto i
= bindings
.begin(); i
!= bindings
.end(); i
++) {
98 if(!(_keyname
== i
->symbol
) || _mod
!= i
->mod
|| _modmask
!= i
->modmask
)
103 throw std::runtime_error("No such binding");
107 * \brief Map key symbol from keyboard + polarity into a command.
109 * Takes in symbol from keyboard and polarity. Outputs command to run.
111 * \param sym Symbol from keyboard (with its mods).
112 * \param polarity True if key is being pressed, false if being released.
113 * \return The command to run. "" if none.
114 * \throws std::bad_alloc Not enough memory.
116 std::string
map(typename
T::keysymbol sym
, bool polarity
) throw(std::bad_alloc
)
118 unsigned _mod
= T::mod_key(sym
);
119 typename
T::internal_keysymbol _keyname
= T::key_key(sym
);
120 for(auto i
= bindings
.begin(); i
!= bindings
.end(); i
++) {
121 if((!(_keyname
== i
->symbol
)) || ((_mod
& i
->modmask
) != (i
->mod
& i
->modmask
)))
123 std::string x
= fixup_command_polarity(i
->command
, polarity
);
132 * \brief Dump list of bindigns as messages to specified graphics handle.
134 * \param win The graphics system handle.
135 * \throws std::bad_alloc Not enough memory.
137 void dumpbindings(window
* win
) throw(std::bad_alloc
)
139 for(auto i
= bindings
.begin(); i
!= bindings
.end(); i
++)
140 out(win
) << "bind " << T::name_key(i
->mod
, i
->modmask
, i
->symbol
) << " " << i
->command
148 typename
T::internal_keysymbol symbol
;
151 std::list
<kdata
> bindings
;