Skip to content

Commit

Permalink
Implemented qualifier keys support in hotkeys
Browse files Browse the repository at this point in the history
Currently supported qualifiers are Ctrl, Alt, Shift, GUI/Win keys
  • Loading branch information
midwan committed Dec 23, 2020
1 parent 666c1fe commit 7ab9a7e
Show file tree
Hide file tree
Showing 7 changed files with 264 additions and 101 deletions.
19 changes: 19 additions & 0 deletions src/include/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -1092,6 +1092,25 @@ struct amiberry_customised_layout
std::array<int, 15> select;
};

struct hotkey_modifiers
{
bool lctrl;
bool rctrl;
bool lalt;
bool ralt;
bool lshift;
bool rshift;
bool lgui;
bool rgui;
};
struct amiberry_hotkey
{
int scancode;
std::string key_name;
std::string modifiers_string;
hotkey_modifiers modifiers;
};

struct amiberry_options
{
bool quickstart_start = true;
Expand Down
117 changes: 68 additions & 49 deletions src/osdep/amiberry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,14 @@ bool host_poweroff = false;
int saveimageoriginalpath = 0;

struct amiberry_options amiberry_options = {};

// Default Enter GUI key is F12
int enter_gui_key = 0;
amiberry_hotkey enter_gui_key;
SDL_GameControllerButton enter_gui_button;
// We don't set a default value for Quitting
int quit_key = 0;
// The default value for Action Replay is Pause/Break
int action_replay_button = 0;
// No default value for Full Screen toggle
int fullscreen_key = 0;
// No default value for Minimize key
int minimize_key = 0;
amiberry_hotkey quit_key;
amiberry_hotkey action_replay_button;
amiberry_hotkey fullscreen_key;
amiberry_hotkey minimize_key;

bool lctrl, rctrl, lalt, ralt, lshift, rshift, lgui, rgui;

bool mouse_grabbed = false;

Expand All @@ -100,17 +96,63 @@ std::string get_version_string()
return label_text;
}

amiberry_hotkey get_hotkey_from_config(std::string config_option)
{
amiberry_hotkey hotkey = {};
std::string delimiter = "+";
std::string lctrl = "LCtrl";
std::string rctrl = "RCtrl";
std::string lalt = "LAlt";
std::string ralt = "RAlt";
std::string lshift = "LShift";
std::string rshift = "RShift";
std::string lgui = "LGUI";
std::string rgui = "RGUI";

if (config_option.empty()) return hotkey;

size_t pos = 0;
std::string token;
while ((pos = config_option.find(delimiter)) != std::string::npos)
{
token = config_option.substr(0, pos);
if (token.compare(lctrl) == 0)
hotkey.modifiers.lctrl = true;
if (token.compare(rctrl) == 0)
hotkey.modifiers.rctrl = true;
if (token.compare(lalt) == 0)
hotkey.modifiers.lalt = true;
if (token.compare(ralt) == 0)
hotkey.modifiers.ralt = true;
if (token.compare(lshift) == 0)
hotkey.modifiers.lshift = true;
if (token.compare(rshift) == 0)
hotkey.modifiers.rshift = true;
if (token.compare(lgui) == 0)
hotkey.modifiers.lgui = true;
if (token.compare(rgui) == 0)
hotkey.modifiers.rgui = true;

config_option.erase(0, pos + delimiter.length());
}
hotkey.key_name = config_option;
hotkey.scancode = SDL_GetScancodeFromName(hotkey.key_name.c_str());

return hotkey;
}


