Merge pull request #466 from aginor/hotkeyrewrite
This reworks the hotkey system to rely on scancodes.
This commit is contained in:
commit
91cd168ec8
14 changed files with 1834 additions and 691 deletions
|
@ -66,7 +66,7 @@
|
|||
[/hotkey]
|
||||
[hotkey]
|
||||
command=command
|
||||
key=:
|
||||
key=;
|
||||
[/hotkey]
|
||||
[hotkey]
|
||||
command=continue
|
||||
|
@ -92,11 +92,11 @@
|
|||
[/hotkey]
|
||||
[hotkey]
|
||||
command=endunitturn
|
||||
key=" "
|
||||
key="space"
|
||||
[/hotkey]
|
||||
[hotkey]
|
||||
command=endturn
|
||||
key=" "
|
||||
key="space"
|
||||
#ifdef APPLE
|
||||
alt=yes
|
||||
#else
|
||||
|
@ -114,7 +114,7 @@
|
|||
[/hotkey]
|
||||
[hotkey]
|
||||
command=holdposition
|
||||
key=" "
|
||||
key="space"
|
||||
shift=yes
|
||||
[/hotkey]
|
||||
[hotkey]
|
||||
|
@ -262,7 +262,7 @@
|
|||
[/hotkey]
|
||||
[hotkey]
|
||||
command=zoomin
|
||||
key="+"
|
||||
key="="
|
||||
[/hotkey]
|
||||
[hotkey]
|
||||
command=zoomout
|
||||
|
@ -293,11 +293,11 @@
|
|||
[/hotkey]
|
||||
[hotkey]
|
||||
command=wbbumpupaction
|
||||
key="page up"
|
||||
key="PageUp"
|
||||
[/hotkey]
|
||||
[hotkey]
|
||||
command=wbbumpdownaction
|
||||
key="page down"
|
||||
key="PageDown"
|
||||
[/hotkey]
|
||||
[hotkey]
|
||||
command=wbsupposedead
|
||||
|
|
|
@ -443,6 +443,7 @@ set(wesnoth-sdl_SRC
|
|||
sdl/window.cpp
|
||||
sdl/utils.cpp
|
||||
sdl/shader.cpp
|
||||
sdl/keyboard.cpp
|
||||
xBRZ/xbrz.cpp
|
||||
)
|
||||
|
||||
|
|
|
@ -167,6 +167,7 @@ libwesnoth_sdl_sources = Split("""
|
|||
sdl/exception.cpp
|
||||
sdl/rect.cpp
|
||||
sdl/image.cpp
|
||||
sdl/keyboard.cpp
|
||||
sdl/window.cpp
|
||||
tracer.cpp
|
||||
xBRZ/xbrz.cpp
|
||||
|
|
|
@ -56,7 +56,7 @@ void controller_base::handle_event(const SDL_Event& event)
|
|||
// in which case the key press events should go only to it.
|
||||
if(have_keyboard_focus()) {
|
||||
process_keydown_event(event);
|
||||
hotkey::key_event(get_display(), event.key, get_hotkey_command_executor());
|
||||
hotkey::key_event(get_display(), event, get_hotkey_command_executor());
|
||||
} else {
|
||||
process_focus_keydown_event(event);
|
||||
break;
|
||||
|
@ -67,11 +67,11 @@ void controller_base::handle_event(const SDL_Event& event)
|
|||
break;
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
process_keydown_event(event);
|
||||
hotkey::jbutton_event(get_display(), event.jbutton, get_hotkey_command_executor());
|
||||
hotkey::jbutton_event(get_display(), event, get_hotkey_command_executor());
|
||||
break;
|
||||
case SDL_JOYHATMOTION:
|
||||
process_keydown_event(event);
|
||||
hotkey::jhat_event(get_display(), event.jhat, get_hotkey_command_executor());
|
||||
hotkey::jhat_event(get_display(), event, get_hotkey_command_executor());
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
// Ignore old mouse motion events in the event queue
|
||||
|
@ -91,7 +91,7 @@ void controller_base::handle_event(const SDL_Event& event)
|
|||
if (get_mouse_handler_base().get_show_menu()){
|
||||
show_menu(get_display().get_theme().context_menu()->items(),event.button.x,event.button.y,true, get_display());
|
||||
}
|
||||
hotkey::mbutton_event(get_display(), event.button, get_hotkey_command_executor());
|
||||
hotkey::mbutton_event(get_display(), event, get_hotkey_command_executor());
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
get_mouse_handler_base().mouse_press(event.button, is_browsing());
|
||||
|
|
|
@ -220,7 +220,7 @@ private:
|
|||
*
|
||||
* @param event The SDL joystick hat event triggered.
|
||||
*/
|
||||
void hat_motion(const SDL_JoyHatEvent& event);
|
||||
void hat_motion(const SDL_Event& event);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -228,7 +228,7 @@ private:
|
|||
*
|
||||
* @param event The SDL joystick button event triggered.
|
||||
*/
|
||||
void button_down(const SDL_JoyButtonEvent& event);
|
||||
void button_down(const SDL_Event& event);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -236,7 +236,7 @@ private:
|
|||
*
|
||||
* @param event The SDL keyboard event triggered.
|
||||
*/
|
||||
void key_down(const SDL_KeyboardEvent& event);
|
||||
void key_down(const SDL_Event& event);
|
||||
|
||||
/**
|
||||
* Handles the pressing of a hotkey.
|
||||
|
@ -245,7 +245,7 @@ private:
|
|||
*
|
||||
* @returns True if the hotkey is handled false otherwise.
|
||||
*/
|
||||
bool hotkey_pressed(const hotkey::hotkey_item& key);
|
||||
bool hotkey_pressed(const hotkey::hotkey_ptr key);
|
||||
|
||||
/**
|
||||
* Fires a key down event.
|
||||
|
@ -372,7 +372,7 @@ void thandler::handle_event(const SDL_Event& event)
|
|||
} break;
|
||||
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
button_down(event.jbutton);
|
||||
button_down(event);
|
||||
break;
|
||||
|
||||
case SDL_JOYBUTTONUP:
|
||||
|
@ -382,11 +382,11 @@ void thandler::handle_event(const SDL_Event& event)
|
|||
break;
|
||||
|
||||
case SDL_JOYHATMOTION:
|
||||
hat_motion(event.jhat);
|
||||
hat_motion(event);
|
||||
break;
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
key_down(event.key);
|
||||
key_down(event);
|
||||
break;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
|
@ -689,11 +689,11 @@ tdispatcher* thandler::keyboard_dispatcher()
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void thandler::hat_motion(const SDL_JoyHatEvent& event)
|
||||
void thandler::hat_motion(const SDL_Event& event)
|
||||
{
|
||||
const hotkey::hotkey_item& hk = hotkey::get_hotkey(event);
|
||||
const hotkey::hotkey_ptr& hk = hotkey::get_hotkey(event);
|
||||
bool done = false;
|
||||
if(!hk.null()) {
|
||||
if(!hk->null()) {
|
||||
done = hotkey_pressed(hk);
|
||||
}
|
||||
if(!done) {
|
||||
|
@ -702,11 +702,11 @@ void thandler::hat_motion(const SDL_JoyHatEvent& event)
|
|||
}
|
||||
}
|
||||
|
||||
void thandler::button_down(const SDL_JoyButtonEvent& event)
|
||||
void thandler::button_down(const SDL_Event& event)
|
||||
{
|
||||
const hotkey::hotkey_item& hk = hotkey::get_hotkey(event);
|
||||
const hotkey::hotkey_ptr hk = hotkey::get_hotkey(event);
|
||||
bool done = false;
|
||||
if(!hk.null()) {
|
||||
if(!hk->null()) {
|
||||
done = hotkey_pressed(hk);
|
||||
}
|
||||
if(!done) {
|
||||
|
@ -715,22 +715,22 @@ void thandler::button_down(const SDL_JoyButtonEvent& event)
|
|||
}
|
||||
}
|
||||
|
||||
void thandler::key_down(const SDL_KeyboardEvent& event)
|
||||
void thandler::key_down(const SDL_Event& event)
|
||||
{
|
||||
const hotkey::hotkey_item& hk = hotkey::get_hotkey(event);
|
||||
const hotkey::hotkey_ptr hk = hotkey::get_hotkey(event);
|
||||
bool done = false;
|
||||
if(!hk.null()) {
|
||||
if(!hk->null()) {
|
||||
done = hotkey_pressed(hk);
|
||||
}
|
||||
if(!done) {
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
key_down(event.keysym.sym,
|
||||
static_cast<const SDL_Keymod>(event.keysym.mod),
|
||||
key_down(event.key.keysym.sym,
|
||||
static_cast<const SDL_Keymod>(event.key.keysym.mod),
|
||||
"");
|
||||
#else
|
||||
key_down(event.keysym.sym,
|
||||
event.keysym.mod,
|
||||
unicode_cast<std::string>(static_cast<ucs4::char_t>(event.keysym.unicode)));
|
||||
key_down(event.key.keysym.sym,
|
||||
event.key.keysym.mod,
|
||||
unicode_cast<std::string>(static_cast<ucs4::char_t>(event.key.keysym.unicode)));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -740,7 +740,7 @@ void thandler::text_input(const std::string& unicode)
|
|||
key_down(static_cast<SDLKey>(0), static_cast<SDLMod>(0), unicode);
|
||||
}
|
||||
|
||||
bool thandler::hotkey_pressed(const hotkey::hotkey_item& key)
|
||||
bool thandler::hotkey_pressed(const hotkey::hotkey_ptr key)
|
||||
{
|
||||
tdispatcher* dispatcher = keyboard_dispatcher();
|
||||
|
||||
|
@ -748,7 +748,7 @@ bool thandler::hotkey_pressed(const hotkey::hotkey_item& key)
|
|||
return false;
|
||||
}
|
||||
|
||||
return dispatcher->execute_hotkey(hotkey::get_id(key.get_command()));
|
||||
return dispatcher->execute_hotkey(hotkey::get_id(key->get_command()));
|
||||
}
|
||||
|
||||
void thandler::key_down(const SDLKey key,
|
||||
|
|
|
@ -43,10 +43,7 @@ static lg::log_domain log_config("config");
|
|||
|
||||
namespace hotkey {
|
||||
|
||||
static void key_event_execute(display& disp, const SDL_KeyboardEvent& event, command_executor* executor);
|
||||
static void jbutton_event_execute(display& disp, const SDL_JoyButtonEvent& event, command_executor* executor);
|
||||
static void jhat_event_execute(display& disp, const SDL_JoyHatEvent& event, command_executor* executor);
|
||||
static void mbutton_event_execute(display& disp, const SDL_MouseButtonEvent& event, command_executor* executor);
|
||||
static void event_execute(display& disp, const SDL_Event& event, command_executor* executor);
|
||||
|
||||
bool command_executor::execute_command(const hotkey_command& cmd, int /*index*/)
|
||||
{
|
||||
|
@ -480,47 +477,47 @@ void basic_handler::handle_event(const SDL_Event& event)
|
|||
// handled by the executor.
|
||||
// If we're not in a dialog we can call the regular key event handler.
|
||||
if (!gui::in_dialog()) {
|
||||
key_event(*disp_, event.key,exec_);
|
||||
key_event(*disp_, event,exec_);
|
||||
} else if (exec_ != NULL) {
|
||||
key_event_execute(*disp_, event.key,exec_);
|
||||
event_execute(*disp_, event,exec_);
|
||||
}
|
||||
break;
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
if (!gui::in_dialog()) {
|
||||
jbutton_event(*disp_, event.jbutton,exec_);
|
||||
jbutton_event(*disp_, event,exec_);
|
||||
} else if (exec_ != NULL) {
|
||||
jbutton_event_execute(*disp_, event.jbutton,exec_);
|
||||
event_execute(*disp_, event,exec_);
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
if (!gui::in_dialog()) {
|
||||
mbutton_event(*disp_, event.button,exec_);
|
||||
mbutton_event(*disp_, event,exec_);
|
||||
} else if (exec_ != NULL) {
|
||||
mbutton_event_execute(*disp_, event.button,exec_);
|
||||
event_execute(*disp_, event,exec_);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mbutton_event(display& disp, const SDL_MouseButtonEvent& event, command_executor* executor)
|
||||
void mbutton_event(display& disp, const SDL_Event& event, command_executor* executor)
|
||||
{
|
||||
mbutton_event_execute(disp, event, executor);
|
||||
event_execute(disp, event, executor);
|
||||
}
|
||||
|
||||
void jbutton_event(display& disp, const SDL_JoyButtonEvent& event, command_executor* executor)
|
||||
void jbutton_event(display& disp, const SDL_Event& event, command_executor* executor)
|
||||
{
|
||||
jbutton_event_execute(disp, event, executor);
|
||||
event_execute(disp, event, executor);
|
||||
}
|
||||
|
||||
void jhat_event(display& disp, const SDL_JoyHatEvent& event, command_executor* executor)
|
||||
void jhat_event(display& disp, const SDL_Event& event, command_executor* executor)
|
||||
{
|
||||
jhat_event_execute(disp, event, executor);
|
||||
event_execute(disp, event, executor);
|
||||
}
|
||||
|
||||
void key_event(display& disp, const SDL_KeyboardEvent& event, command_executor* executor)
|
||||
void key_event(display& disp, const SDL_Event& event, command_executor* executor)
|
||||
{
|
||||
if (!executor) return;
|
||||
if(event.keysym.sym == SDLK_ESCAPE && disp.in_game()) {
|
||||
if(event.key.keysym.sym == SDLK_ESCAPE && disp.in_game()) {
|
||||
LOG_G << "escape pressed..showing quit\n";
|
||||
const int res = gui2::show_message(disp.video(), _("Quit"),
|
||||
_("Do you really want to quit?"), gui2::tmessage::yes_no_buttons);
|
||||
|
@ -531,13 +528,13 @@ void key_event(display& disp, const SDL_KeyboardEvent& event, command_executor*
|
|||
}
|
||||
}
|
||||
|
||||
key_event_execute(disp, event,executor);
|
||||
event_execute(disp, event,executor);
|
||||
}
|
||||
|
||||
void mbutton_event_execute(display& disp, const SDL_MouseButtonEvent& event, command_executor* executor)
|
||||
static void event_execute(display& disp, const SDL_Event& event, command_executor* executor)
|
||||
{
|
||||
if (!executor) return;
|
||||
const hotkey_item* hk = &get_hotkey(event);
|
||||
const hotkey_ptr hk = get_hotkey(event);
|
||||
if (!hk->active()) {
|
||||
return;
|
||||
}
|
||||
|
@ -546,52 +543,6 @@ void mbutton_event_execute(display& disp, const SDL_MouseButtonEvent& event, com
|
|||
executor->set_button_state(disp);
|
||||
}
|
||||
|
||||
void jbutton_event_execute(display& disp, const SDL_JoyButtonEvent& event, command_executor* executor)
|
||||
{
|
||||
if (!executor) return;
|
||||
const hotkey_item* hk = &get_hotkey(event);
|
||||
if (!hk->active()) {
|
||||
return;
|
||||
}
|
||||
|
||||
execute_command(disp, get_hotkey_command(hk->get_command()), executor);
|
||||
executor->set_button_state(disp);
|
||||
}
|
||||
|
||||
void jhat_event_execute(display& disp, const SDL_JoyHatEvent& event, command_executor* executor)
|
||||
{
|
||||
if (!executor) return;
|
||||
const hotkey_item* hk = &get_hotkey(event);
|
||||
if (!hk->active()) {
|
||||
return;
|
||||
}
|
||||
|
||||
execute_command(disp, get_hotkey_command(hk->get_command()), executor);
|
||||
executor->set_button_state(disp);
|
||||
}
|
||||
|
||||
void key_event_execute(display& disp, const SDL_KeyboardEvent& event, command_executor* executor)
|
||||
{
|
||||
if (!executor) return;
|
||||
const hotkey_item* hk = &get_hotkey(event);
|
||||
|
||||
#if 0
|
||||
// This is not generally possible without knowing keyboard layout.
|
||||
if (hk->null()) {
|
||||
//no matching hotkey was found, but try an in-exact match.
|
||||
hk = &get_hotkey(event, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!hk->active()) {
|
||||
return;
|
||||
}
|
||||
|
||||
execute_command(disp, get_hotkey_command(hk->get_command()), executor);
|
||||
executor->set_button_state(disp);
|
||||
}
|
||||
|
||||
|
||||
void execute_command(display& disp, const hotkey_command& command, command_executor* executor, int index)
|
||||
{
|
||||
const int zoom_amount = 4;
|
||||
|
|
|
@ -133,10 +133,11 @@ public:
|
|||
* Also handles some events in the function itself,
|
||||
* and so is still meaningful to call with executor=NULL
|
||||
*/
|
||||
void jbutton_event(display& disp, const SDL_JoyButtonEvent& event, command_executor* executor);
|
||||
void jhat_event(display& disp, const SDL_JoyHatEvent& event, command_executor* executor);
|
||||
void key_event(display& disp, const SDL_KeyboardEvent& event, command_executor* executor);
|
||||
void mbutton_event(display& disp, const SDL_MouseButtonEvent& event, command_executor* executor);
|
||||
void jbutton_event(display& disp, const SDL_Event& event, command_executor* executor);
|
||||
void jhat_event(display& disp, const SDL_Event& event, command_executor* executor);
|
||||
void key_event(display& disp, const SDL_Event& event, command_executor* executor);
|
||||
void mbutton_event(display& disp, const SDL_Event& event, command_executor* executor);
|
||||
|
||||
|
||||
//TODO
|
||||
void execute_command(display& disp, const hotkey_command& command, command_executor* executor, int index=-1);
|
||||
|
|
|
@ -389,9 +389,9 @@ void add_wml_hotkey(const std::string& id, const t_string& description, const co
|
|||
|
||||
if(!default_hotkey.empty() && !has_hotkey_item(id))
|
||||
{
|
||||
hotkey_item new_item(default_hotkey, true);
|
||||
new_item.set_command(id);
|
||||
if(new_item.valid())
|
||||
hotkey::hotkey_ptr new_item = hotkey::load_from_config(default_hotkey);
|
||||
new_item->set_command(id);
|
||||
if(new_item->valid())
|
||||
{
|
||||
DBG_G << "added default description for the wml hotkey with id=" + id;
|
||||
add_hotkey(new_item);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
|
||||
#include "log.hpp"
|
||||
#include "hotkey_item.hpp"
|
||||
#include "hotkey_command.hpp"
|
||||
|
@ -24,243 +25,384 @@
|
|||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include "key.hpp"
|
||||
|
||||
#include "SDL.h"
|
||||
|
||||
#if !SDL_VERSION_ATLEAST(2,0,0)
|
||||
#include "sdl/keyboard.hpp"
|
||||
#endif
|
||||
|
||||
static lg::log_domain log_config("config");
|
||||
#define ERR_G LOG_STREAM(err, lg::general)
|
||||
#define LOG_G LOG_STREAM(info, lg::general)
|
||||
#define DBG_G LOG_STREAM(debug, lg::general)
|
||||
#define ERR_CF LOG_STREAM(err, log_config)
|
||||
|
||||
namespace {
|
||||
|
||||
std::vector<hotkey::hotkey_item> hotkeys_;
|
||||
config default_hotkey_cfg_;
|
||||
|
||||
hotkey::hotkey_item null_hotkey_("null");
|
||||
|
||||
hotkey::hotkey_item& get_hotkey(int mouse, int joystick, int button, int hat, int value,
|
||||
bool shift, bool ctrl, bool cmd, bool alt)
|
||||
{
|
||||
std::vector<hotkey::hotkey_item>::iterator itor;
|
||||
|
||||
for (itor = hotkeys_.begin(); itor != hotkeys_.end(); ++itor) {
|
||||
|
||||
if ( !( hotkey::is_scope_active(hotkey::get_hotkey_command(itor->get_command()).scope) && itor->active() ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( itor->get_shift() != shift || itor->get_ctrl() != ctrl
|
||||
|| itor->get_cmd() != cmd || itor->get_alt() != alt ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( itor->get_joystick() == joystick && itor->get_button() == button
|
||||
&& itor->get_hat() == hat && itor->get_value() == value
|
||||
&& itor->get_mouse() == mouse ) {
|
||||
return *itor;
|
||||
}
|
||||
}
|
||||
|
||||
return null_hotkey_;
|
||||
}
|
||||
|
||||
hotkey::hotkey_item& get_hotkey(int character, int keycode,
|
||||
bool shift, bool ctrl, bool cmd, bool alt)
|
||||
{
|
||||
std::vector<hotkey::hotkey_item>::iterator itor;
|
||||
|
||||
DBG_G << "getting hotkey: char=" << lexical_cast<std::string>(character)
|
||||
<< " keycode=" << lexical_cast<std::string>(keycode) << " "
|
||||
<< (shift ? "shift," : "")
|
||||
<< (ctrl ? "ctrl," : "")
|
||||
<< (cmd ? "cmd," : "")
|
||||
<< (alt ? "alt," : "")
|
||||
<< "\n";
|
||||
|
||||
// Sometimes control modifies by -64, ie ^A == 1.
|
||||
if (0 < character && character < 64 && ctrl) {
|
||||
if (shift) {
|
||||
character += 64;
|
||||
} else {
|
||||
character += 96;
|
||||
}
|
||||
/// @todo
|
||||
DBG_G << "Mapped to character " << lexical_cast<std::string>(character) << "\n";
|
||||
}
|
||||
|
||||
// For some reason on Mac OS, if cmd and shift are down, the character doesn't get upper-cased
|
||||
if (cmd && character > 96 && character < 123 && shift) {
|
||||
character -= 32; }
|
||||
|
||||
bool found = false;
|
||||
|
||||
for (itor = hotkeys_.begin(); itor != hotkeys_.end(); ++itor) {
|
||||
// Special case for Ctrl+Return/Enter keys, which gets resolved to Ctrl-j and Ctrl-m characters (LF and CR respectively).
|
||||
// In such cases, do not match by character but go straight to key code.
|
||||
if (itor->get_character() != -1 &&
|
||||
!(tolower(character) == 'j' && keycode != SDLK_j) &&
|
||||
!(tolower(character) == 'm' && keycode != SDLK_m)) {
|
||||
if (character == itor->get_character()) {
|
||||
if (ctrl == itor->get_ctrl()
|
||||
&& cmd == itor->get_cmd()
|
||||
&& alt == itor->get_alt()) {
|
||||
if (hotkey::is_scope_active(hotkey::get_hotkey_command(itor->get_command()).scope) && itor->active()) {
|
||||
DBG_G << "Could match by character..." << "yes\n";
|
||||
found = true;
|
||||
break;
|
||||
} else {
|
||||
DBG_G << "Could match by character..." << "yes, but scope is inactive\n";
|
||||
}
|
||||
}
|
||||
DBG_G << "Could match by character..." << "but modifiers different\n";
|
||||
}
|
||||
} else if (itor->get_keycode() != -1) {
|
||||
if (keycode == itor->get_keycode()) {
|
||||
if (shift == itor->get_shift()
|
||||
&& ctrl == itor->get_ctrl()
|
||||
&& cmd == itor->get_cmd()
|
||||
&& alt == itor->get_alt()) {
|
||||
if (hotkey::is_scope_active(hotkey::get_hotkey_command(itor->get_command()).scope) && itor->active()) {
|
||||
DBG_G << "Could match by keycode..." << "yes\n";
|
||||
found = true;
|
||||
break;
|
||||
} else {
|
||||
DBG_G << "Could match by keycode..." << "yes, but scope is inactive\n";
|
||||
}
|
||||
}
|
||||
DBG_G << "Could match by keycode..." << "but modifiers different\n";
|
||||
}
|
||||
}
|
||||
if (found) { break; }
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
return null_hotkey_; }
|
||||
|
||||
return *itor;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
namespace hotkey {
|
||||
|
||||
hotkey_list hotkeys_;
|
||||
config default_hotkey_cfg_;
|
||||
|
||||
const hotkey_item& get_hotkey(const SDL_JoyButtonEvent& event)
|
||||
static unsigned int sdl_get_mods()
|
||||
{
|
||||
CKey keystate;
|
||||
bool shift = keystate[SDLK_RSHIFT] || keystate[SDLK_LSHIFT];
|
||||
bool ctrl = keystate[SDLK_RCTRL] || keystate[SDLK_LCTRL];
|
||||
bool cmd = keystate[SDLK_RMETA] || keystate[SDLK_LMETA];
|
||||
bool alt = keystate[SDLK_RALT] || keystate[SDLK_LALT];
|
||||
unsigned int mods;
|
||||
mods = SDL_GetModState();
|
||||
|
||||
return get_hotkey(-1, event.which, event.button, -1, -1, shift, ctrl, cmd, alt);
|
||||
}
|
||||
mods &= ~KMOD_NUM;
|
||||
mods &= ~KMOD_CAPS;
|
||||
mods &= ~KMOD_MODE;
|
||||
|
||||
const hotkey_item& get_hotkey(const SDL_JoyHatEvent& event)
|
||||
{
|
||||
CKey keystate;
|
||||
bool shift = keystate[SDLK_RSHIFT] || keystate[SDLK_LSHIFT];
|
||||
bool ctrl = keystate[SDLK_RCTRL] || keystate[SDLK_LCTRL];
|
||||
bool cmd = keystate[SDLK_RMETA] || keystate[SDLK_LMETA];
|
||||
bool alt = keystate[SDLK_RALT] || keystate[SDLK_LALT];
|
||||
// save the matching for checking right vs left keys
|
||||
if (mods & KMOD_SHIFT)
|
||||
mods |= KMOD_SHIFT;
|
||||
|
||||
return get_hotkey(-1, event.which, -1, event.hat, event.value, shift, ctrl, cmd, alt);
|
||||
}
|
||||
if (mods & KMOD_CTRL)
|
||||
mods |= KMOD_CTRL;
|
||||
|
||||
if (mods & KMOD_ALT)
|
||||
mods |= KMOD_ALT;
|
||||
|
||||
const hotkey_item& get_hotkey(const SDL_MouseButtonEvent& event)
|
||||
{
|
||||
CKey keystate;
|
||||
bool shift = keystate[SDLK_RSHIFT] || keystate[SDLK_LSHIFT];
|
||||
bool ctrl = keystate[SDLK_RCTRL] || keystate[SDLK_LCTRL];
|
||||
bool cmd = keystate[SDLK_RMETA] || keystate[SDLK_LMETA];
|
||||
bool alt = keystate[SDLK_RALT] || keystate[SDLK_LALT];
|
||||
|
||||
return get_hotkey(event.which, -1, event.button, -1, -1, shift, ctrl, cmd, alt);
|
||||
}
|
||||
|
||||
|
||||
const hotkey_item& get_hotkey(const SDL_KeyboardEvent& event)
|
||||
{
|
||||
return get_hotkey(
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
event.keysym.scancode,
|
||||
#if SDL_VERSION_ATLEAST(2,0,0)
|
||||
if (mods & KMOD_GUI)
|
||||
mods |= KMOD_GUI;
|
||||
#else
|
||||
event.keysym.unicode,
|
||||
if (mods & KMOD_META)
|
||||
mods |= KMOD_META;
|
||||
#endif
|
||||
event.keysym.sym,
|
||||
(event.keysym.mod & KMOD_SHIFT) != 0,
|
||||
(event.keysym.mod & KMOD_CTRL) != 0,
|
||||
(event.keysym.mod & KMOD_META) != 0,
|
||||
(event.keysym.mod & KMOD_ALT) != 0
|
||||
);
|
||||
|
||||
return mods;
|
||||
}
|
||||
|
||||
const std::string hotkey_base::get_name() const
|
||||
{
|
||||
std::string ret = "";
|
||||
|
||||
if (mod_ & KMOD_CTRL)
|
||||
ret += "ctrl";
|
||||
|
||||
std::string get_names(std::string id) {
|
||||
ret +=
|
||||
(!ret.empty() && !boost::algorithm::ends_with(ret, "+") ?
|
||||
"+" : "");
|
||||
if (mod_ & KMOD_ALT)
|
||||
ret += "alt";
|
||||
|
||||
std::vector<std::string> names;
|
||||
BOOST_FOREACH(const hotkey::hotkey_item& item, hotkeys_) {
|
||||
if (item.get_command() == id && (!item.null()) ) {
|
||||
names.push_back(item.get_name());
|
||||
}
|
||||
ret +=
|
||||
(!ret.empty() && !boost::algorithm::ends_with(ret, "+") ?
|
||||
"+" : "");
|
||||
if (mod_ & KMOD_SHIFT)
|
||||
ret += "shift";
|
||||
|
||||
ret +=
|
||||
(!ret.empty() && !boost::algorithm::ends_with(ret, "+") ?
|
||||
"+" : "");
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
if (mod_ & KMOD_GUI)
|
||||
#else
|
||||
if (mod_ & KMOD_META)
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
ret += "cmd";
|
||||
#else
|
||||
ret += "win";
|
||||
#endif
|
||||
|
||||
ret +=
|
||||
(!ret.empty() && !boost::algorithm::ends_with(ret, "+") ?
|
||||
"+" : "");
|
||||
return ret += get_name_helper();
|
||||
}
|
||||
|
||||
bool hotkey_base::bindings_equal(hotkey_ptr other)
|
||||
{
|
||||
|
||||
bool ret;
|
||||
|
||||
if (other == hotkey_ptr()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return boost::algorithm::join(names, ", ");
|
||||
hk_scopes scopematch = hotkey::get_hotkey_command(get_command()).scope
|
||||
& hotkey::get_hotkey_command(other->get_command()).scope;
|
||||
|
||||
if (scopematch.none()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = mod_ == other->mod_ && bindings_equal_helper(other);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const hotkey_item& get_hotkey(int mouse, int joystick, int button, int hat, int value,
|
||||
bool shift, bool ctrl, bool cmd, bool alt)
|
||||
bool hotkey_base::matches(const SDL_Event &event) const
|
||||
{
|
||||
return ::get_hotkey(mouse, joystick, button, hat, value,
|
||||
shift, ctrl, cmd, alt);
|
||||
unsigned int mods = sdl_get_mods();
|
||||
|
||||
if (!hotkey::is_scope_active(hotkey::get_hotkey_command(get_command()).scope) ||
|
||||
!active()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((mods != mod_)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return matches_helper(event);
|
||||
}
|
||||
|
||||
const hotkey::hotkey_item& get_hotkey(int character, int keycode,
|
||||
bool shift, bool ctrl, bool cmd, bool alt)
|
||||
void hotkey_base::save(config& item) const
|
||||
{
|
||||
return ::get_hotkey(character, keycode,
|
||||
shift, ctrl, cmd, alt);
|
||||
item["command"] = get_command();
|
||||
|
||||
item["shift"] = !!(mod_ & KMOD_SHIFT);
|
||||
item["ctrl"] = !!(mod_ & KMOD_CTRL);
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
item["cmd"] = !!(mod_ & KMOD_GUI);
|
||||
#else
|
||||
item["cmd"] = !!(mod_ & KMOD_META);
|
||||
#endif
|
||||
item["alt"] = !!(mod_ & KMOD_ALT);
|
||||
|
||||
save_helper(item);
|
||||
}
|
||||
|
||||
hotkey_ptr create_hotkey(const std::string &id, SDL_Event &event)
|
||||
{
|
||||
hotkey_ptr base = hotkey_ptr(new hotkey_void);
|
||||
|
||||
switch (event.type) {
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP: {
|
||||
hotkey_keyboard_ptr keyboard(new hotkey_keyboard());
|
||||
base = boost::dynamic_pointer_cast<hotkey_base>(keyboard);
|
||||
SDL_Scancode code;
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
code = event.key.keysym.scancode;
|
||||
#else
|
||||
code = SDL_GetScancodeFromKey(event.key.keysym.sym);
|
||||
#endif
|
||||
keyboard->set_scancode(code);
|
||||
break;
|
||||
}
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP: {
|
||||
hotkey_mouse_ptr mouse(new hotkey_mouse());
|
||||
base = boost::dynamic_pointer_cast<hotkey_base>(mouse);
|
||||
mouse->set_button(event.button.button);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ERR_G<< "Trying to bind an unknown event type:" << event.type << "\n";
|
||||
break;
|
||||
}
|
||||
|
||||
base->set_mods(sdl_get_mods());
|
||||
base->set_command(id);
|
||||
base->unset_default();
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
hotkey_ptr load_from_config(const config& cfg)
|
||||
{
|
||||
hotkey_ptr base = hotkey_ptr(new hotkey_void());
|
||||
|
||||
const std::string& mouse_cfg = cfg["mouse"];
|
||||
if (!mouse_cfg.empty()) {
|
||||
hotkey_mouse_ptr mouse(new hotkey_mouse());
|
||||
base = boost::dynamic_pointer_cast<hotkey_base>(mouse);
|
||||
mouse->set_button(cfg["button"].to_int());
|
||||
}
|
||||
// TODO: add joystick support back
|
||||
#if 0
|
||||
const std::string& joystick_cfg = cfg["joystick"];
|
||||
if (!joystick_cfg.empty()) {
|
||||
joystick_ = cfg["joystick"].to_int();
|
||||
}
|
||||
const std::string& hat = cfg["hat"];
|
||||
if (!hat.empty()) {
|
||||
hat_ = cfg["hat"].to_int();
|
||||
value_ = cfg["value"].to_int();
|
||||
}
|
||||
|
||||
const std::string& button = cfg["button"];
|
||||
if (!button.empty()) {
|
||||
button_ = cfg["button"].to_int();
|
||||
}
|
||||
#endif
|
||||
|
||||
const std::string& key_cfg = cfg["key"];
|
||||
if (!key_cfg.empty()) {
|
||||
hotkey_keyboard_ptr keyboard(new hotkey_keyboard());
|
||||
base = boost::dynamic_pointer_cast<hotkey_base>(keyboard);
|
||||
|
||||
SDL_Scancode scancode = SDL_GetScancodeFromName(key_cfg.c_str());
|
||||
if (scancode == SDL_SCANCODE_UNKNOWN) {
|
||||
ERR_G<< "Unknown key: " << key_cfg << "\n";
|
||||
}
|
||||
keyboard->set_scancode(scancode);
|
||||
}
|
||||
|
||||
if (base == hotkey_ptr()) {
|
||||
return base;
|
||||
}
|
||||
|
||||
unsigned int mods = 0;
|
||||
|
||||
if (cfg["shift"].to_bool())
|
||||
mods |= KMOD_SHIFT;
|
||||
if (cfg["ctrl"].to_bool())
|
||||
mods |= KMOD_CTRL;
|
||||
if (cfg["cmd"].to_bool())
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
mods |= KMOD_GUI;
|
||||
#else
|
||||
mods |= KMOD_META;
|
||||
#endif
|
||||
if (cfg["alt"].to_bool())
|
||||
mods |= KMOD_ALT;
|
||||
|
||||
base->set_mods(mods);
|
||||
base->set_command(cfg["command"].str());
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
bool hotkey_mouse::matches_helper(const SDL_Event &event) const
|
||||
{
|
||||
if (event.type != SDL_MOUSEBUTTONUP && event.type != SDL_MOUSEBUTTONDOWN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.button.button != button_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string hotkey_mouse::get_name_helper() const
|
||||
{
|
||||
return "mouse " + lexical_cast<std::string>(button_);
|
||||
}
|
||||
|
||||
void hotkey_mouse::save_helper(config &item) const
|
||||
{
|
||||
item["mouse"] = 0;
|
||||
if (button_ != 0) {
|
||||
item["button"] = button_;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string hotkey_keyboard::get_name_helper() const
|
||||
{
|
||||
std::string ret = std::string(SDL_GetKeyName(SDL_GetKeyFromScancode(scancode_)));
|
||||
|
||||
if (ret.size() == 1) {
|
||||
boost::algorithm::to_lower(ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool hotkey_keyboard::matches_helper(const SDL_Event &event) const
|
||||
{
|
||||
if (event.type != SDL_KEYDOWN && event.type != SDL_KEYUP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_Scancode code;
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
code = event.key.keysym.scancode;
|
||||
#else
|
||||
code = SDL_GetScancodeFromKey(event.key.keysym.sym);
|
||||
#endif
|
||||
|
||||
if (code != scancode_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hotkey_mouse::bindings_equal_helper(hotkey_ptr other) const
|
||||
{
|
||||
hotkey_mouse_ptr other_m = boost::dynamic_pointer_cast<hotkey_mouse>(other);
|
||||
|
||||
if (other_m == hotkey_mouse_ptr()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return button_ == other_m->button_;
|
||||
}
|
||||
|
||||
void hotkey_keyboard::save_helper(config &item) const
|
||||
{
|
||||
if (scancode_ != SDL_SCANCODE_UNKNOWN) {
|
||||
item["key"] = SDL_GetScancodeName(scancode_);
|
||||
}
|
||||
}
|
||||
|
||||
bool has_hotkey_item(const std::string& command)
|
||||
{
|
||||
BOOST_FOREACH(hotkey_item& item, hotkeys_)
|
||||
{
|
||||
if(item.get_command() == command)
|
||||
BOOST_FOREACH(hotkey_ptr item, hotkeys_) {
|
||||
if (item->get_command() == command) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void add_hotkey(const hotkey_item& item) {
|
||||
bool hotkey_keyboard::bindings_equal_helper(hotkey_ptr other) const
|
||||
{
|
||||
hotkey_keyboard_ptr other_k = boost::dynamic_pointer_cast<hotkey_keyboard>(
|
||||
other);
|
||||
if (other_k == hotkey_keyboard_ptr()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return scancode_ == other_k->scancode_;
|
||||
}
|
||||
|
||||
void del_hotkey(hotkey_ptr item)
|
||||
{
|
||||
if (!hotkeys_.empty()) {
|
||||
hotkeys_.erase(std::remove(hotkeys_.begin(), hotkeys_.end(), item));
|
||||
}
|
||||
}
|
||||
|
||||
void add_hotkey(const hotkey_ptr item)
|
||||
{
|
||||
|
||||
if (item == hotkey_ptr()) {
|
||||
return;
|
||||
}
|
||||
|
||||
scope_changer scope_ch;
|
||||
set_active_scopes(hotkey::get_hotkey_command(item.get_command()).scope);
|
||||
set_active_scopes(hotkey::get_hotkey_command(item->get_command()).scope);
|
||||
|
||||
hotkey_item& old_hk = (item.get_mouse() != -1 || item.get_joystick() != -1) ?
|
||||
::get_hotkey(item.get_mouse(), item.get_joystick(), item.get_button(), item.get_hat()
|
||||
, item.get_value(), item.get_shift(), item.get_ctrl(), item.get_cmd(), item.get_alt()) :
|
||||
::get_hotkey(item.get_character(), item.get_keycode(),
|
||||
item.get_shift(), item.get_ctrl(), item.get_cmd(), item.get_alt());
|
||||
|
||||
if (old_hk.active()) {
|
||||
old_hk.set_command(item.get_command());
|
||||
old_hk.unset_default();
|
||||
if (!hotkeys_.empty()) {
|
||||
hotkeys_.erase(
|
||||
std::remove_if(hotkeys_.begin(), hotkeys_.end(),
|
||||
boost::bind(&hotkey_base::bindings_equal, _1, (item))),
|
||||
hotkeys_.end());
|
||||
}
|
||||
else
|
||||
hotkeys_.push_back(item);
|
||||
|
||||
hotkeys_.push_back(item);
|
||||
|
||||
}
|
||||
|
||||
void clear_hotkeys(const std::string& command)
|
||||
{
|
||||
BOOST_FOREACH(hotkey::hotkey_item& item, hotkeys_) {
|
||||
if (item.get_command() == command) {
|
||||
item.clear(); }
|
||||
BOOST_FOREACH(hotkey::hotkey_ptr item, hotkeys_) {
|
||||
if (item->get_command() == command) {
|
||||
item->clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,11 +411,26 @@ void clear_hotkeys()
|
|||
hotkeys_.clear();
|
||||
}
|
||||
|
||||
const hotkey_ptr get_hotkey(const SDL_Event &event)
|
||||
{
|
||||
BOOST_FOREACH(hotkey_ptr item, hotkeys_) {
|
||||
if (item->matches(event)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return hotkey_ptr(new hotkey_void());
|
||||
}
|
||||
|
||||
void load_hotkeys(const config& cfg, bool set_as_default)
|
||||
{
|
||||
BOOST_FOREACH(const config &hk, cfg.child_range("hotkey")) {
|
||||
hotkey_item item = hotkey_item(hk, set_as_default);
|
||||
if(!item.null()){
|
||||
|
||||
hotkey_ptr item = load_from_config(hk);
|
||||
if (!set_as_default) {
|
||||
item->unset_default();
|
||||
}
|
||||
|
||||
if (!item->null()) {
|
||||
add_hotkey(item);
|
||||
}
|
||||
}
|
||||
|
@ -287,14 +444,14 @@ void reset_default_hotkeys()
|
|||
{
|
||||
hotkeys_.clear();
|
||||
|
||||
if(!default_hotkey_cfg_.empty()) {
|
||||
if (!default_hotkey_cfg_.empty()) {
|
||||
load_hotkeys(default_hotkey_cfg_, true);
|
||||
} else {
|
||||
ERR_G << "no default hotkeys set yet; all hotkeys are now unassigned!" << std::endl;
|
||||
ERR_G<< "no default hotkeys set yet; all hotkeys are now unassigned!" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<hotkey_item>& get_hotkeys()
|
||||
const hotkey_list& get_hotkeys()
|
||||
{
|
||||
return hotkeys_;
|
||||
}
|
||||
|
@ -303,258 +460,24 @@ void save_hotkeys(config& cfg)
|
|||
{
|
||||
cfg.clear_children("hotkey");
|
||||
|
||||
for(std::vector<hotkey_item>::iterator i = hotkeys_.begin();
|
||||
i != hotkeys_.end(); ++i)
|
||||
{
|
||||
if (!i->is_default())
|
||||
i->save(cfg.add_child("hotkey"));
|
||||
}
|
||||
}
|
||||
|
||||
bool hotkey_item::active() const
|
||||
{
|
||||
return !(command_ == "null");
|
||||
}
|
||||
|
||||
bool hotkey_item::valid() const
|
||||
{
|
||||
return (character_ | keycode_ | joystick_ | mouse_ | button_ | hat_ | value_) != 0;
|
||||
}
|
||||
|
||||
// There are two kinds of "key" values.
|
||||
// One refers to actual keys, like F1 or SPACE.
|
||||
// The other refers to characters produced, eg 'M' or ':'.
|
||||
// For the latter, specifying shift+; doesn't make sense,
|
||||
// because ; is already shifted on French keyboards, for example.
|
||||
// You really want to say ':', however that is typed.
|
||||
// However, when you say shift+SPACE,
|
||||
// you're really referring to the space bar,
|
||||
// as shift+SPACE usually just produces a SPACE character.
|
||||
void hotkey_item::load_from_config(const config& cfg)
|
||||
{
|
||||
command_ = cfg["command"].str();
|
||||
|
||||
const std::string& mouse = cfg["mouse"];
|
||||
if (!mouse.empty()) {
|
||||
mouse_ = cfg["mouse"].to_int();
|
||||
button_ = cfg["button"].to_int();
|
||||
}
|
||||
const std::string& joystick = cfg["joystick"];
|
||||
if (!joystick.empty()) {
|
||||
joystick_ = cfg["joystick"].to_int();
|
||||
}
|
||||
const std::string& hat = cfg["hat"];
|
||||
if (!hat.empty()) {
|
||||
hat_ = cfg["hat"].to_int();
|
||||
value_ = cfg["value"].to_int();
|
||||
}
|
||||
|
||||
const std::string& button = cfg["button"];
|
||||
if (!button.empty()) {
|
||||
button_ = cfg["button"].to_int();
|
||||
}
|
||||
|
||||
shift_ = cfg["shift"].to_bool();
|
||||
ctrl_ = cfg["ctrl"].to_bool();
|
||||
cmd_ = cfg["cmd"].to_bool();
|
||||
alt_ = cfg["alt"].to_bool();
|
||||
|
||||
const std::string& key = cfg["key"];
|
||||
if (key.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ucs4::string wkey = unicode_cast<ucs4::string>(key);
|
||||
|
||||
// They may really want a specific key on the keyboard:
|
||||
// we assume that any single character keyname is a character.
|
||||
if (wkey.size() > 1) {
|
||||
|
||||
keycode_ = sdl_keysym_from_name(key);
|
||||
if (keycode_ == SDLK_UNKNOWN) {
|
||||
if (tolower(key[0]) != 'f') {
|
||||
ERR_CF << "hotkey key '" << key << "' invalid" << std::endl;
|
||||
} else {
|
||||
int num = lexical_cast_default<int>(key.c_str() + 1);
|
||||
keycode_ = num + SDLK_F1 - 1;
|
||||
}
|
||||
BOOST_FOREACH(hotkey_ptr item, hotkeys_) {
|
||||
if (!item->is_default()) {
|
||||
item->save(cfg.add_child("hotkey"));
|
||||
}
|
||||
} else if (key == " " || shift_
|
||||
#ifdef __APPLE__
|
||||
|| alt_
|
||||
#endif
|
||||
) {
|
||||
// Space must be treated as a key because shift-space
|
||||
// isn't a different character from space,
|
||||
// and control key makes it go weird.
|
||||
// shift=yes should never be specified on single characters
|
||||
// (eg. key=m, shift=yes would be key=M),
|
||||
// but we don't want to break old preferences files.
|
||||
keycode_ = wkey[0];
|
||||
} else {
|
||||
character_ = wkey[0];
|
||||
}
|
||||
}
|
||||
|
||||
void hotkey_item::set_command(const std::string& command) {
|
||||
command_ = command;
|
||||
}
|
||||
|
||||
std::string hotkey_item::get_name() const
|
||||
std::string get_names(std::string id)
|
||||
{
|
||||
std::stringstream str;
|
||||
|
||||
if (shift_) { str << "shift+"; }
|
||||
if (ctrl_) { str << "ctrl+"; }
|
||||
if (cmd_) { str << "cmd+"; }
|
||||
if (alt_) { str << "alt+"; }
|
||||
|
||||
if (mouse_ >= 0) { str << _("Mouse") << mouse_ << _("Button") << button_; }
|
||||
if (character_ != -1) { str << static_cast<char>(character_); }
|
||||
if (keycode_ != -1) { str << SDL_GetKeyName(SDLKey(keycode_)); }
|
||||
if (joystick_ >= 0) { str << _("Joystick") << joystick_ << _("Button") << button_; }
|
||||
|
||||
if (value_ >= 0) {
|
||||
std::string direction;
|
||||
switch (value_) {
|
||||
case SDL_HAT_CENTERED:
|
||||
direction = _("Centered");
|
||||
break;
|
||||
case SDL_HAT_UP:
|
||||
direction = _("Up");
|
||||
break;
|
||||
case SDL_HAT_RIGHT:
|
||||
direction = _("Right");
|
||||
break;
|
||||
case SDL_HAT_DOWN:
|
||||
direction = _("Down");
|
||||
break;
|
||||
case SDL_HAT_LEFT:
|
||||
direction = _("Left");
|
||||
break;
|
||||
case SDL_HAT_RIGHTUP:
|
||||
direction = _("RightUp");
|
||||
break;
|
||||
case SDL_HAT_RIGHTDOWN:
|
||||
direction = _("RightDown");
|
||||
break;
|
||||
case SDL_HAT_LEFTUP:
|
||||
direction = _("LeftUp");
|
||||
break;
|
||||
case SDL_HAT_LEFTDOWN:
|
||||
direction = _("LeftDown");
|
||||
break;
|
||||
default:
|
||||
direction = _("Unknown");
|
||||
break;
|
||||
std::vector<std::string> names;
|
||||
BOOST_FOREACH(const hotkey::hotkey_ptr item, hotkeys_) {
|
||||
if (item->get_command() == id && (!item->null())) {
|
||||
names.push_back(item->get_name());
|
||||
}
|
||||
str << _("Joystick") << joystick_ << _("Hat") << button_ << direction;
|
||||
}
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
void hotkey_item::clear()
|
||||
{
|
||||
command_ = "null";
|
||||
}
|
||||
|
||||
void hotkey_item::save(config& item) const
|
||||
{
|
||||
if (get_button() >= 0) item["button"] = get_button();
|
||||
if (get_joystick() >= 0) item["joystick"] = get_joystick();
|
||||
if (get_hat() >= 0) item["hat"] = get_hat();
|
||||
if (get_value() >= 0) item["value"] = get_value();
|
||||
if (get_keycode() >= 0) item["key"] = SDL_GetKeyName(SDLKey(get_keycode()));
|
||||
if (get_character() >= 0) item["key"] = unicode_cast<utf8::string>(static_cast<ucs4::char_t>(get_character()));
|
||||
if (get_mouse() >= 0) item["mouse"] = get_mouse();
|
||||
if (get_button() >= 0) item["button"] = get_button();
|
||||
|
||||
item["command"] = get_command();
|
||||
if (get_shift()) item["shift"] = get_shift();
|
||||
if (get_ctrl() ) item["ctrl"] = get_ctrl();
|
||||
if (get_cmd() ) item["cmd"] = get_cmd();
|
||||
if (get_alt() ) item["alt"] = get_alt();
|
||||
}
|
||||
|
||||
void hotkey_item::set_jbutton(int joystick, int button,
|
||||
bool shift, bool ctrl, bool cmd, bool alt)
|
||||
{
|
||||
joystick_ = joystick;
|
||||
button_ = button;
|
||||
shift_ = shift;
|
||||
ctrl_ = ctrl;
|
||||
cmd_ = cmd;
|
||||
alt_ = alt;
|
||||
}
|
||||
|
||||
void hotkey_item::set_jhat(int joystick, int hat, int value,
|
||||
bool shift, bool ctrl, bool cmd, bool alt)
|
||||
{
|
||||
joystick_ = joystick;
|
||||
hat_ = hat;
|
||||
value_ = value;
|
||||
shift_ = shift;
|
||||
ctrl_ = ctrl;
|
||||
cmd_ = cmd;
|
||||
alt_ = alt;
|
||||
}
|
||||
|
||||
void hotkey_item::set_mbutton(int mouse, int button,
|
||||
bool shift, bool ctrl, bool cmd, bool alt)
|
||||
{
|
||||
mouse_ = mouse;
|
||||
button_ = button;
|
||||
shift_ = shift;
|
||||
ctrl_ = ctrl;
|
||||
cmd_ = cmd;
|
||||
alt_ = alt;
|
||||
}
|
||||
|
||||
void hotkey_item::set_key(int character, int keycode,
|
||||
bool shift, bool ctrl, bool cmd, bool alt)
|
||||
{
|
||||
LOG_G << "setting hotkey: char=" << lexical_cast<std::string>(character)
|
||||
<< " keycode=" << lexical_cast<std::string>(keycode) << " "
|
||||
<< (shift ? "shift," : "")
|
||||
<< (ctrl ? "ctrl," : "")
|
||||
<< (cmd ? "cmd," : "")
|
||||
<< (alt ? "alt," : "")
|
||||
<< "\n";
|
||||
|
||||
// Sometimes control modifies by -64, ie ^A == 1.
|
||||
if (character < 64 && ctrl) {
|
||||
if (shift) {
|
||||
character += 64; }
|
||||
else {
|
||||
character += 96; }
|
||||
LOG_G << "Mapped to character " << lexical_cast<std::string>(character) << "\n";
|
||||
}
|
||||
|
||||
// For some reason on Mac OS, if cmd and shift are down, the character doesn't get upper-cased
|
||||
if (cmd && character > 96 && character < 123 && shift) {
|
||||
character -= 32; }
|
||||
|
||||
// We handle simple cases by character, others by the actual key.
|
||||
// @ and ` are exceptions related to the space character. Without these, combinations involving Ctrl or Ctrl+Shift often resolve the character value to null (or @ and `).
|
||||
// j and m exceptions are to catch Ctrl+Return/Enter, which is interpreted as Ctrl+j and Ctrl+m characters (LF and CR respectively).
|
||||
if (isprint(character) && !isspace(character) &&
|
||||
character != '@' && character != '`' &&
|
||||
!(tolower(character) == 'j' && keycode != SDLK_j) &&
|
||||
!(tolower(character) == 'm' && keycode != SDLK_m)) {
|
||||
character_ = character;
|
||||
ctrl_ = ctrl;
|
||||
cmd_ = cmd;
|
||||
alt_ = alt;
|
||||
LOG_G << "type = BY_CHARACTER\n";
|
||||
} else {
|
||||
keycode_ = keycode;
|
||||
shift_ = shift;
|
||||
ctrl_ = ctrl;
|
||||
cmd_ = cmd;
|
||||
alt_ = alt;
|
||||
LOG_G << "type = BY_KEYCODE\n";
|
||||
}
|
||||
return boost::algorithm::join(names, ", ");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,154 +12,403 @@
|
|||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HOTKEY_ITEM_HPP_INCLUDED
|
||||
#define HOTKEY_ITEM_HPP_INCLUDED
|
||||
|
||||
#include "config.hpp"
|
||||
#include "SDL_events.h"
|
||||
#include "SDL.h"
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <vector>
|
||||
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
#include "sdl/keyboard.hpp"
|
||||
#endif
|
||||
|
||||
namespace hotkey {
|
||||
|
||||
/* forward declarations */
|
||||
class hotkey_base;
|
||||
class hotkey_mouse;
|
||||
class hotkey_keyboard;
|
||||
typedef boost::shared_ptr<hotkey_base> hotkey_ptr;
|
||||
typedef boost::shared_ptr<hotkey_mouse> hotkey_mouse_ptr;
|
||||
typedef boost::shared_ptr<hotkey_keyboard> hotkey_keyboard_ptr;
|
||||
|
||||
class hotkey_item {
|
||||
typedef std::vector<hotkey::hotkey_ptr> hotkey_list;
|
||||
typedef std::vector<hotkey::hotkey_ptr>::iterator hotkey_list_iter;
|
||||
|
||||
/**
|
||||
* This is the base class for hotkey event matching.
|
||||
*/
|
||||
class hotkey_base
|
||||
{
|
||||
public:
|
||||
|
||||
explicit hotkey_item(const std::string& command) :
|
||||
command_(command),
|
||||
shift_(false), ctrl_(false), cmd_(false), alt_(false),
|
||||
character_(-1), keycode_(-1),
|
||||
joystick_(-1), mouse_(-1),
|
||||
button_(-1), hat_(-1), value_(-1),
|
||||
is_default_(false)
|
||||
/**
|
||||
* Initialises a new empty hotkey that will be disabled
|
||||
*/
|
||||
hotkey_base() : command_("null"), is_default_(true), mod_(0)
|
||||
{}
|
||||
|
||||
explicit hotkey_item(const config& cfg, bool is_default):
|
||||
command_("null"),
|
||||
shift_(false), ctrl_(false), cmd_(false), alt_(false),
|
||||
character_(-1), keycode_(-1),
|
||||
joystick_(-1), mouse_(-1),
|
||||
button_(-1), hat_(-1), value_(-1),
|
||||
is_default_(is_default)
|
||||
void set_command(const std::string& command)
|
||||
{
|
||||
load_from_config(cfg);
|
||||
command_ = command;
|
||||
}
|
||||
|
||||
void load_from_config(const config& cfg);
|
||||
/**
|
||||
* Set keyboard modifiers.
|
||||
* @param mods Bitmask of SDLMod.
|
||||
*/
|
||||
void set_mods(unsigned int mods)
|
||||
{
|
||||
mod_ = mods;
|
||||
}
|
||||
|
||||
void set_command(const std::string& command);
|
||||
/**
|
||||
* Returns the string name of the HOTKEY_COMMAND
|
||||
* @return The unique string for a hotkey command.
|
||||
**/
|
||||
const std::string& get_command() const
|
||||
{
|
||||
return command_;
|
||||
}
|
||||
|
||||
/** get the string name of the HOTKEY_COMMAND */
|
||||
const std::string get_command() const { return command_; }
|
||||
/** The translated description */
|
||||
/**
|
||||
* Returns the translated description
|
||||
* @todo unused
|
||||
* @return internationalised description of the command.
|
||||
**/
|
||||
const std::string get_description() const;
|
||||
/** @return if the item should appear in the hotkey preferences */
|
||||
bool hidden() const;
|
||||
|
||||
bool is_default() const { return is_default_; }
|
||||
|
||||
void unset_default(bool is_not_default = true) {
|
||||
is_default_ = !is_not_default;
|
||||
/**
|
||||
* This controls whether the item should appear in the hotkey preferences.
|
||||
* @return true if the item should be hidden
|
||||
**/
|
||||
virtual bool hidden() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Return "name" of hotkey. Example :"ctrl+alt+g"
|
||||
std::string get_name() const;
|
||||
/**
|
||||
* This indicates whether a hotkey is from the default config or if it's
|
||||
* from the user preferences.
|
||||
* @return true if from the default configurations, false otherwise
|
||||
*/
|
||||
bool is_default() const
|
||||
{
|
||||
return is_default_;
|
||||
}
|
||||
|
||||
void clear();
|
||||
/**
|
||||
* Used to indicate that a hotkey is overriden and should be treated as
|
||||
* a user-set hotkey.
|
||||
*/
|
||||
void unset_default()
|
||||
{
|
||||
is_default_ = false;
|
||||
}
|
||||
|
||||
bool null() const { return command_ == "null"; }
|
||||
/**
|
||||
* Unbind this hotkey by linking it to the null-command
|
||||
*/
|
||||
void clear()
|
||||
{
|
||||
command_ = "null";
|
||||
}
|
||||
|
||||
/// returns weather there is a associated hotkey_command.
|
||||
// if the none of the hotkey_commands fits this hotkey_item then get_hotkey_command will return the hotkey_command::null_command().
|
||||
bool active() const;
|
||||
/**
|
||||
* Returns whether this hotkey points to the null-command
|
||||
* @return true if it points to the null-command, false otherwise.
|
||||
*/
|
||||
bool null() const
|
||||
{
|
||||
return command_ == "null";
|
||||
}
|
||||
|
||||
/// checks weather that hotkey "makes sense" meaning weather one of character, keycode, joystick, mouse, button, hat, value is set.
|
||||
/// i don't know what the axis_.. values are so i ignore them.
|
||||
bool valid() const;
|
||||
/*
|
||||
* Returns whether there is a associated hotkey_command.
|
||||
* If the none of the hotkey_commands fits this hotkey_item then
|
||||
* @param get_hotkey_command will return the hotkey_command::null_command().
|
||||
* @return true if the hotkey is not bound to the null-command.
|
||||
*/
|
||||
bool active() const
|
||||
{
|
||||
return command_ != "null";
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates whether the hotkey bindings are valid.
|
||||
* @return true if they are valid, false otherwise.
|
||||
*/
|
||||
virtual bool valid() const = 0;
|
||||
|
||||
/**
|
||||
* Save the hotkey into the configuration object.
|
||||
* @param cfg The configuration object to save into.
|
||||
*/
|
||||
void save(config& cfg) const;
|
||||
|
||||
/// Return the actual key code.
|
||||
int get_keycode() const { return keycode_; }
|
||||
/// Returns unicode value of the pressed key.
|
||||
int get_character() const { return character_; }
|
||||
/**
|
||||
* Return "name" of hotkey. Example :"ctrl+alt+g"
|
||||
* @return The string representation of the keybindings
|
||||
*/
|
||||
const std::string get_name() const;
|
||||
|
||||
/** for buttons on devices */
|
||||
int get_button() const { return button_; }
|
||||
int get_joystick() const { return joystick_; }
|
||||
int get_hat() const { return hat_; }
|
||||
int get_mouse() const { return mouse_; }
|
||||
int get_value() const { return value_; }
|
||||
/**
|
||||
* Used to evaluate whether:
|
||||
* 1. The hotkey is valid in the current scope.
|
||||
* 2. The Keyboard modifiers and SDL_Event mathes this hotkey.
|
||||
*
|
||||
* @param event The @SDL_Event that has triggered and is being evaluated.
|
||||
*/
|
||||
bool matches(const SDL_Event &event) const;
|
||||
|
||||
/** modifiers */
|
||||
bool get_shift() const { return shift_; }
|
||||
bool get_ctrl() const { return ctrl_; }
|
||||
bool get_cmd() const { return cmd_; }
|
||||
bool get_alt() const { return alt_; }
|
||||
/**
|
||||
* Checks whether the hotkey bindings and scope are equal.
|
||||
* @param other the hokey bindings to compare against.
|
||||
* @return true if %other has same scope and bindings.
|
||||
*/
|
||||
virtual bool bindings_equal(hotkey_ptr other);
|
||||
|
||||
void set_jbutton(int button, int joystick, bool shift, bool ctrl, bool cmd, bool alt);
|
||||
void set_jhat(int joystick, int hat, int value, bool shift, bool ctrl, bool cmd, bool alt);
|
||||
void set_key(int character, int keycode, bool shift, bool ctrl, bool cmd, bool alt);
|
||||
void set_mbutton(int device, int button, bool shift, bool ctrl, bool cmd, bool alt);
|
||||
virtual ~hotkey_base()
|
||||
{}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* This is invoked by hotkey_base::get_name and must be implemented by subclasses.
|
||||
* Keyboard modifiers are handled in this class, other hotkeys in the respective classes
|
||||
*/
|
||||
virtual const std::string get_name_helper() const = 0;
|
||||
/**
|
||||
* This is invoked by hotkey_base::matches as a helper for the concrete classes.
|
||||
* Implementing classes should only check their parts of the hotkey.
|
||||
* @param event The SDL_Event being generated.
|
||||
* @returns true if they match, false otherwise.
|
||||
*/
|
||||
virtual bool matches_helper(const SDL_Event &event) const = 0;
|
||||
virtual void save_helper(config& cfg) const = 0;
|
||||
/**
|
||||
* This is invoked by hotkey_base::bindings_equal as a helper for the concrete classes.
|
||||
* Implementing classes should only check their parts of the hotkey.
|
||||
* @param other The other hotkey the check against. Not guaranteed to be the same subclass.
|
||||
* @returns true if they match, false otherwise.
|
||||
*/
|
||||
virtual bool bindings_equal_helper(hotkey_ptr other) const = 0;
|
||||
|
||||
// The unique command associated with this item.
|
||||
// Used to bind to a hotkey_command struct.
|
||||
/**
|
||||
* The command that should be executed, or "null".
|
||||
*/
|
||||
std::string command_;
|
||||
|
||||
// modifier keys
|
||||
bool shift_, ctrl_, cmd_, alt_;
|
||||
|
||||
// Actual unicode character
|
||||
int character_;
|
||||
|
||||
// These used for function keys (which don't have a unicode value) or
|
||||
// space (which doesn't have a distinct unicode value when shifted).
|
||||
int keycode_;
|
||||
|
||||
int joystick_, mouse_;
|
||||
int button_;
|
||||
int hat_, value_;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
bool is_default_;
|
||||
|
||||
/*
|
||||
* Keyboard modifiers. Treat as opaque, only do comparisons.
|
||||
*
|
||||
*/
|
||||
unsigned int mod_;
|
||||
};
|
||||
|
||||
/// Initiated weather there is at least one hotkey_item with the given command
|
||||
/**
|
||||
* This class is responsible for handling keys, not modifiers.
|
||||
*/
|
||||
class hotkey_keyboard: public hotkey_base
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initialise new instance of this class that has no key associated with is.
|
||||
*/
|
||||
hotkey_keyboard() : hotkey_base(), scancode_(SDL_SCANCODE_UNKNOWN)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Set the scancode associated with this class.
|
||||
* @param scancode The SDL_Scancode that this hotkey should be associated with
|
||||
*/
|
||||
void set_scancode(SDL_Scancode scancode)
|
||||
{
|
||||
scancode_ = scancode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this hotkey has been set to a sensible value.
|
||||
* @ return true if it is a known key
|
||||
*/
|
||||
virtual bool valid() const
|
||||
{
|
||||
return scancode_ != SDL_SCANCODE_UNKNOWN;
|
||||
}
|
||||
|
||||
protected:
|
||||
SDL_Scancode scancode_;
|
||||
|
||||
virtual void save_helper(config& cfg) const;
|
||||
virtual const std::string get_name_helper() const;
|
||||
virtual bool matches_helper(const SDL_Event &event) const;
|
||||
virtual bool bindings_equal_helper (hotkey_ptr other) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class is used to return non-valid results in order to save
|
||||
* other people from null checks.
|
||||
*/
|
||||
class hotkey_void: public hotkey_base
|
||||
{
|
||||
public:
|
||||
hotkey_void() : hotkey_base()
|
||||
{}
|
||||
virtual bool valid() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
protected:
|
||||
virtual void save_helper(config&) const
|
||||
{}
|
||||
virtual const std::string get_name_helper() const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
virtual bool matches_helper(const SDL_Event&) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool bindings_equal_helper(hotkey_ptr) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This class is responsible for handling mouse button presses.
|
||||
*/
|
||||
class hotkey_mouse: public hotkey_base
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initialise new instance of this class that has no button associated with is.
|
||||
*/
|
||||
hotkey_mouse() : hotkey_base(), button_ (0)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Returns true if the hotkey has a valid mouse button associated with it.
|
||||
* @return true if a mouse button is set, false otherwise.
|
||||
*/
|
||||
virtual bool valid() const
|
||||
{
|
||||
return button_ != 0;
|
||||
}
|
||||
|
||||
/* new functionality for this class */
|
||||
void set_button(int button)
|
||||
{
|
||||
button_ = button;
|
||||
}
|
||||
protected:
|
||||
int button_;
|
||||
|
||||
virtual void save_helper(config& cfg) const;
|
||||
virtual const std::string get_name_helper() const;
|
||||
virtual bool matches_helper(const SDL_Event &event) const;
|
||||
virtual bool bindings_equal_helper (hotkey_ptr other) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @todo not implemented
|
||||
*/
|
||||
class hotkey_joystick: public hotkey_base
|
||||
{
|
||||
protected:
|
||||
int button_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create and instantiate a hotkey from a config element.
|
||||
* @param cfg The config element to read for data.
|
||||
* @return The new instance of the hotkey item.
|
||||
*/
|
||||
hotkey_ptr load_from_config(const config& cfg);
|
||||
|
||||
/*
|
||||
* Scans the list of hotkeys to see if one has been bound to the command.
|
||||
* @param command The command that is searched for
|
||||
* @return true if there is a hotkey item that has the command bound.
|
||||
*/
|
||||
bool has_hotkey_item(const std::string& command);
|
||||
|
||||
void add_hotkey(const hotkey_item& item);
|
||||
/**
|
||||
* Add a hotkey to the list of hotkeys.
|
||||
* @param item The item to add.
|
||||
*/
|
||||
void add_hotkey(const hotkey_ptr item);
|
||||
|
||||
const hotkey_item& get_hotkey(int mouse, int joystick,
|
||||
int button, int hat, int value,
|
||||
bool shift, bool ctrl, bool cmd, bool alt);
|
||||
const hotkey_item& get_hotkey(int character, int keycode,
|
||||
bool shift, bool ctrl, bool cmd, bool alt);
|
||||
/**
|
||||
* Remove a hotkey from the list of hotkeys
|
||||
* @todo unusued?
|
||||
*/
|
||||
void del_hotkey(const hotkey_ptr item);
|
||||
|
||||
const hotkey_item& get_hotkey(const SDL_JoyButtonEvent& event);
|
||||
const hotkey_item& get_hotkey(const SDL_JoyHatEvent& event);
|
||||
const hotkey_item& get_hotkey(const SDL_KeyboardEvent& event);
|
||||
const hotkey_item& get_hotkey(const SDL_MouseButtonEvent& event);
|
||||
/**
|
||||
* Create a new hotkey item for a command from an SDL_Event.
|
||||
* @param id The command to bind to.
|
||||
* @param event The SDL_Event to base the creation on.
|
||||
*/
|
||||
hotkey_ptr create_hotkey(const std::string &id, SDL_Event &event);
|
||||
|
||||
/**
|
||||
* Iterate through the list of hotkeys and return a hotkey that matches
|
||||
* the SDL_Event and the current keyboard modifier state.
|
||||
* @param event The SDL_Event to use as a template.
|
||||
* @return The newly created hotkey item.
|
||||
*/
|
||||
const hotkey_ptr get_hotkey(const SDL_Event &event);
|
||||
|
||||
/**
|
||||
* Iterates through all hotkeys present in the config struct and creates and adds
|
||||
* them to the hotkey list.
|
||||
* @param cfg The config struct to load from.
|
||||
* @param set_as_default Indicates whether the config struct should be treated as the
|
||||
* default game settings.
|
||||
*/
|
||||
void load_hotkeys(const config& cfg, bool set_as_default = false);
|
||||
|
||||
/**
|
||||
* Reset all hotkeys to the defaults.
|
||||
*/
|
||||
void reset_default_hotkeys();
|
||||
|
||||
const std::vector<hotkey_item>& get_hotkeys();
|
||||
/**
|
||||
* Returns the list of hotkeys.
|
||||
*/
|
||||
const hotkey_list& get_hotkeys();
|
||||
|
||||
/**
|
||||
* Unset the command bindings for all hotkeys matching the command.
|
||||
* @command The binding to be unset
|
||||
*/
|
||||
void clear_hotkeys(const std::string& command);
|
||||
|
||||
/**
|
||||
* Unset the bindings for all hotkeys.
|
||||
*/
|
||||
void clear_hotkeys();
|
||||
|
||||
/// returns all hotkey_item s that point to this, command in the form "A,Strg+M,F4"
|
||||
/// used in the preferences menu
|
||||
/**
|
||||
* Returns a comma-separated string of hotkey names. A hotkey name is in the form of
|
||||
* "ctrl+l" or "n" or "mouse 1". The comman separated string is of the form "ctrl+l,n,mouse 1".
|
||||
* @return The comma separated string of hotkey names.
|
||||
*/
|
||||
std::string get_names(std::string id);
|
||||
|
||||
/**
|
||||
* Save the non-default hotkeys to the config.
|
||||
* @param cfg The config to save to.
|
||||
*/
|
||||
void save_hotkeys(config& cfg);
|
||||
|
||||
/// Append a single hotkey item to @a cfg.
|
||||
//void save_hotkey(config& cfg, const hotkey_item & item);
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -590,8 +590,7 @@ void hotkey_preferences_dialog::show_binding_dialog(
|
|||
disp_.update_display();
|
||||
SDL_Event event;
|
||||
event.type = 0;
|
||||
int character = -1, keycode = -1, mod = -1;
|
||||
int mouse = -1, joystick = -1, button = -1, hat = -1, value = -1;
|
||||
int keycode = -1, mod = -1;
|
||||
const int any_mod = KMOD_CTRL | KMOD_META | KMOD_ALT;
|
||||
|
||||
while ( event.type != SDL_KEYDOWN && event.type != SDL_JOYBUTTONDOWN
|
||||
|
@ -605,28 +604,11 @@ void hotkey_preferences_dialog::show_binding_dialog(
|
|||
|
||||
case SDL_KEYDOWN:
|
||||
keycode = event.key.keysym.sym;
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
character = event.key.keysym.scancode,
|
||||
#else
|
||||
character = event.key.keysym.unicode;
|
||||
#endif
|
||||
mod = event.key.keysym.mod;
|
||||
break;
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
joystick = event.jbutton.which;
|
||||
button = event.jbutton.button;
|
||||
break;
|
||||
case SDL_JOYHATMOTION:
|
||||
joystick = event.jhat.which;
|
||||
hat = event.jhat.hat;
|
||||
value = event.jhat.value;
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
mouse = event.button.which;
|
||||
button = event.button.button;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
SDL_PollEvent(&event);
|
||||
disp_.flip();
|
||||
disp_.delay(10);
|
||||
|
@ -637,44 +619,16 @@ void hotkey_preferences_dialog::show_binding_dialog(
|
|||
restorer.restore();
|
||||
disp_.update_display();
|
||||
|
||||
// only if not canceled.
|
||||
// only if not cancelled.
|
||||
if (!(keycode == SDLK_ESCAPE && (mod & any_mod) == 0)) {
|
||||
|
||||
hotkey::hotkey_item newhk(id);
|
||||
const hotkey::hotkey_item* oldhk = NULL;
|
||||
hotkey::hotkey_ptr newhk;
|
||||
hotkey::hotkey_ptr oldhk;
|
||||
|
||||
CKey keystate;
|
||||
bool shift = keystate[SDLK_RSHIFT] || keystate[SDLK_LSHIFT];
|
||||
bool ctrl = keystate[SDLK_RCTRL] || keystate[SDLK_LCTRL];
|
||||
bool cmd = keystate[SDLK_RMETA] || keystate[SDLK_LMETA];
|
||||
bool alt = keystate[SDLK_RALT] || keystate[SDLK_LALT];
|
||||
|
||||
switch (event.type) {
|
||||
|
||||
case SDL_JOYHATMOTION:
|
||||
oldhk = &hotkey::get_hotkey(mouse, joystick, button, hat, value,
|
||||
shift, ctrl, cmd, alt);
|
||||
newhk.set_jhat(joystick, hat, value, shift, ctrl, cmd, alt);
|
||||
break;
|
||||
case SDL_JOYBUTTONUP:
|
||||
oldhk = &hotkey::get_hotkey(-1, joystick, button, -1, -1,
|
||||
shift, ctrl, cmd, alt);
|
||||
newhk.set_jbutton(joystick, button, shift, ctrl, cmd, alt);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
oldhk = &hotkey::get_hotkey(mouse, -1, button, -1, -1,
|
||||
shift, ctrl, cmd, alt);
|
||||
newhk.set_mbutton(mouse, button, shift, ctrl, cmd, alt);
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
oldhk =
|
||||
&hotkey::get_hotkey( character, keycode,
|
||||
(mod & KMOD_SHIFT) != 0, (mod & KMOD_CTRL) != 0,
|
||||
(mod & KMOD_LMETA) != 0, (mod & KMOD_ALT) != 0 );
|
||||
newhk.set_key(character, keycode, (mod & KMOD_SHIFT) != 0,
|
||||
(mod & KMOD_CTRL) != 0, (mod & KMOD_LMETA) != 0,
|
||||
(mod & KMOD_ALT) != 0);
|
||||
oldhk = hotkey::get_hotkey(event);
|
||||
newhk = hotkey::create_hotkey(id, event);
|
||||
|
||||
#if 0
|
||||
//TODO
|
||||
// if ( (hotkey::get_id(newhk.get_command()) == hotkey::HOTKEY_SCREENSHOT
|
||||
// || hotkey::get_id(newhk.get_command()) == hotkey::HOTKEY_MAP_SCREENSHOT)
|
||||
|
@ -685,6 +639,7 @@ Control, Alt or Meta modifiers to avoid problems.")); */
|
|||
// }
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (oldhk && oldhk->active()) {
|
||||
if (oldhk->get_command() != id) {
|
||||
|
@ -692,7 +647,7 @@ Control, Alt or Meta modifiers to avoid problems.")); */
|
|||
utils::string_map symbols;
|
||||
symbols["hotkey_sequence"] = oldhk->get_name();
|
||||
symbols["old_hotkey_action"] = hotkey::get_description(oldhk->get_command());
|
||||
symbols["new_hotkey_action"] = hotkey::get_description(newhk.get_command());
|
||||
symbols["new_hotkey_action"] = hotkey::get_description(newhk->get_command());
|
||||
|
||||
std::string text =
|
||||
vgettext("\"$hotkey_sequence|\" is in use by \
|
||||
|
|
641
src/sdl/keyboard.cpp
Normal file
641
src/sdl/keyboard.cpp
Normal file
|
@ -0,0 +1,641 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL.h"
|
||||
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
#include "sdl/keyboard.hpp"
|
||||
|
||||
#define SDLK_SCANCODE_MASK (1<<30)
|
||||
#define SDL_SCANCODE_TO_KEYCODE(X) (X | SDLK_SCANCODE_MASK)
|
||||
|
||||
|
||||
static const int SDL_default_keymap[SDL_NUM_SCANCODES] = {
|
||||
0, 0, 0, 0,
|
||||
'a',
|
||||
'b',
|
||||
'c',
|
||||
'd',
|
||||
'e',
|
||||
'f',
|
||||
'g',
|
||||
'h',
|
||||
'i',
|
||||
'j',
|
||||
'k',
|
||||
'l',
|
||||
'm',
|
||||
'n',
|
||||
'o',
|
||||
'p',
|
||||
'q',
|
||||
'r',
|
||||
's',
|
||||
't',
|
||||
'u',
|
||||
'v',
|
||||
'w',
|
||||
'x',
|
||||
'y',
|
||||
'z',
|
||||
'1',
|
||||
'2',
|
||||
'3',
|
||||
'4',
|
||||
'5',
|
||||
'6',
|
||||
'7',
|
||||
'8',
|
||||
'9',
|
||||
'0',
|
||||
SDLK_RETURN,
|
||||
SDLK_ESCAPE,
|
||||
SDLK_BACKSPACE,
|
||||
SDLK_TAB,
|
||||
SDLK_SPACE,
|
||||
'-',
|
||||
'=',
|
||||
'[',
|
||||
']',
|
||||
'\\',
|
||||
'#',
|
||||
';',
|
||||
'\'',
|
||||
'`',
|
||||
',',
|
||||
'.',
|
||||
'/',
|
||||
SDLK_CAPSLOCK,
|
||||
SDLK_F1,
|
||||
SDLK_F2,
|
||||
SDLK_F3,
|
||||
SDLK_F4,
|
||||
SDLK_F5,
|
||||
SDLK_F6,
|
||||
SDLK_F7,
|
||||
SDLK_F8,
|
||||
SDLK_F9,
|
||||
SDLK_F10,
|
||||
SDLK_F11,
|
||||
SDLK_F12,
|
||||
SDLK_PRINT,
|
||||
SDLK_SCROLLOCK,
|
||||
SDLK_PAUSE,
|
||||
SDLK_INSERT,
|
||||
SDLK_HOME,
|
||||
SDLK_PAGEUP,
|
||||
SDLK_DELETE,
|
||||
SDLK_END,
|
||||
SDLK_PAGEDOWN,
|
||||
SDLK_RIGHT,
|
||||
SDLK_LEFT,
|
||||
SDLK_DOWN,
|
||||
SDLK_UP,
|
||||
0,
|
||||
SDLK_KP_DIVIDE,
|
||||
SDLK_KP_MULTIPLY,
|
||||
SDLK_KP_MINUS,
|
||||
SDLK_KP_PLUS,
|
||||
SDLK_KP_ENTER,
|
||||
SDLK_KP1,
|
||||
SDLK_KP2,
|
||||
SDLK_KP3,
|
||||
SDLK_KP4,
|
||||
SDLK_KP5,
|
||||
SDLK_KP6,
|
||||
SDLK_KP7,
|
||||
SDLK_KP8,
|
||||
SDLK_KP9,
|
||||
SDLK_KP0,
|
||||
SDLK_KP_PERIOD,
|
||||
0,
|
||||
0,
|
||||
SDLK_POWER,
|
||||
SDLK_KP_EQUALS,
|
||||
SDLK_F13,
|
||||
SDLK_F14,
|
||||
SDLK_F15,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
SDLK_HELP,
|
||||
SDLK_MENU,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, 0, 0,
|
||||
0,
|
||||
0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
SDLK_SYSREQ,
|
||||
0,
|
||||
SDLK_CLEAR,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, 0,
|
||||
SDLK_LCTRL,
|
||||
SDLK_LSHIFT,
|
||||
SDLK_LALT,
|
||||
SDLK_LMETA,
|
||||
SDLK_RCTRL,
|
||||
SDLK_RSHIFT,
|
||||
SDLK_RALT,
|
||||
SDLK_RMETA,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
SDLK_MODE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
static const char *SDL_scancode_names[SDL_NUM_SCANCODES] = {
|
||||
NULL, NULL, NULL, NULL,
|
||||
"A",
|
||||
"B",
|
||||
"C",
|
||||
"D",
|
||||
"E",
|
||||
"F",
|
||||
"G",
|
||||
"H",
|
||||
"I",
|
||||
"J",
|
||||
"K",
|
||||
"L",
|
||||
"M",
|
||||
"N",
|
||||
"O",
|
||||
"P",
|
||||
"Q",
|
||||
"R",
|
||||
"S",
|
||||
"T",
|
||||
"U",
|
||||
"V",
|
||||
"W",
|
||||
"X",
|
||||
"Y",
|
||||
"Z",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"0",
|
||||
"Return",
|
||||
"Escape",
|
||||
"Backspace",
|
||||
"Tab",
|
||||
"Space",
|
||||
"-",
|
||||
"=",
|
||||
"[",
|
||||
"]",
|
||||
"\\",
|
||||
"#",
|
||||
";",
|
||||
"'",
|
||||
"`",
|
||||
",",
|
||||
".",
|
||||
"/",
|
||||
"CapsLock",
|
||||
"F1",
|
||||
"F2",
|
||||
"F3",
|
||||
"F4",
|
||||
"F5",
|
||||
"F6",
|
||||
"F7",
|
||||
"F8",
|
||||
"F9",
|
||||
"F10",
|
||||
"F11",
|
||||
"F12",
|
||||
"PrintScreen",
|
||||
"ScrollLock",
|
||||
"Pause",
|
||||
"Insert",
|
||||
"Home",
|
||||
"PageUp",
|
||||
"Delete",
|
||||
"End",
|
||||
"PageDown",
|
||||
"Right",
|
||||
"Left",
|
||||
"Down",
|
||||
"Up",
|
||||
"Numlock",
|
||||
"Keypad /",
|
||||
"Keypad *",
|
||||
"Keypad -",
|
||||
"Keypad +",
|
||||
"Keypad Enter",
|
||||
"Keypad 1",
|
||||
"Keypad 2",
|
||||
"Keypad 3",
|
||||
"Keypad 4",
|
||||
"Keypad 5",
|
||||
"Keypad 6",
|
||||
"Keypad 7",
|
||||
"Keypad 8",
|
||||
"Keypad 9",
|
||||
"Keypad 0",
|
||||
"Keypad .",
|
||||
NULL,
|
||||
"Application",
|
||||
"Power",
|
||||
"Keypad =",
|
||||
"F13",
|
||||
"F14",
|
||||
"F15",
|
||||
"F16",
|
||||
"F17",
|
||||
"F18",
|
||||
"F19",
|
||||
"F20",
|
||||
"F21",
|
||||
"F22",
|
||||
"F23",
|
||||
"F24",
|
||||
"Execute",
|
||||
"Help",
|
||||
"Menu",
|
||||
"Select",
|
||||
"Stop",
|
||||
"Again",
|
||||
"Undo",
|
||||
"Cut",
|
||||
"Copy",
|
||||
"Paste",
|
||||
"Find",
|
||||
"Mute",
|
||||
"VolumeUp",
|
||||
"VolumeDown",
|
||||
NULL, NULL, NULL,
|
||||
"Keypad ,",
|
||||
"Keypad = (AS400)",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
"AltErase",
|
||||
"SysReq",
|
||||
"Cancel",
|
||||
"Clear",
|
||||
"Prior",
|
||||
"Return",
|
||||
"Separator",
|
||||
"Out",
|
||||
"Oper",
|
||||
"Clear / Again",
|
||||
"CrSel",
|
||||
"ExSel",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
"Keypad 00",
|
||||
"Keypad 000",
|
||||
"ThousandsSeparator",
|
||||
"DecimalSeparator",
|
||||
"CurrencyUnit",
|
||||
"CurrencySubUnit",
|
||||
"Keypad (",
|
||||
"Keypad )",
|
||||
"Keypad {",
|
||||
"Keypad }",
|
||||
"Keypad Tab",
|
||||
"Keypad Backspace",
|
||||
"Keypad A",
|
||||
"Keypad B",
|
||||
"Keypad C",
|
||||
"Keypad D",
|
||||
"Keypad E",
|
||||
"Keypad F",
|
||||
"Keypad XOR",
|
||||
"Keypad ^",
|
||||
"Keypad %",
|
||||
"Keypad <",
|
||||
"Keypad >",
|
||||
"Keypad &",
|
||||
"Keypad &&",
|
||||
"Keypad |",
|
||||
"Keypad ||",
|
||||
"Keypad :",
|
||||
"Keypad #",
|
||||
"Keypad Space",
|
||||
"Keypad @",
|
||||
"Keypad !",
|
||||
"Keypad MemStore",
|
||||
"Keypad MemRecall",
|
||||
"Keypad MemClear",
|
||||
"Keypad MemAdd",
|
||||
"Keypad MemSubtract",
|
||||
"Keypad MemMultiply",
|
||||
"Keypad MemDivide",
|
||||
"Keypad +/-",
|
||||
"Keypad Clear",
|
||||
"Keypad ClearEntry",
|
||||
"Keypad Binary",
|
||||
"Keypad Octal",
|
||||
"Keypad Decimal",
|
||||
"Keypad Hexadecimal",
|
||||
NULL, NULL,
|
||||
"Left Ctrl",
|
||||
"Left Shift",
|
||||
"Left Alt",
|
||||
"Left GUI",
|
||||
"Right Ctrl",
|
||||
"Right Shift",
|
||||
"Right Alt",
|
||||
"Right GUI",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL,
|
||||
"ModeSwitch",
|
||||
"AudioNext",
|
||||
"AudioPrev",
|
||||
"AudioStop",
|
||||
"AudioPlay",
|
||||
"AudioMute",
|
||||
"MediaSelect",
|
||||
"WWW",
|
||||
"Mail",
|
||||
"Calculator",
|
||||
"Computer",
|
||||
"AC Search",
|
||||
"AC Home",
|
||||
"AC Back",
|
||||
"AC Forward",
|
||||
"AC Stop",
|
||||
"AC Refresh",
|
||||
"AC Bookmarks",
|
||||
"BrightnessDown",
|
||||
"BrightnessUp",
|
||||
"DisplaySwitch",
|
||||
"KBDIllumToggle",
|
||||
"KBDIllumDown",
|
||||
"KBDIllumUp",
|
||||
"Eject",
|
||||
"Sleep",
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get the key code corresponding to the given scancode according
|
||||
* to the current keyboard layout.
|
||||
*
|
||||
* See ::SDL_Keycode for details.
|
||||
*
|
||||
* \sa SDL_GetKeyName()
|
||||
*/
|
||||
SDLKey SDL_GetKeyFromScancode(SDL_Scancode scancode);
|
||||
|
||||
/**
|
||||
* \brief Get the scancode corresponding to the given key code according to the
|
||||
* current keyboard layout.
|
||||
*
|
||||
* See ::SDL_Scancode for details.
|
||||
*
|
||||
* \sa SDL_GetScancodeName()
|
||||
*/
|
||||
SDL_Scancode SDL_GetScancodeFromKey(SDLKey key);
|
||||
|
||||
/**
|
||||
* \brief Get a human-readable name for a scancode.
|
||||
*
|
||||
* \return A pointer to the name for the scancode.
|
||||
* If the scancode doesn't have a name, this function returns
|
||||
* an empty string ("").
|
||||
*
|
||||
* \sa SDL_Scancode
|
||||
*/
|
||||
const char * SDL_GetScancodeName(SDL_Scancode scancode);
|
||||
|
||||
/**
|
||||
* \brief Get a scancode from a human-readable name
|
||||
*
|
||||
* \return scancode, or SDL_SCANCODE_UNKNOWN if the name wasn't recognized
|
||||
*
|
||||
* \sa SDL_Scancode
|
||||
*/
|
||||
SDL_Scancode SDL_GetScancodeFromName(const char *name);
|
||||
|
||||
SDLKey
|
||||
SDL_GetKeyFromScancode(SDL_Scancode scancode)
|
||||
{
|
||||
if (scancode < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) {
|
||||
return SDLK_UNKNOWN;
|
||||
}
|
||||
|
||||
return static_cast<SDLKey>(SDL_default_keymap[scancode]);
|
||||
}
|
||||
|
||||
SDL_Scancode
|
||||
SDL_GetScancodeFromKey(SDLKey key)
|
||||
{
|
||||
for (int scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES;
|
||||
++scancode) {
|
||||
if (SDL_default_keymap[scancode] == key) {
|
||||
return static_cast<SDL_Scancode>(scancode);
|
||||
}
|
||||
}
|
||||
return SDL_SCANCODE_UNKNOWN;
|
||||
}
|
||||
|
||||
const char *
|
||||
SDL_GetScancodeName(SDL_Scancode scancode)
|
||||
{
|
||||
const char *name;
|
||||
if (scancode < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) {
|
||||
return "";
|
||||
}
|
||||
|
||||
name = SDL_scancode_names[scancode];
|
||||
if (name)
|
||||
return name;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
SDL_Scancode SDL_GetScancodeFromName(const char *name)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!name || !*name) {
|
||||
return SDL_SCANCODE_UNKNOWN;
|
||||
}
|
||||
|
||||
for (i = 0; i < SDL_arraysize(SDL_scancode_names); ++i) {
|
||||
if (!SDL_scancode_names[i]) {
|
||||
continue;
|
||||
}
|
||||
if (SDL_strcasecmp(name, SDL_scancode_names[i]) == 0) {
|
||||
return static_cast<SDL_Scancode>(i);
|
||||
}
|
||||
}
|
||||
|
||||
return SDL_SCANCODE_UNKNOWN;
|
||||
}
|
||||
|
||||
SDLKey
|
||||
SDL_GetKeyFromName(const char *name)
|
||||
{
|
||||
int key;
|
||||
|
||||
/* Check input */
|
||||
if (name == NULL) return SDLK_UNKNOWN;
|
||||
|
||||
/* If it's a single UTF-8 character, then that's the keycode itself */
|
||||
key = *reinterpret_cast<const unsigned char *>(name);
|
||||
if (key >= 0xF0) {
|
||||
if (SDL_strlen(name) == 4) {
|
||||
int i = 0;
|
||||
key = static_cast<Uint16>((name[i]&0x07) << 18);
|
||||
key |= static_cast<Uint16>((name[++i]&0x3F) << 12);
|
||||
key |= static_cast<Uint16>((name[++i]&0x3F) << 6);
|
||||
key |= static_cast<Uint16>((name[++i]&0x3F));
|
||||
return static_cast<SDLKey>(key);
|
||||
}
|
||||
return SDLK_UNKNOWN;
|
||||
} else if (key >= 0xE0) {
|
||||
if (SDL_strlen(name) == 3) {
|
||||
int i = 0;
|
||||
key = static_cast<Uint16>((name[i]&0x0F) << 12);
|
||||
key |= static_cast<Uint16>((name[++i]&0x3F) << 6);
|
||||
key |= static_cast<Uint16>((name[++i]&0x3F));
|
||||
return static_cast<SDLKey>(key);
|
||||
}
|
||||
return SDLK_UNKNOWN;
|
||||
} else if (key >= 0xC0) {
|
||||
if (SDL_strlen(name) == 2) {
|
||||
int i = 0;
|
||||
key = static_cast<Uint16>((name[i]&0x1F) << 6);
|
||||
key |= static_cast<Uint16>((name[++i]&0x3F));
|
||||
return static_cast<SDLKey>(key);
|
||||
}
|
||||
return SDLK_UNKNOWN;
|
||||
} else {
|
||||
if (SDL_strlen(name) == 1) {
|
||||
if (key >= 'A' && key <= 'Z') {
|
||||
key += 32;
|
||||
}
|
||||
return static_cast<SDLKey>(key);
|
||||
}
|
||||
|
||||
/* Get the scancode for this name, and the associated keycode */
|
||||
return static_cast<SDLKey>(SDL_default_keymap[SDL_GetScancodeFromName(name)]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
422
src/sdl/keyboard.hpp
Normal file
422
src/sdl/keyboard.hpp
Normal file
|
@ -0,0 +1,422 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_KEYBOARD_HPP_INCLUDED
|
||||
#define SDL_KEYBOARD_HPP_INCLUDED
|
||||
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/**
|
||||
* \brief The SDL keyboard scancode representation.
|
||||
*
|
||||
* Values of this type are used to represent keyboard keys, among other places
|
||||
* in the \link SDL_Keysym::scancode key.keysym.scancode \endlink field of the
|
||||
* SDL_Event structure.
|
||||
*
|
||||
* The values in this enumeration are based on the USB usage page standard:
|
||||
* http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
SDL_SCANCODE_UNKNOWN = 0,
|
||||
|
||||
/**
|
||||
* \name Usage page 0x07
|
||||
*
|
||||
* These values are from usage page 0x07 (USB keyboard page).
|
||||
*/
|
||||
/* @{ */
|
||||
|
||||
SDL_SCANCODE_A = 4,
|
||||
SDL_SCANCODE_B = 5,
|
||||
SDL_SCANCODE_C = 6,
|
||||
SDL_SCANCODE_D = 7,
|
||||
SDL_SCANCODE_E = 8,
|
||||
SDL_SCANCODE_F = 9,
|
||||
SDL_SCANCODE_G = 10,
|
||||
SDL_SCANCODE_H = 11,
|
||||
SDL_SCANCODE_I = 12,
|
||||
SDL_SCANCODE_J = 13,
|
||||
SDL_SCANCODE_K = 14,
|
||||
SDL_SCANCODE_L = 15,
|
||||
SDL_SCANCODE_M = 16,
|
||||
SDL_SCANCODE_N = 17,
|
||||
SDL_SCANCODE_O = 18,
|
||||
SDL_SCANCODE_P = 19,
|
||||
SDL_SCANCODE_Q = 20,
|
||||
SDL_SCANCODE_R = 21,
|
||||
SDL_SCANCODE_S = 22,
|
||||
SDL_SCANCODE_T = 23,
|
||||
SDL_SCANCODE_U = 24,
|
||||
SDL_SCANCODE_V = 25,
|
||||
SDL_SCANCODE_W = 26,
|
||||
SDL_SCANCODE_X = 27,
|
||||
SDL_SCANCODE_Y = 28,
|
||||
SDL_SCANCODE_Z = 29,
|
||||
|
||||
SDL_SCANCODE_1 = 30,
|
||||
SDL_SCANCODE_2 = 31,
|
||||
SDL_SCANCODE_3 = 32,
|
||||
SDL_SCANCODE_4 = 33,
|
||||
SDL_SCANCODE_5 = 34,
|
||||
SDL_SCANCODE_6 = 35,
|
||||
SDL_SCANCODE_7 = 36,
|
||||
SDL_SCANCODE_8 = 37,
|
||||
SDL_SCANCODE_9 = 38,
|
||||
SDL_SCANCODE_0 = 39,
|
||||
|
||||
SDL_SCANCODE_RETURN = 40,
|
||||
SDL_SCANCODE_ESCAPE = 41,
|
||||
SDL_SCANCODE_BACKSPACE = 42,
|
||||
SDL_SCANCODE_TAB = 43,
|
||||
SDL_SCANCODE_SPACE = 44,
|
||||
|
||||
SDL_SCANCODE_MINUS = 45,
|
||||
SDL_SCANCODE_EQUALS = 46,
|
||||
SDL_SCANCODE_LEFTBRACKET = 47,
|
||||
SDL_SCANCODE_RIGHTBRACKET = 48,
|
||||
SDL_SCANCODE_BACKSLASH = 49, /**< Located at the lower left of the return
|
||||
* key on ISO keyboards and at the right end
|
||||
* of the QWERTY row on ANSI keyboards.
|
||||
* Produces REVERSE SOLIDUS (backslash) and
|
||||
* VERTICAL LINE in a US layout, REVERSE
|
||||
* SOLIDUS and VERTICAL LINE in a UK Mac
|
||||
* layout, NUMBER SIGN and TILDE in a UK
|
||||
* Windows layout, DOLLAR SIGN and POUND SIGN
|
||||
* in a Swiss German layout, NUMBER SIGN and
|
||||
* APOSTROPHE in a German layout, GRAVE
|
||||
* ACCENT and POUND SIGN in a French Mac
|
||||
* layout, and ASTERISK and MICRO SIGN in a
|
||||
* French Windows layout.
|
||||
*/
|
||||
SDL_SCANCODE_NONUSHASH = 50, /**< ISO USB keyboards actually use this code
|
||||
* instead of 49 for the same key, but all
|
||||
* OSes I've seen treat the two codes
|
||||
* identically. So, as an implementor, unless
|
||||
* your keyboard generates both of those
|
||||
* codes and your OS treats them differently,
|
||||
* you should generate SDL_SCANCODE_BACKSLASH
|
||||
* instead of this code. As a user, you
|
||||
* should not rely on this code because SDL
|
||||
* will never generate it with most (all?)
|
||||
* keyboards.
|
||||
*/
|
||||
SDL_SCANCODE_SEMICOLON = 51,
|
||||
SDL_SCANCODE_APOSTROPHE = 52,
|
||||
SDL_SCANCODE_GRAVE = 53, /**< Located in the top left corner (on both ANSI
|
||||
* and ISO keyboards). Produces GRAVE ACCENT and
|
||||
* TILDE in a US Windows layout and in US and UK
|
||||
* Mac layouts on ANSI keyboards, GRAVE ACCENT
|
||||
* and NOT SIGN in a UK Windows layout, SECTION
|
||||
* SIGN and PLUS-MINUS SIGN in US and UK Mac
|
||||
* layouts on ISO keyboards, SECTION SIGN and
|
||||
* DEGREE SIGN in a Swiss German layout (Mac:
|
||||
* only on ISO keyboards), CIRCUMFLEX ACCENT and
|
||||
* DEGREE SIGN in a German layout (Mac: only on
|
||||
* ISO keyboards), SUPERSCRIPT TWO and TILDE in a
|
||||
* French Windows layout, COMMERCIAL AT and
|
||||
* NUMBER SIGN in a French Mac layout on ISO
|
||||
* keyboards, and LESS-THAN SIGN and GREATER-THAN
|
||||
* SIGN in a Swiss German, German, or French Mac
|
||||
* layout on ANSI keyboards.
|
||||
*/
|
||||
SDL_SCANCODE_COMMA = 54,
|
||||
SDL_SCANCODE_PERIOD = 55,
|
||||
SDL_SCANCODE_SLASH = 56,
|
||||
|
||||
SDL_SCANCODE_CAPSLOCK = 57,
|
||||
|
||||
SDL_SCANCODE_F1 = 58,
|
||||
SDL_SCANCODE_F2 = 59,
|
||||
SDL_SCANCODE_F3 = 60,
|
||||
SDL_SCANCODE_F4 = 61,
|
||||
SDL_SCANCODE_F5 = 62,
|
||||
SDL_SCANCODE_F6 = 63,
|
||||
SDL_SCANCODE_F7 = 64,
|
||||
SDL_SCANCODE_F8 = 65,
|
||||
SDL_SCANCODE_F9 = 66,
|
||||
SDL_SCANCODE_F10 = 67,
|
||||
SDL_SCANCODE_F11 = 68,
|
||||
SDL_SCANCODE_F12 = 69,
|
||||
|
||||
SDL_SCANCODE_PRINTSCREEN = 70,
|
||||
SDL_SCANCODE_SCROLLLOCK = 71,
|
||||
SDL_SCANCODE_PAUSE = 72,
|
||||
SDL_SCANCODE_INSERT = 73, /**< insert on PC, help on some Mac keyboards (but
|
||||
does send code 73, not 117) */
|
||||
SDL_SCANCODE_HOME = 74,
|
||||
SDL_SCANCODE_PAGEUP = 75,
|
||||
SDL_SCANCODE_DELETE = 76,
|
||||
SDL_SCANCODE_END = 77,
|
||||
SDL_SCANCODE_PAGEDOWN = 78,
|
||||
SDL_SCANCODE_RIGHT = 79,
|
||||
SDL_SCANCODE_LEFT = 80,
|
||||
SDL_SCANCODE_DOWN = 81,
|
||||
SDL_SCANCODE_UP = 82,
|
||||
|
||||
SDL_SCANCODE_NUMLOCKCLEAR = 83, /**< num lock on PC, clear on Mac keyboards
|
||||
*/
|
||||
SDL_SCANCODE_KP_DIVIDE = 84,
|
||||
SDL_SCANCODE_KP_MULTIPLY = 85,
|
||||
SDL_SCANCODE_KP_MINUS = 86,
|
||||
SDL_SCANCODE_KP_PLUS = 87,
|
||||
SDL_SCANCODE_KP_ENTER = 88,
|
||||
SDL_SCANCODE_KP_1 = 89,
|
||||
SDL_SCANCODE_KP_2 = 90,
|
||||
SDL_SCANCODE_KP_3 = 91,
|
||||
SDL_SCANCODE_KP_4 = 92,
|
||||
SDL_SCANCODE_KP_5 = 93,
|
||||
SDL_SCANCODE_KP_6 = 94,
|
||||
SDL_SCANCODE_KP_7 = 95,
|
||||
SDL_SCANCODE_KP_8 = 96,
|
||||
SDL_SCANCODE_KP_9 = 97,
|
||||
SDL_SCANCODE_KP_0 = 98,
|
||||
SDL_SCANCODE_KP_PERIOD = 99,
|
||||
|
||||
SDL_SCANCODE_NONUSBACKSLASH = 100, /**< This is the additional key that ISO
|
||||
* keyboards have over ANSI ones,
|
||||
* located between left shift and Y.
|
||||
* Produces GRAVE ACCENT and TILDE in a
|
||||
* US or UK Mac layout, REVERSE SOLIDUS
|
||||
* (backslash) and VERTICAL LINE in a
|
||||
* US or UK Windows layout, and
|
||||
* LESS-THAN SIGN and GREATER-THAN SIGN
|
||||
* in a Swiss German, German, or French
|
||||
* layout. */
|
||||
SDL_SCANCODE_APPLICATION = 101, /**< windows contextual menu, compose */
|
||||
SDL_SCANCODE_POWER = 102, /**< The USB document says this is a status flag,
|
||||
* not a physical key - but some Mac keyboards
|
||||
* do have a power key. */
|
||||
SDL_SCANCODE_KP_EQUALS = 103,
|
||||
SDL_SCANCODE_F13 = 104,
|
||||
SDL_SCANCODE_F14 = 105,
|
||||
SDL_SCANCODE_F15 = 106,
|
||||
SDL_SCANCODE_F16 = 107,
|
||||
SDL_SCANCODE_F17 = 108,
|
||||
SDL_SCANCODE_F18 = 109,
|
||||
SDL_SCANCODE_F19 = 110,
|
||||
SDL_SCANCODE_F20 = 111,
|
||||
SDL_SCANCODE_F21 = 112,
|
||||
SDL_SCANCODE_F22 = 113,
|
||||
SDL_SCANCODE_F23 = 114,
|
||||
SDL_SCANCODE_F24 = 115,
|
||||
SDL_SCANCODE_EXECUTE = 116,
|
||||
SDL_SCANCODE_HELP = 117,
|
||||
SDL_SCANCODE_MENU = 118,
|
||||
SDL_SCANCODE_SELECT = 119,
|
||||
SDL_SCANCODE_STOP = 120,
|
||||
SDL_SCANCODE_AGAIN = 121, /**< redo */
|
||||
SDL_SCANCODE_UNDO = 122,
|
||||
SDL_SCANCODE_CUT = 123,
|
||||
SDL_SCANCODE_COPY = 124,
|
||||
SDL_SCANCODE_PASTE = 125,
|
||||
SDL_SCANCODE_FIND = 126,
|
||||
SDL_SCANCODE_MUTE = 127,
|
||||
SDL_SCANCODE_VOLUMEUP = 128,
|
||||
SDL_SCANCODE_VOLUMEDOWN = 129,
|
||||
/* not sure whether there's a reason to enable these */
|
||||
/* SDL_SCANCODE_LOCKINGCAPSLOCK = 130, */
|
||||
/* SDL_SCANCODE_LOCKINGNUMLOCK = 131, */
|
||||
/* SDL_SCANCODE_LOCKINGSCROLLLOCK = 132, */
|
||||
SDL_SCANCODE_KP_COMMA = 133,
|
||||
SDL_SCANCODE_KP_EQUALSAS400 = 134,
|
||||
|
||||
SDL_SCANCODE_INTERNATIONAL1 = 135, /**< used on Asian keyboards, see
|
||||
footnotes in USB doc */
|
||||
SDL_SCANCODE_INTERNATIONAL2 = 136,
|
||||
SDL_SCANCODE_INTERNATIONAL3 = 137, /**< Yen */
|
||||
SDL_SCANCODE_INTERNATIONAL4 = 138,
|
||||
SDL_SCANCODE_INTERNATIONAL5 = 139,
|
||||
SDL_SCANCODE_INTERNATIONAL6 = 140,
|
||||
SDL_SCANCODE_INTERNATIONAL7 = 141,
|
||||
SDL_SCANCODE_INTERNATIONAL8 = 142,
|
||||
SDL_SCANCODE_INTERNATIONAL9 = 143,
|
||||
SDL_SCANCODE_LANG1 = 144, /**< Hangul/English toggle */
|
||||
SDL_SCANCODE_LANG2 = 145, /**< Hanja conversion */
|
||||
SDL_SCANCODE_LANG3 = 146, /**< Katakana */
|
||||
SDL_SCANCODE_LANG4 = 147, /**< Hiragana */
|
||||
SDL_SCANCODE_LANG5 = 148, /**< Zenkaku/Hankaku */
|
||||
SDL_SCANCODE_LANG6 = 149, /**< reserved */
|
||||
SDL_SCANCODE_LANG7 = 150, /**< reserved */
|
||||
SDL_SCANCODE_LANG8 = 151, /**< reserved */
|
||||
SDL_SCANCODE_LANG9 = 152, /**< reserved */
|
||||
|
||||
SDL_SCANCODE_ALTERASE = 153, /**< Erase-Eaze */
|
||||
SDL_SCANCODE_SYSREQ = 154,
|
||||
SDL_SCANCODE_CANCEL = 155,
|
||||
SDL_SCANCODE_CLEAR = 156,
|
||||
SDL_SCANCODE_PRIOR = 157,
|
||||
SDL_SCANCODE_RETURN2 = 158,
|
||||
SDL_SCANCODE_SEPARATOR = 159,
|
||||
SDL_SCANCODE_OUT = 160,
|
||||
SDL_SCANCODE_OPER = 161,
|
||||
SDL_SCANCODE_CLEARAGAIN = 162,
|
||||
SDL_SCANCODE_CRSEL = 163,
|
||||
SDL_SCANCODE_EXSEL = 164,
|
||||
|
||||
SDL_SCANCODE_KP_00 = 176,
|
||||
SDL_SCANCODE_KP_000 = 177,
|
||||
SDL_SCANCODE_THOUSANDSSEPARATOR = 178,
|
||||
SDL_SCANCODE_DECIMALSEPARATOR = 179,
|
||||
SDL_SCANCODE_CURRENCYUNIT = 180,
|
||||
SDL_SCANCODE_CURRENCYSUBUNIT = 181,
|
||||
SDL_SCANCODE_KP_LEFTPAREN = 182,
|
||||
SDL_SCANCODE_KP_RIGHTPAREN = 183,
|
||||
SDL_SCANCODE_KP_LEFTBRACE = 184,
|
||||
SDL_SCANCODE_KP_RIGHTBRACE = 185,
|
||||
SDL_SCANCODE_KP_TAB = 186,
|
||||
SDL_SCANCODE_KP_BACKSPACE = 187,
|
||||
SDL_SCANCODE_KP_A = 188,
|
||||
SDL_SCANCODE_KP_B = 189,
|
||||
SDL_SCANCODE_KP_C = 190,
|
||||
SDL_SCANCODE_KP_D = 191,
|
||||
SDL_SCANCODE_KP_E = 192,
|
||||
SDL_SCANCODE_KP_F = 193,
|
||||
SDL_SCANCODE_KP_XOR = 194,
|
||||
SDL_SCANCODE_KP_POWER = 195,
|
||||
SDL_SCANCODE_KP_PERCENT = 196,
|
||||
SDL_SCANCODE_KP_LESS = 197,
|
||||
SDL_SCANCODE_KP_GREATER = 198,
|
||||
SDL_SCANCODE_KP_AMPERSAND = 199,
|
||||
SDL_SCANCODE_KP_DBLAMPERSAND = 200,
|
||||
SDL_SCANCODE_KP_VERTICALBAR = 201,
|
||||
SDL_SCANCODE_KP_DBLVERTICALBAR = 202,
|
||||
SDL_SCANCODE_KP_COLON = 203,
|
||||
SDL_SCANCODE_KP_HASH = 204,
|
||||
SDL_SCANCODE_KP_SPACE = 205,
|
||||
SDL_SCANCODE_KP_AT = 206,
|
||||
SDL_SCANCODE_KP_EXCLAM = 207,
|
||||
SDL_SCANCODE_KP_MEMSTORE = 208,
|
||||
SDL_SCANCODE_KP_MEMRECALL = 209,
|
||||
SDL_SCANCODE_KP_MEMCLEAR = 210,
|
||||
SDL_SCANCODE_KP_MEMADD = 211,
|
||||
SDL_SCANCODE_KP_MEMSUBTRACT = 212,
|
||||
SDL_SCANCODE_KP_MEMMULTIPLY = 213,
|
||||
SDL_SCANCODE_KP_MEMDIVIDE = 214,
|
||||
SDL_SCANCODE_KP_PLUSMINUS = 215,
|
||||
SDL_SCANCODE_KP_CLEAR = 216,
|
||||
SDL_SCANCODE_KP_CLEARENTRY = 217,
|
||||
SDL_SCANCODE_KP_BINARY = 218,
|
||||
SDL_SCANCODE_KP_OCTAL = 219,
|
||||
SDL_SCANCODE_KP_DECIMAL = 220,
|
||||
SDL_SCANCODE_KP_HEXADECIMAL = 221,
|
||||
|
||||
SDL_SCANCODE_LCTRL = 224,
|
||||
SDL_SCANCODE_LSHIFT = 225,
|
||||
SDL_SCANCODE_LALT = 226, /**< alt, option */
|
||||
SDL_SCANCODE_LGUI = 227, /**< windows, command (apple), meta */
|
||||
SDL_SCANCODE_RCTRL = 228,
|
||||
SDL_SCANCODE_RSHIFT = 229,
|
||||
SDL_SCANCODE_RALT = 230, /**< alt gr, option */
|
||||
SDL_SCANCODE_RGUI = 231, /**< windows, command (apple), meta */
|
||||
|
||||
SDL_SCANCODE_MODE = 257, /**< I'm not sure if this is really not covered
|
||||
* by any of the above, but since there's a
|
||||
* special KMOD_MODE for it I'm adding it here
|
||||
*/
|
||||
|
||||
/* @} *//* Usage page 0x07 */
|
||||
|
||||
/**
|
||||
* \name Usage page 0x0C
|
||||
*
|
||||
* These values are mapped from usage page 0x0C (USB consumer page).
|
||||
*/
|
||||
/* @{ */
|
||||
|
||||
SDL_SCANCODE_AUDIONEXT = 258,
|
||||
SDL_SCANCODE_AUDIOPREV = 259,
|
||||
SDL_SCANCODE_AUDIOSTOP = 260,
|
||||
SDL_SCANCODE_AUDIOPLAY = 261,
|
||||
SDL_SCANCODE_AUDIOMUTE = 262,
|
||||
SDL_SCANCODE_MEDIASELECT = 263,
|
||||
SDL_SCANCODE_WWW = 264,
|
||||
SDL_SCANCODE_MAIL = 265,
|
||||
SDL_SCANCODE_CALCULATOR = 266,
|
||||
SDL_SCANCODE_COMPUTER = 267,
|
||||
SDL_SCANCODE_AC_SEARCH = 268,
|
||||
SDL_SCANCODE_AC_HOME = 269,
|
||||
SDL_SCANCODE_AC_BACK = 270,
|
||||
SDL_SCANCODE_AC_FORWARD = 271,
|
||||
SDL_SCANCODE_AC_STOP = 272,
|
||||
SDL_SCANCODE_AC_REFRESH = 273,
|
||||
SDL_SCANCODE_AC_BOOKMARKS = 274,
|
||||
|
||||
/* @} *//* Usage page 0x0C */
|
||||
|
||||
/**
|
||||
* \name Walther keys
|
||||
*
|
||||
* These are values that Christian Walther added (for mac keyboard?).
|
||||
*/
|
||||
/* @{ */
|
||||
|
||||
SDL_SCANCODE_BRIGHTNESSDOWN = 275,
|
||||
SDL_SCANCODE_BRIGHTNESSUP = 276,
|
||||
SDL_SCANCODE_DISPLAYSWITCH = 277, /**< display mirroring/dual display
|
||||
switch, video mode switch */
|
||||
SDL_SCANCODE_KBDILLUMTOGGLE = 278,
|
||||
SDL_SCANCODE_KBDILLUMDOWN = 279,
|
||||
SDL_SCANCODE_KBDILLUMUP = 280,
|
||||
SDL_SCANCODE_EJECT = 281,
|
||||
SDL_SCANCODE_SLEEP = 282,
|
||||
|
||||
SDL_SCANCODE_APP1 = 283,
|
||||
SDL_SCANCODE_APP2 = 284,
|
||||
|
||||
/* @} *//* Walther keys */
|
||||
|
||||
/* Add any other keys here. */
|
||||
|
||||
SDL_NUM_SCANCODES = 512 /**< not a key, just marks the number of scancodes
|
||||
for array bounds */
|
||||
} SDL_Scancode;
|
||||
|
||||
extern SDL_Scancode SDL_GetScancodeFromKey(SDLKey key);
|
||||
|
||||
extern SDL_Scancode SDL_GetScancodeFromName(const char *name);
|
||||
|
||||
extern const char *
|
||||
SDL_GetScancodeName(SDL_Scancode scancode);
|
||||
|
||||
/**
|
||||
* \brief Get a key code from a human-readable name
|
||||
*
|
||||
* \return key code, or SDLK_UNKNOWN if the name wasn't recognized
|
||||
*
|
||||
* \sa SDL_Keycode
|
||||
*/
|
||||
extern SDLKey SDL_GetKeyFromName(const char *name);
|
||||
|
||||
|
||||
extern SDLKey SDL_GetKeyFromScancode(SDL_Scancode scancode);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SDL_KEYBOARD_HPP_INCLUDED */
|
|
@ -2735,4 +2735,3 @@ std::ostream& operator<<(std::ostream& s, const SDL_Rect& rect)
|
|||
s << rect.x << ',' << rect.y << " x " << rect.w << ',' << rect.h;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue