Handle key repeats in Jtk itself
This commit is contained in:
parent
6ff2faf4af
commit
4e3050dbec
@ -11,22 +11,6 @@
|
||||
#define INITIAL_HEIGHT 800
|
||||
#define FONT_SIZE 16
|
||||
|
||||
#define TIMER_TYPE_KEY_REPEAT 1u
|
||||
|
||||
struct KeyStatus
|
||||
{
|
||||
size_t timer_id;
|
||||
uint32_t keyval;
|
||||
bool pressed;
|
||||
bool event_pending;
|
||||
|
||||
KeyStatus()
|
||||
{
|
||||
pressed = false;
|
||||
}
|
||||
};
|
||||
std::unordered_map<uint32_t, KeyStatus> g_key_statuses;
|
||||
|
||||
/**
|
||||
* Initialize OpenGL.
|
||||
*
|
||||
@ -139,6 +123,8 @@ bool Window::create(std::shared_ptr<Buffer> buffer)
|
||||
|
||||
resize();
|
||||
|
||||
m_redraw_requested = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -153,13 +139,13 @@ void Window::run_event_loop()
|
||||
|
||||
while (!m_exit_requested)
|
||||
{
|
||||
Jtk_WaitEvent(&event);
|
||||
handle_event(event);
|
||||
if (m_redraw_requested)
|
||||
{
|
||||
m_redraw_requested = false;
|
||||
redraw();
|
||||
}
|
||||
Jtk_WaitEvent(&event);
|
||||
handle_event(event);
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,46 +163,18 @@ void Window::handle_event(Jtk_Event & event)
|
||||
#endif
|
||||
|
||||
case JTK_EVENT_KEY_PRESS:
|
||||
if (!event.key.repeat)
|
||||
{
|
||||
KeyStatus & key_status = g_key_statuses[event.key.key];
|
||||
key_status.pressed = true;
|
||||
key_status.keyval = event.key.key;
|
||||
key_status.timer_id = Jtk_AddTimer(300u, 25u,
|
||||
(void *)TIMER_TYPE_KEY_REPEAT, &key_status);
|
||||
handle_keypress(event.key.key);
|
||||
}
|
||||
break;
|
||||
|
||||
case JTK_EVENT_KEY_RELEASE:
|
||||
{
|
||||
KeyStatus & key_status = g_key_statuses[event.key.key];
|
||||
if (key_status.pressed)
|
||||
{
|
||||
Jtk_RemoveTimer(key_status.timer_id);
|
||||
key_status.pressed = false;
|
||||
}
|
||||
Jtk_BeginKeyRepeat(&event.key, 300u, 25u);
|
||||
}
|
||||
handle_keypress(event.key.key);
|
||||
m_redraw_requested = true;
|
||||
break;
|
||||
|
||||
case JTK_EVENT_WINDOW_EXPOSE:
|
||||
m_redraw_requested = true;
|
||||
break;
|
||||
|
||||
case JTK_EVENT_TIMER:
|
||||
switch ((uintptr_t)event.timer.user1)
|
||||
{
|
||||
case TIMER_TYPE_KEY_REPEAT:
|
||||
{
|
||||
KeyStatus * key_status = (KeyStatus *)event.timer.user2;
|
||||
if (key_status->pressed)
|
||||
{
|
||||
handle_keypress(key_status->keyval);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case SDL_WINDOWEVENT:
|
||||
switch (event.window.event)
|
||||
|
@ -7,167 +7,179 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include "Jtk_internal.h"
|
||||
#include <unordered_map>
|
||||
|
||||
/** Do not wait longer than 100ms */
|
||||
#define MAX_WAIT_TIME 100000u
|
||||
|
||||
/**
|
||||
* Process an X keyboard event.
|
||||
*
|
||||
* @param x_event
|
||||
* Pointer to the X event.
|
||||
* @param event
|
||||
* Pointer to the Jtk event.
|
||||
*/
|
||||
static bool ProcessXKeyEvent(XEvent * x_event, Jtk_Event * event)
|
||||
/** Hold a copy of the last-seen keyboard modifier state. */
|
||||
static unsigned int g_x_state;
|
||||
static std::unordered_map<unsigned int, size_t> g_repeating_keys;
|
||||
static std::unordered_map<size_t, unsigned int> g_key_repeat_timers;
|
||||
|
||||
static void StopKeyRepeat(unsigned int x_keycode)
|
||||
{
|
||||
auto it = g_repeating_keys.find(x_keycode);
|
||||
if (it != g_repeating_keys.end())
|
||||
{
|
||||
size_t timer_id = it->second;
|
||||
Jtk_RemoveTimer(timer_id);
|
||||
g_repeating_keys.erase(x_keycode);
|
||||
g_key_repeat_timers.erase(timer_id);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t XKeyToJtkKey(unsigned int x_keycode)
|
||||
{
|
||||
XKeyEvent x_key_event;
|
||||
x_key_event.type = KeyPress;
|
||||
x_key_event.display = g_display;
|
||||
/* Turn off the ControlMask bit for looking up keys. We'll handle control
|
||||
* keys ourselves. */
|
||||
x_key_event.state = g_x_state & ~ControlMask;
|
||||
x_key_event.keycode = x_keycode;
|
||||
char buffer;
|
||||
KeySym keysym;
|
||||
/* Make a copy of x_event and turn off the ControlMask bit for lookup
|
||||
* up keycodes. We'll handle control keys ourselves. */
|
||||
XEvent x_event_for_key_lookup = *x_event;
|
||||
x_event_for_key_lookup.xkey.state &= ~ControlMask;
|
||||
if (XLookupString(&x_event_for_key_lookup.xkey, &buffer, 1, &keysym, nullptr) > 0)
|
||||
uint32_t key = JTK_KEY_UNKNOWN;
|
||||
|
||||
if (XLookupString(&x_key_event, &buffer, 1, &keysym, nullptr) > 0)
|
||||
{
|
||||
if (buffer == '\r')
|
||||
{
|
||||
event->key.key = '\n';
|
||||
key = '\n';
|
||||
}
|
||||
else
|
||||
{
|
||||
event->key.key = buffer;
|
||||
key = buffer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (keysym)
|
||||
{
|
||||
case XK_F1: event->key.key = JTK_KEY_F1; break;
|
||||
case XK_F2: event->key.key = JTK_KEY_F2; break;
|
||||
case XK_F3: event->key.key = JTK_KEY_F3; break;
|
||||
case XK_F4: event->key.key = JTK_KEY_F4; break;
|
||||
case XK_F5: event->key.key = JTK_KEY_F5; break;
|
||||
case XK_F6: event->key.key = JTK_KEY_F6; break;
|
||||
case XK_F7: event->key.key = JTK_KEY_F7; break;
|
||||
case XK_F8: event->key.key = JTK_KEY_F8; break;
|
||||
case XK_F9: event->key.key = JTK_KEY_F9; break;
|
||||
case XK_F10: event->key.key = JTK_KEY_F10; break;
|
||||
case XK_F11: event->key.key = JTK_KEY_F11; break;
|
||||
case XK_F12: event->key.key = JTK_KEY_F12; break;
|
||||
case XK_F13: event->key.key = JTK_KEY_F13; break;
|
||||
case XK_F14: event->key.key = JTK_KEY_F14; break;
|
||||
case XK_F15: event->key.key = JTK_KEY_F15; break;
|
||||
case XK_F16: event->key.key = JTK_KEY_F16; break;
|
||||
case XK_F17: event->key.key = JTK_KEY_F17; break;
|
||||
case XK_F18: event->key.key = JTK_KEY_F18; break;
|
||||
case XK_F19: event->key.key = JTK_KEY_F19; break;
|
||||
case XK_F20: event->key.key = JTK_KEY_F20; break;
|
||||
case XK_F21: event->key.key = JTK_KEY_F21; break;
|
||||
case XK_F22: event->key.key = JTK_KEY_F22; break;
|
||||
case XK_F23: event->key.key = JTK_KEY_F23; break;
|
||||
case XK_F24: event->key.key = JTK_KEY_F24; break;
|
||||
case XK_F25: event->key.key = JTK_KEY_F25; break;
|
||||
case XK_F26: event->key.key = JTK_KEY_F26; break;
|
||||
case XK_F27: event->key.key = JTK_KEY_F27; break;
|
||||
case XK_F28: event->key.key = JTK_KEY_F28; break;
|
||||
case XK_F29: event->key.key = JTK_KEY_F29; break;
|
||||
case XK_F30: event->key.key = JTK_KEY_F30; break;
|
||||
case XK_F31: event->key.key = JTK_KEY_F31; break;
|
||||
case XK_F1: key = JTK_KEY_F1; break;
|
||||
case XK_F2: key = JTK_KEY_F2; break;
|
||||
case XK_F3: key = JTK_KEY_F3; break;
|
||||
case XK_F4: key = JTK_KEY_F4; break;
|
||||
case XK_F5: key = JTK_KEY_F5; break;
|
||||
case XK_F6: key = JTK_KEY_F6; break;
|
||||
case XK_F7: key = JTK_KEY_F7; break;
|
||||
case XK_F8: key = JTK_KEY_F8; break;
|
||||
case XK_F9: key = JTK_KEY_F9; break;
|
||||
case XK_F10: key = JTK_KEY_F10; break;
|
||||
case XK_F11: key = JTK_KEY_F11; break;
|
||||
case XK_F12: key = JTK_KEY_F12; break;
|
||||
case XK_F13: key = JTK_KEY_F13; break;
|
||||
case XK_F14: key = JTK_KEY_F14; break;
|
||||
case XK_F15: key = JTK_KEY_F15; break;
|
||||
case XK_F16: key = JTK_KEY_F16; break;
|
||||
case XK_F17: key = JTK_KEY_F17; break;
|
||||
case XK_F18: key = JTK_KEY_F18; break;
|
||||
case XK_F19: key = JTK_KEY_F19; break;
|
||||
case XK_F20: key = JTK_KEY_F20; break;
|
||||
case XK_F21: key = JTK_KEY_F21; break;
|
||||
case XK_F22: key = JTK_KEY_F22; break;
|
||||
case XK_F23: key = JTK_KEY_F23; break;
|
||||
case XK_F24: key = JTK_KEY_F24; break;
|
||||
case XK_F25: key = JTK_KEY_F25; break;
|
||||
case XK_F26: key = JTK_KEY_F26; break;
|
||||
case XK_F27: key = JTK_KEY_F27; break;
|
||||
case XK_F28: key = JTK_KEY_F28; break;
|
||||
case XK_F29: key = JTK_KEY_F29; break;
|
||||
case XK_F30: key = JTK_KEY_F30; break;
|
||||
case XK_F31: key = JTK_KEY_F31; break;
|
||||
|
||||
case XK_Shift_L: event->key.key = JTK_KEY_SHIFT_L; break;
|
||||
case XK_Shift_R: event->key.key = JTK_KEY_SHIFT_R; break;
|
||||
case XK_Control_L: event->key.key = JTK_KEY_CTRL_L; break;
|
||||
case XK_Control_R: event->key.key = JTK_KEY_CTRL_R; break;
|
||||
case XK_Caps_Lock: event->key.key = JTK_KEY_CAPS_LOCK; break;
|
||||
case XK_Shift_Lock: event->key.key = JTK_KEY_SHIFT_LOCK;break;
|
||||
case XK_Shift_L: key = JTK_KEY_SHIFT_L; break;
|
||||
case XK_Shift_R: key = JTK_KEY_SHIFT_R; break;
|
||||
case XK_Control_L: key = JTK_KEY_CTRL_L; break;
|
||||
case XK_Control_R: key = JTK_KEY_CTRL_R; break;
|
||||
case XK_Caps_Lock: key = JTK_KEY_CAPS_LOCK; break;
|
||||
case XK_Shift_Lock: key = JTK_KEY_SHIFT_LOCK;break;
|
||||
|
||||
case XK_Meta_L: event->key.key = JTK_KEY_META_L; break;
|
||||
case XK_Meta_R: event->key.key = JTK_KEY_META_R; break;
|
||||
case XK_Alt_L: event->key.key = JTK_KEY_ALT_L; break;
|
||||
case XK_Alt_R: event->key.key = JTK_KEY_ALT_R; break;
|
||||
case XK_Super_L: event->key.key = JTK_KEY_SUPER_L; break;
|
||||
case XK_Super_R: event->key.key = JTK_KEY_SUPER_R; break;
|
||||
case XK_Meta_L: key = JTK_KEY_META_L; break;
|
||||
case XK_Meta_R: key = JTK_KEY_META_R; break;
|
||||
case XK_Alt_L: key = JTK_KEY_ALT_L; break;
|
||||
case XK_Alt_R: key = JTK_KEY_ALT_R; break;
|
||||
case XK_Super_L: key = JTK_KEY_SUPER_L; break;
|
||||
case XK_Super_R: key = JTK_KEY_SUPER_R; break;
|
||||
|
||||
case XK_Home: event->key.key = JTK_KEY_HOME; break;
|
||||
case XK_Left: event->key.key = JTK_KEY_LEFT; break;
|
||||
case XK_Up: event->key.key = JTK_KEY_UP; break;
|
||||
case XK_Right: event->key.key = JTK_KEY_RIGHT; break;
|
||||
case XK_Down: event->key.key = JTK_KEY_DOWN; break;
|
||||
case XK_Page_Up: event->key.key = JTK_KEY_PAGE_UP; break;
|
||||
case XK_Page_Down: event->key.key = JTK_KEY_PAGE_DOWN; break;
|
||||
case XK_End: event->key.key = JTK_KEY_END; break;
|
||||
case XK_Begin: event->key.key = JTK_KEY_BEGIN; break;
|
||||
case XK_Home: key = JTK_KEY_HOME; break;
|
||||
case XK_Left: key = JTK_KEY_LEFT; break;
|
||||
case XK_Up: key = JTK_KEY_UP; break;
|
||||
case XK_Right: key = JTK_KEY_RIGHT; break;
|
||||
case XK_Down: key = JTK_KEY_DOWN; break;
|
||||
case XK_Page_Up: key = JTK_KEY_PAGE_UP; break;
|
||||
case XK_Page_Down: key = JTK_KEY_PAGE_DOWN; break;
|
||||
case XK_End: key = JTK_KEY_END; break;
|
||||
case XK_Begin: key = JTK_KEY_BEGIN; break;
|
||||
|
||||
case XK_Select: event->key.key = JTK_KEY_SELECT; break;
|
||||
case XK_Print: event->key.key = JTK_KEY_PRINT; break;
|
||||
case XK_Execute: event->key.key = JTK_KEY_EXECUTE; break;
|
||||
case XK_Insert: event->key.key = JTK_KEY_INSERT; break;
|
||||
case XK_Undo: event->key.key = JTK_KEY_UNDO; break;
|
||||
case XK_Redo: event->key.key = JTK_KEY_REDO; break;
|
||||
case XK_Menu: event->key.key = JTK_KEY_MENU; break;
|
||||
case XK_Find: event->key.key = JTK_KEY_FIND; break;
|
||||
case XK_Cancel: event->key.key = JTK_KEY_CANCEL; break;
|
||||
case XK_Help: event->key.key = JTK_KEY_HELP; break;
|
||||
case XK_Break: event->key.key = JTK_KEY_BREAK; break;
|
||||
case XK_Num_Lock: event->key.key = JTK_KEY_NUM_LOCK; break;
|
||||
case XK_Select: key = JTK_KEY_SELECT; break;
|
||||
case XK_Print: key = JTK_KEY_PRINT; break;
|
||||
case XK_Execute: key = JTK_KEY_EXECUTE; break;
|
||||
case XK_Insert: key = JTK_KEY_INSERT; break;
|
||||
case XK_Undo: key = JTK_KEY_UNDO; break;
|
||||
case XK_Redo: key = JTK_KEY_REDO; break;
|
||||
case XK_Menu: key = JTK_KEY_MENU; break;
|
||||
case XK_Find: key = JTK_KEY_FIND; break;
|
||||
case XK_Cancel: key = JTK_KEY_CANCEL; break;
|
||||
case XK_Help: key = JTK_KEY_HELP; break;
|
||||
case XK_Break: key = JTK_KEY_BREAK; break;
|
||||
case XK_Num_Lock: key = JTK_KEY_NUM_LOCK; break;
|
||||
|
||||
case XK_KP_Space: event->key.key = JTK_KEY_KP_SPACE; break;
|
||||
case XK_KP_Tab: event->key.key = JTK_KEY_KP_TAB; break;
|
||||
case XK_KP_Enter: event->key.key = JTK_KEY_KP_ENTER; break;
|
||||
case XK_KP_F1: event->key.key = JTK_KEY_KP_F1; break;
|
||||
case XK_KP_F2: event->key.key = JTK_KEY_KP_F2; break;
|
||||
case XK_KP_F3: event->key.key = JTK_KEY_KP_F3; break;
|
||||
case XK_KP_F4: event->key.key = JTK_KEY_KP_F4; break;
|
||||
case XK_KP_Home: event->key.key = JTK_KEY_KP_HOME; break;
|
||||
case XK_KP_Left: event->key.key = JTK_KEY_KP_LEFT; break;
|
||||
case XK_KP_Up: event->key.key = JTK_KEY_KP_UP; break;
|
||||
case XK_KP_Right: event->key.key = JTK_KEY_KP_RIGHT; break;
|
||||
case XK_KP_Down: event->key.key = JTK_KEY_KP_DOWN; break;
|
||||
case XK_KP_Page_Up: event->key.key = JTK_KEY_KP_PAGE_UP; break;
|
||||
case XK_KP_Page_Down: event->key.key = JTK_KEY_KP_PAGE_DOWN; break;
|
||||
case XK_KP_End: event->key.key = JTK_KEY_KP_END; break;
|
||||
case XK_KP_Begin: event->key.key = JTK_KEY_KP_BEGIN; break;
|
||||
case XK_KP_Insert: event->key.key = JTK_KEY_KP_INSERT; break;
|
||||
case XK_KP_Delete: event->key.key = JTK_KEY_KP_DELETE; break;
|
||||
case XK_KP_Equal: event->key.key = JTK_KEY_KP_EQUAL; break;
|
||||
case XK_KP_Multiply: event->key.key = JTK_KEY_KP_MULTIPLY; break;
|
||||
case XK_KP_Add: event->key.key = JTK_KEY_KP_ADD; break;
|
||||
case XK_KP_Separator: event->key.key = JTK_KEY_KP_SEPARATOR; break;
|
||||
case XK_KP_Subtract: event->key.key = JTK_KEY_KP_SUBTRACT; break;
|
||||
case XK_KP_Decimal: event->key.key = JTK_KEY_KP_DECIMAL; break;
|
||||
case XK_KP_Divide: event->key.key = JTK_KEY_KP_DIVIDE; break;
|
||||
case XK_KP_Space: key = JTK_KEY_KP_SPACE; break;
|
||||
case XK_KP_Tab: key = JTK_KEY_KP_TAB; break;
|
||||
case XK_KP_Enter: key = JTK_KEY_KP_ENTER; break;
|
||||
case XK_KP_F1: key = JTK_KEY_KP_F1; break;
|
||||
case XK_KP_F2: key = JTK_KEY_KP_F2; break;
|
||||
case XK_KP_F3: key = JTK_KEY_KP_F3; break;
|
||||
case XK_KP_F4: key = JTK_KEY_KP_F4; break;
|
||||
case XK_KP_Home: key = JTK_KEY_KP_HOME; break;
|
||||
case XK_KP_Left: key = JTK_KEY_KP_LEFT; break;
|
||||
case XK_KP_Up: key = JTK_KEY_KP_UP; break;
|
||||
case XK_KP_Right: key = JTK_KEY_KP_RIGHT; break;
|
||||
case XK_KP_Down: key = JTK_KEY_KP_DOWN; break;
|
||||
case XK_KP_Page_Up: key = JTK_KEY_KP_PAGE_UP; break;
|
||||
case XK_KP_Page_Down: key = JTK_KEY_KP_PAGE_DOWN; break;
|
||||
case XK_KP_End: key = JTK_KEY_KP_END; break;
|
||||
case XK_KP_Begin: key = JTK_KEY_KP_BEGIN; break;
|
||||
case XK_KP_Insert: key = JTK_KEY_KP_INSERT; break;
|
||||
case XK_KP_Delete: key = JTK_KEY_KP_DELETE; break;
|
||||
case XK_KP_Equal: key = JTK_KEY_KP_EQUAL; break;
|
||||
case XK_KP_Multiply: key = JTK_KEY_KP_MULTIPLY; break;
|
||||
case XK_KP_Add: key = JTK_KEY_KP_ADD; break;
|
||||
case XK_KP_Separator: key = JTK_KEY_KP_SEPARATOR; break;
|
||||
case XK_KP_Subtract: key = JTK_KEY_KP_SUBTRACT; break;
|
||||
case XK_KP_Decimal: key = JTK_KEY_KP_DECIMAL; break;
|
||||
case XK_KP_Divide: key = JTK_KEY_KP_DIVIDE; break;
|
||||
|
||||
case XK_KP_0: event->key.key = JTK_KEY_KP_0; break;
|
||||
case XK_KP_1: event->key.key = JTK_KEY_KP_1; break;
|
||||
case XK_KP_2: event->key.key = JTK_KEY_KP_2; break;
|
||||
case XK_KP_3: event->key.key = JTK_KEY_KP_3; break;
|
||||
case XK_KP_4: event->key.key = JTK_KEY_KP_4; break;
|
||||
case XK_KP_5: event->key.key = JTK_KEY_KP_5; break;
|
||||
case XK_KP_6: event->key.key = JTK_KEY_KP_6; break;
|
||||
case XK_KP_7: event->key.key = JTK_KEY_KP_7; break;
|
||||
case XK_KP_8: event->key.key = JTK_KEY_KP_8; break;
|
||||
case XK_KP_9: event->key.key = JTK_KEY_KP_9; break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
case XK_KP_0: key = JTK_KEY_KP_0; break;
|
||||
case XK_KP_1: key = JTK_KEY_KP_1; break;
|
||||
case XK_KP_2: key = JTK_KEY_KP_2; break;
|
||||
case XK_KP_3: key = JTK_KEY_KP_3; break;
|
||||
case XK_KP_4: key = JTK_KEY_KP_4; break;
|
||||
case XK_KP_5: key = JTK_KEY_KP_5; break;
|
||||
case XK_KP_6: key = JTK_KEY_KP_6; break;
|
||||
case XK_KP_7: key = JTK_KEY_KP_7; break;
|
||||
case XK_KP_8: key = JTK_KEY_KP_8; break;
|
||||
case XK_KP_9: key = JTK_KEY_KP_9; break;
|
||||
}
|
||||
}
|
||||
|
||||
/* OR in the modifier states */
|
||||
if (x_event->xkey.state & ShiftMask)
|
||||
if (g_x_state & ShiftMask)
|
||||
{
|
||||
event->key.key |= JTK_KEY_MODS_SHIFT;
|
||||
key |= JTK_KEY_MODS_SHIFT;
|
||||
}
|
||||
if (x_event->xkey.state & LockMask)
|
||||
if (g_x_state & LockMask)
|
||||
{
|
||||
event->key.key |= JTK_KEY_MODS_LOCK;
|
||||
key |= JTK_KEY_MODS_LOCK;
|
||||
}
|
||||
if (x_event->xkey.state & ControlMask)
|
||||
if (g_x_state & ControlMask)
|
||||
{
|
||||
event->key.key |= JTK_KEY_MODS_CTRL;
|
||||
key |= JTK_KEY_MODS_CTRL;
|
||||
}
|
||||
|
||||
return true;
|
||||
return key;
|
||||
}
|
||||
|
||||
static Bool KeyRepeatCheckIfEvent(Display * display, XEvent * chkev,
|
||||
@ -198,6 +210,44 @@ static bool IsRepeatKey(Display * display, XEvent * event)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an X key press event.
|
||||
*
|
||||
* @param x_event
|
||||
* Pointer to the X event.
|
||||
* @param event
|
||||
* Pointer to the Jtk event.
|
||||
*/
|
||||
static bool ProcessXKeyPressEvent(XEvent * x_event, Jtk_Event * event)
|
||||
{
|
||||
unsigned int x_keycode = x_event->xkey.keycode;
|
||||
g_x_state = x_event->xkey.state;
|
||||
event->type = JTK_EVENT_KEY_PRESS;
|
||||
event->key.repeat = false;
|
||||
event->key.key = XKeyToJtkKey(x_keycode);
|
||||
event->key.x_keycode = x_keycode;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an X key release event.
|
||||
*
|
||||
* @param x_event
|
||||
* Pointer to the X event.
|
||||
* @param event
|
||||
* Pointer to the Jtk event.
|
||||
*/
|
||||
static bool ProcessXKeyReleaseEvent(XEvent * x_event, Jtk_Event * event)
|
||||
{
|
||||
if (IsRepeatKey(g_display, x_event))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
g_x_state = x_event->xkey.state;
|
||||
StopKeyRepeat(x_event->xkey.keycode);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an X event.
|
||||
*
|
||||
@ -216,15 +266,10 @@ static bool ProcessXEvent(XEvent * x_event, Jtk_Event * event)
|
||||
switch (x_event->type)
|
||||
{
|
||||
case KeyPress:
|
||||
event->type = JTK_EVENT_KEY_PRESS;
|
||||
return ProcessXKeyEvent(x_event, event);
|
||||
return ProcessXKeyPressEvent(x_event, event);
|
||||
|
||||
case KeyRelease:
|
||||
if (IsRepeatKey(g_display, x_event)) {
|
||||
return false;
|
||||
}
|
||||
event->type = JTK_EVENT_KEY_RELEASE;
|
||||
return ProcessXKeyEvent(x_event, event);
|
||||
return ProcessXKeyReleaseEvent(x_event, event);
|
||||
|
||||
case ButtonPress:
|
||||
break;
|
||||
@ -251,10 +296,21 @@ void Jtk_WaitEvent(Jtk_Event * event)
|
||||
size_t timer_id = Jtk_GetExpiredTimer();
|
||||
if (timer_id != (size_t)-1)
|
||||
{
|
||||
event->type = JTK_EVENT_TIMER;
|
||||
event->timer.timer_id = timer_id;
|
||||
event->timer.user1 = Jtk_GetTimerUserData(timer_id, 0u);
|
||||
event->timer.user2 = Jtk_GetTimerUserData(timer_id, 1u);
|
||||
auto it = g_key_repeat_timers.find(timer_id);
|
||||
if (it != g_key_repeat_timers.end())
|
||||
{
|
||||
event->type = JTK_EVENT_KEY_PRESS;
|
||||
event->key.repeat = true;
|
||||
event->key.key = XKeyToJtkKey(it->second);
|
||||
event->key.x_keycode = it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
event->type = JTK_EVENT_TIMER;
|
||||
event->timer.timer_id = timer_id;
|
||||
event->timer.user1 = Jtk_GetTimerUserData(timer_id, 0u);
|
||||
event->timer.user2 = Jtk_GetTimerUserData(timer_id, 1u);
|
||||
}
|
||||
Jtk_ServiceTimer(timer_id);
|
||||
return;
|
||||
}
|
||||
@ -286,4 +342,12 @@ void Jtk_WaitEvent(Jtk_Event * event)
|
||||
}
|
||||
}
|
||||
|
||||
void Jtk_BeginKeyRepeat(Jtk_KeyEvent * key_event, uint32_t delay, uint32_t interval)
|
||||
{
|
||||
StopKeyRepeat(key_event->x_keycode);
|
||||
size_t timer_id = Jtk_AddTimer(delay, interval, nullptr, nullptr);
|
||||
g_repeating_keys[key_event->x_keycode] = timer_id;
|
||||
g_key_repeat_timers[timer_id] = key_event->x_keycode;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -14,7 +14,11 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool repeat;
|
||||
uint32_t key;
|
||||
#ifdef JTK_X
|
||||
unsigned int x_keycode;
|
||||
#endif
|
||||
} Jtk_KeyEvent;
|
||||
|
||||
typedef struct
|
||||
@ -41,5 +45,6 @@ typedef struct
|
||||
} Jtk_Event;
|
||||
|
||||
void Jtk_WaitEvent(Jtk_Event * event);
|
||||
void Jtk_BeginKeyRepeat(Jtk_KeyEvent * key_event, uint32_t delay, uint32_t interval);
|
||||
|
||||
#endif
|
||||
|
@ -115,4 +115,6 @@
|
||||
#define JTK_KEY_KP_8 0x00FF0078u
|
||||
#define JTK_KEY_KP_9 0x00FF0079u
|
||||
|
||||
#define JTK_KEY_UNKNOWN 0x00FFFFFFu
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user