void set_key_configs(struct uae_prefs* p)
{
if (strncmp(p->open_gui, "", 1) != 0)
// If we have a value in the config, we use that instead
enter_gui_key = SDL_GetScancodeFromName(p->open_gui);
enter_gui_key = get_hotkey_from_config(p->open_gui);
else
// Otherwise we go for the default found in amiberry.conf
enter_gui_key = SDL_GetScancodeFromName(amiberry_options.default_open_gui_key);
enter_gui_key = get_hotkey_from_config(amiberry_options.default_open_gui_key);
// if nothing was found in amiberry.conf either, we default back to F12
if (enter_gui_key == 0)
enter_gui_key = SDL_SCANCODE_F12;
if (enter_gui_key.scancode == 0)
enter_gui_key.scancode = SDL_SCANCODE_F12;

enter_gui_button = SDL_GameControllerGetButtonFromString(p->open_gui);
if (enter_gui_button == SDL_CONTROLLER_BUTTON_INVALID)
Expand All @@ -119,24 +161,24 @@ void set_key_configs(struct uae_prefs* p)
enter_gui_button = SDL_CONTROLLER_BUTTON_GUIDE;

if (strncmp(p->quit_amiberry, "", 1) != 0)
quit_key = SDL_GetScancodeFromName(p->quit_amiberry);
quit_key = get_hotkey_from_config(p->quit_amiberry);
else
quit_key = SDL_GetScancodeFromName(amiberry_options.default_quit_key);
quit_key = get_hotkey_from_config(amiberry_options.default_quit_key);

if (strncmp(p->action_replay, "", 1) != 0)
action_replay_button = SDL_GetScancodeFromName(p->action_replay);
action_replay_button = get_hotkey_from_config(p->action_replay);
else
action_replay_button = SDL_GetScancodeFromName(amiberry_options.default_ar_key);
if (action_replay_button == 0)
action_replay_button = SDL_SCANCODE_PAUSE;
action_replay_button = get_hotkey_from_config(amiberry_options.default_ar_key);
if (action_replay_button.scancode == 0)
action_replay_button.scancode = SDL_SCANCODE_PAUSE;

if (strncmp(p->fullscreen_toggle, "", 1) != 0)
fullscreen_key = SDL_GetScancodeFromName(p->fullscreen_toggle);
fullscreen_key = get_hotkey_from_config(p->fullscreen_toggle);
else
fullscreen_key = SDL_GetScancodeFromName(amiberry_options.default_fullscreen_toggle_key);
fullscreen_key = get_hotkey_from_config(amiberry_options.default_fullscreen_toggle_key);

if (strncmp(p->minimize, "", 1) != 0)
minimize_key = SDL_GetScancodeFromName(p->minimize);
minimize_key = get_hotkey_from_config(p->minimize);
}

extern void signal_segv(int signum, siginfo_t* info, void* ptr);
Expand Down Expand Up @@ -1007,31 +1049,6 @@ void process_event(SDL_Event event)
scancode = SDL_SCANCODE_RGUI;
}

if (enter_gui_key && scancode == enter_gui_key)
{
inputdevice_add_inputcode(AKS_ENTERGUI, 1, nullptr);
break;
}
if (action_replay_button && scancode == action_replay_button)
{
inputdevice_add_inputcode(AKS_FREEZEBUTTON, 1, nullptr);
break;
}
if (fullscreen_key && scancode == fullscreen_key)
{
inputdevice_add_inputcode(AKS_TOGGLEWINDOWEDFULLSCREEN, 1, nullptr);
break;
}
if (quit_key && scancode == quit_key)
{
inputdevice_add_inputcode(AKS_QUIT, 1, nullptr);
break;
}
if (minimize_key && scancode == minimize_key)
{
minimizewindow();
break;
}
my_kbd_handler(0, scancode, pressed, false);
}
break;
Expand Down Expand Up @@ -1214,6 +1231,7 @@ void update_clipboard()

