Expose key modifier state to C++/Lua

develop
lethosor 2015-01-11 12:48:52 -05:00
parent 2db6c0c735
commit 077d149d64
3 changed files with 39 additions and 17 deletions

@ -714,7 +714,7 @@ command_result Core::runCommand(color_ostream &con, const std::string &first, ve
std::string keystr = parts[1]; std::string keystr = parts[1];
if (parts[0] == "set") if (parts[0] == "set")
ClearKeyBindings(keystr); ClearKeyBindings(keystr);
for (int i = parts.size()-1; i >= 2; i--) for (int i = parts.size()-1; i >= 2; i--)
{ {
if (!AddKeyBinding(keystr, parts[i])) { if (!AddKeyBinding(keystr, parts[i])) {
con.printerr("Invalid key spec: %s\n", keystr.c_str()); con.printerr("Invalid key spec: %s\n", keystr.c_str());
@ -910,7 +910,7 @@ void fIOthread(void * iodata)
main_history.add(command); main_history.add(command);
main_history.save("dfhack.history"); main_history.save("dfhack.history");
} }
auto rv = core->runCommand(con, command); auto rv = core->runCommand(con, command);
if (rv == CR_NOT_IMPLEMENTED) if (rv == CR_NOT_IMPLEMENTED)
@ -1091,6 +1091,7 @@ bool Core::Init()
screen_window = new Windows::top_level_window(); screen_window = new Windows::top_level_window();
screen_window->addChild(new Windows::dfhack_dummy(5,10)); screen_window->addChild(new Windows::dfhack_dummy(5,10));
started = true; started = true;
modstate = 0;
cerr << "Starting the TCP listener.\n"; cerr << "Starting the TCP listener.\n";
server = new ServerMain(); server = new ServerMain();
@ -1579,7 +1580,7 @@ int UnicodeAwareSym(const SDL::KeyboardEvent& ke)
//MEMO: return false if event is consumed //MEMO: return false if event is consumed
int Core::DFH_SDL_Event(SDL::Event* ev) int Core::DFH_SDL_Event(SDL::Event* ev)
{ {
static bool alt = 0; //static bool alt = 0;
// do NOT process events before we are ready. // do NOT process events before we are ready.
if(!started) return true; if(!started) return true;
@ -1589,31 +1590,27 @@ int Core::DFH_SDL_Event(SDL::Event* ev)
{ {
auto ke = (SDL::KeyboardEvent *)ev; auto ke = (SDL::KeyboardEvent *)ev;
if (ke->ksym.sym == SDL::K_LALT || ke->ksym.sym == SDL::K_RALT) if (ke->ksym.sym == SDL::K_LSHIFT || ke->ksym.sym == SDL::K_RSHIFT)
{ modstate = (ev->type == SDL::ET_KEYDOWN) ? modstate | MOD_SHIFT : modstate & ~MOD_SHIFT;
alt = (ev->type == SDL::ET_KEYDOWN); else if (ke->ksym.sym == SDL::K_LCTRL || ke->ksym.sym == SDL::K_RCTRL)
} modstate = (ev->type == SDL::ET_KEYDOWN) ? modstate | MOD_CTRL : modstate & ~MOD_CTRL;
else else if (ke->ksym.sym == SDL::K_LALT || ke->ksym.sym == SDL::K_RALT)
if(ke->state == SDL::BTN_PRESSED && !hotkey_states[ke->ksym.sym]) modstate = (ev->type == SDL::ET_KEYDOWN) ? modstate | MOD_ALT : modstate & ~MOD_ALT;
else if(ke->state == SDL::BTN_PRESSED && !hotkey_states[ke->ksym.sym])
{ {
hotkey_states[ke->ksym.sym] = true; hotkey_states[ke->ksym.sym] = true;
int mod = 0;
if (ke->ksym.mod & SDL::KMOD_SHIFT) mod |= 1;
if (ke->ksym.mod & SDL::KMOD_CTRL) mod |= 2;
if (alt) mod |= 4;
// Use unicode so Windows gives the correct value for the // Use unicode so Windows gives the correct value for the
// user's Input Language // user's Input Language
if((ke->ksym.unicode & 0xff80) == 0) if((ke->ksym.unicode & 0xff80) == 0)
{ {
int key = UnicodeAwareSym(*ke); int key = UnicodeAwareSym(*ke);
SelectHotkey(key, mod); SelectHotkey(key, modstate);
} }
else else
{ {
// Pretend non-ascii characters don't happen: // Pretend non-ascii characters don't happen:
SelectHotkey(ke->ksym.sym, mod); SelectHotkey(ke->ksym.sym, modstate);
} }
} }
else if(ke->state == SDL::BTN_RELEASED) else if(ke->state == SDL::BTN_RELEASED)
@ -1710,7 +1707,7 @@ static bool parseKeySpec(std::string keyspec, int *psym, int *pmod, std::string
} else if (keyspec.size() > 4 && keyspec.substr(0, 4) == "Alt-") { } else if (keyspec.size() > 4 && keyspec.substr(0, 4) == "Alt-") {
*pmod |= 4; *pmod |= 4;
keyspec = keyspec.substr(4); keyspec = keyspec.substr(4);
} else } else
break; break;
} }

@ -2008,10 +2008,12 @@ static void *checkaddr(lua_State *L, int idx, bool allow_null = false)
static uint32_t getImageBase() { return Core::getInstance().p->getBase(); } static uint32_t getImageBase() { return Core::getInstance().p->getBase(); }
static int getRebaseDelta() { return Core::getInstance().vinfo->getRebaseDelta(); } static int getRebaseDelta() { return Core::getInstance().vinfo->getRebaseDelta(); }
static int8_t getModstate() { return Core::getInstance().getModstate(); }
static const LuaWrapper::FunctionReg dfhack_internal_module[] = { static const LuaWrapper::FunctionReg dfhack_internal_module[] = {
WRAP(getImageBase), WRAP(getImageBase),
WRAP(getRebaseDelta), WRAP(getRebaseDelta),
WRAP(getModstate),
{ NULL, NULL } { NULL, NULL }
}; };
@ -2351,6 +2353,22 @@ static int internal_runCommand(lua_State *L)
return 1; return 1;
} }
static int internal_getModifiers(lua_State *L)
{
int8_t modstate = Core::getInstance().getModstate();
lua_newtable(L);
lua_pushstring(L, "shift");
lua_pushboolean(L, modstate & MOD_SHIFT);
lua_settable(L, -3);
lua_pushstring(L, "ctrl");
lua_pushboolean(L, modstate & MOD_CTRL);
lua_settable(L, -3);
lua_pushstring(L, "alt");
lua_pushboolean(L, modstate & MOD_ALT);
lua_settable(L, -3);
return 1;
}
static const luaL_Reg dfhack_internal_funcs[] = { static const luaL_Reg dfhack_internal_funcs[] = {
{ "getAddress", internal_getAddress }, { "getAddress", internal_getAddress },
{ "setAddress", internal_setAddress }, { "setAddress", internal_setAddress },
@ -2365,6 +2383,7 @@ static const luaL_Reg dfhack_internal_funcs[] = {
{ "diffscan", internal_diffscan }, { "diffscan", internal_diffscan },
{ "getDir", internal_getDir }, { "getDir", internal_getDir },
{ "runCommand", internal_runCommand }, { "runCommand", internal_runCommand },
{ "getModifiers", internal_getModifiers },
{ NULL, NULL } { NULL, NULL }
}; };

@ -36,6 +36,10 @@ distribution.
#include "RemoteClient.h" #include "RemoteClient.h"
#define MOD_SHIFT 1
#define MOD_CTRL 2
#define MOD_ALT 4
struct WINDOW; struct WINDOW;
namespace tthread namespace tthread
@ -142,6 +146,7 @@ namespace DFHack
bool ClearKeyBindings(std::string keyspec); bool ClearKeyBindings(std::string keyspec);
bool AddKeyBinding(std::string keyspec, std::string cmdline); bool AddKeyBinding(std::string keyspec, std::string cmdline);
std::vector<std::string> ListKeyBindings(std::string keyspec); std::vector<std::string> ListKeyBindings(std::string keyspec);
int8_t getModstate() { return modstate; }
std::string getHackPath(); std::string getHackPath();
@ -216,6 +221,7 @@ namespace DFHack
std::string cmdline; std::string cmdline;
std::string focus; std::string focus;
}; };
int8_t modstate;
std::map<int, std::vector<KeyBinding> > key_bindings; std::map<int, std::vector<KeyBinding> > key_bindings;
std::map<int, bool> hotkey_states; std::map<int, bool> hotkey_states;