libui/unix/keyboard.h

131 lines
3.4 KiB
C

#pragma once
#include "uipriv_unix.h"
static guint translateModifiers(guint state, GdkWindow *window)
{
GdkModifierType statetype;
// GDK doesn't initialize the modifier flags fully; we have to explicitly tell it to (thanks to Daniel_S and daniels (two different people) in irc.gimp.net/#gtk+)
statetype = state;
gdk_keymap_add_virtual_modifiers(
gdk_keymap_get_for_display(gdk_window_get_display(window)),
&statetype);
return statetype;
}
static uiModifiers toModifiers(guint state)
{
uiModifiers m;
m = 0;
if ((state & GDK_CONTROL_MASK) != 0)
m |= uiModifierCtrl;
if ((state & GDK_META_MASK) != 0)
m |= uiModifierAlt;
if ((state & GDK_MOD1_MASK) != 0) // GTK+ itself requires this to be Alt (just read through gtkaccelgroup.c)
m |= uiModifierAlt;
if ((state & GDK_SHIFT_MASK) != 0)
m |= uiModifierShift;
if ((state & GDK_SUPER_MASK) != 0)
m |= uiModifierSuper;
return m;
}
// we use GDK_KEY_Print as a sentinel because libui will never support the print screen key; that key belongs to the user
static const struct {
guint keyval;
uiExtKey extkey;
} extKeys[] = {
{ GDK_KEY_Escape, uiExtKeyEscape },
{ GDK_KEY_Insert, uiExtKeyInsert },
{ GDK_KEY_Delete, uiExtKeyDelete },
{ GDK_KEY_Home, uiExtKeyHome },
{ GDK_KEY_End, uiExtKeyEnd },
{ GDK_KEY_Page_Up, uiExtKeyPageUp },
{ GDK_KEY_Page_Down, uiExtKeyPageDown },
{ GDK_KEY_Up, uiExtKeyUp },
{ GDK_KEY_Down, uiExtKeyDown },
{ GDK_KEY_Left, uiExtKeyLeft },
{ GDK_KEY_Right, uiExtKeyRight },
{ GDK_KEY_F1, uiExtKeyF1 },
{ GDK_KEY_F2, uiExtKeyF2 },
{ GDK_KEY_F3, uiExtKeyF3 },
{ GDK_KEY_F4, uiExtKeyF4 },
{ GDK_KEY_F5, uiExtKeyF5 },
{ GDK_KEY_F6, uiExtKeyF6 },
{ GDK_KEY_F7, uiExtKeyF7 },
{ GDK_KEY_F8, uiExtKeyF8 },
{ GDK_KEY_F9, uiExtKeyF9 },
{ GDK_KEY_F10, uiExtKeyF10 },
{ GDK_KEY_F11, uiExtKeyF11 },
{ GDK_KEY_F12, uiExtKeyF12 },
// numpad numeric keys and . are handled in events.c
{ GDK_KEY_KP_Enter, uiExtKeyNEnter },
{ GDK_KEY_KP_Add, uiExtKeyNAdd },
{ GDK_KEY_KP_Subtract, uiExtKeyNSubtract },
{ GDK_KEY_KP_Multiply, uiExtKeyNMultiply },
{ GDK_KEY_KP_Divide, uiExtKeyNDivide },
{ GDK_KEY_Print, 0 },
};
static const struct {
guint keyval;
uiModifiers mod;
} modKeys[] = {
{ GDK_KEY_Control_L, uiModifierCtrl },
{ GDK_KEY_Control_R, uiModifierCtrl },
{ GDK_KEY_Alt_L, uiModifierAlt },
{ GDK_KEY_Alt_R, uiModifierAlt },
{ GDK_KEY_Meta_L, uiModifierAlt },
{ GDK_KEY_Meta_R, uiModifierAlt },
{ GDK_KEY_Shift_L, uiModifierShift },
{ GDK_KEY_Shift_R, uiModifierShift },
{ GDK_KEY_Super_L, uiModifierSuper },
{ GDK_KEY_Super_R, uiModifierSuper },
{ GDK_KEY_Print, 0 },
};
static gboolean fillUiKeyEvent(uiAreaKeyEvent *ke, GdkEventKey *e)
{
guint state;
int i;
ke->Key = 0;
ke->ExtKey = 0;
ke->Modifier = 0;
state = translateModifiers(e->state, e->window);
ke->Modifiers = toModifiers(state);
for (i = 0; extKeys[i].keyval != GDK_KEY_Print; i++)
if (extKeys[i].keyval == e->keyval) {
ke->ExtKey = extKeys[i].extkey;
goto keyFound;
}
for (i = 0; modKeys[i].keyval != GDK_KEY_Print; i++)
if (modKeys[i].keyval == e->keyval) {
ke->Modifier = modKeys[i].mod;
// don't include the modifier in ke->Modifiers
ke->Modifiers &= ~ke->Modifier;
goto keyFound;
}
if (uiprivFromScancode(e->hardware_keycode - 8, ke))
goto keyFound;
// no supported key found; treat as unhandled
return FALSE;
keyFound:
ke->Up = 0;
if (e->type == GDK_KEY_PRESS)
ke->Up = 1;
return TRUE;
}