int handle_msgpump()
{
lctrl = rctrl = lalt = ralt = lshift = rshift = lgui = rgui = false;
auto got_event = 0;
SDL_Event event;

Expand Down Expand Up @@ -1242,6 +1260,7 @@ bool handle_events()
// we got just paused, report it to caller.
return true;
}
lctrl = rctrl = lalt = ralt = lshift = rshift = lgui = rgui = false;
SDL_Event event;
while (SDL_PollEvent(&event))
{
Expand Down
55 changes: 30 additions & 25 deletions src/osdep/gui/PanelMisc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,56 +213,61 @@ class MiscActionListener : public gcn::ActionListener

else if (actionEvent.getSource() == cmdOpenGUI)
{
const auto* key = ShowMessageForInput("Press a key", "Press a key to map to Open the GUI, or ESC to cancel...", "Cancel");
if (key != nullptr)
const auto key = ShowMessageForInput("Press a key", "Press a key to map to Open the GUI, or ESC to cancel...", "Cancel");
if (!key.key_name.empty())
{
txtOpenGUI->setText(key);
strcpy(changed_prefs.open_gui, key);
strcpy(currprefs.open_gui, key);
std::string hotkey = key.modifiers_string + key.key_name;
txtOpenGUI->setText(hotkey);
strcpy(changed_prefs.open_gui, hotkey.c_str());
strcpy(currprefs.open_gui, hotkey.c_str());
}
}

else if (actionEvent.getSource() == cmdKeyForQuit)
{
const auto* key = ShowMessageForInput("Press a key", "Press a key to map to Quit the emulator, or ESC to cancel...", "Cancel");
if (key != nullptr)
const auto key = ShowMessageForInput("Press a key", "Press a key to map to Quit the emulator, or ESC to cancel...", "Cancel");
if (!key.key_name.empty())
{
txtKeyForQuit->setText(key);
strcpy(changed_prefs.quit_amiberry, key);
strcpy(currprefs.quit_amiberry, key);
std::string hotkey = key.modifiers_string + key.key_name;
txtKeyForQuit->setText(hotkey);
strcpy(changed_prefs.quit_amiberry, hotkey.c_str());
strcpy(currprefs.quit_amiberry, hotkey.c_str());
}
}

else if (actionEvent.getSource() == cmdKeyActionReplay)
{
const auto* key = ShowMessageForInput("Press a key", "Press a key to map to Action Replay, or ESC to cancel...", "Cancel");
if (key != nullptr)
const auto key = ShowMessageForInput("Press a key", "Press a key to map to Action Replay, or ESC to cancel...", "Cancel");
if (!key.key_name.empty())
{
txtKeyActionReplay->setText(key);
strcpy(changed_prefs.action_replay, key);
strcpy(currprefs.action_replay, key);
std::string hotkey = key.modifiers_string + key.key_name;
txtKeyActionReplay->setText(hotkey);
strcpy(changed_prefs.action_replay, hotkey.c_str());
strcpy(currprefs.action_replay, hotkey.c_str());
}
}

else if (actionEvent.getSource() == cmdKeyFullScreen)
{
const auto* key = ShowMessageForInput("Press a key", "Press a key to map to toggle FullScreen, or ESC to cancel...", "Cancel");
if (key != nullptr)
const auto key = ShowMessageForInput("Press a key", "Press a key to map to toggle FullScreen, or ESC to cancel...", "Cancel");
if (!key.key_name.empty())
{
txtKeyFullScreen->setText(key);
strcpy(changed_prefs.fullscreen_toggle, key);
strcpy(currprefs.fullscreen_toggle, key);
std::string hotkey = key.modifiers_string + key.key_name;
txtKeyFullScreen->setText(hotkey);
strcpy(changed_prefs.fullscreen_toggle, hotkey.c_str());
strcpy(currprefs.fullscreen_toggle, hotkey.c_str());
}
}

else if (actionEvent.getSource() == cmdKeyMinimize)
{
const auto* key = ShowMessageForInput("Press a key", "Press a key to map to Minimize or ESC to cancel...", "Cancel");
if (key != nullptr)
const auto key = ShowMessageForInput("Press a key", "Press a key to map to Minimize or ESC to cancel...", "Cancel");
if (!key.key_name.empty())
{
txtKeyMinimize->setText(key);
strcpy(changed_prefs.minimize, key);
strcpy(currprefs.minimize, key);
std::string hotkey = key.modifiers_string + key.key_name;
txtKeyMinimize->setText(hotkey);
strcpy(changed_prefs.minimize, hotkey.c_str());
strcpy(currprefs.minimize, hotkey.c_str());
}
}

Expand Down
Loading

0 comments on commit 7ab9a7e

Please # to comment.