Merge pull request #1 from RustamGamidov/entry_keyEvent
entry. handle key event
This commit is contained in:
commit
cd3f9d29a2
|
@ -11,7 +11,6 @@
|
|||
BOOL libui_enabled;
|
||||
}
|
||||
- (id)initWithFrame:(NSRect)r area:(uiArea *)a;
|
||||
- (uiModifiers)parseModifiers:(NSEvent *)e;
|
||||
- (void)doMouseEvent:(NSEvent *)e;
|
||||
- (int)sendKeyEvent:(uiAreaKeyEvent *)ke;
|
||||
- (int)doKeyDownUp:(NSEvent *)e up:(int)up;
|
||||
|
@ -87,24 +86,6 @@ struct uiArea {
|
|||
return YES;
|
||||
}
|
||||
|
||||
- (uiModifiers)parseModifiers:(NSEvent *)e
|
||||
{
|
||||
NSEventModifierFlags mods;
|
||||
uiModifiers m;
|
||||
|
||||
m = 0;
|
||||
mods = [e modifierFlags];
|
||||
if ((mods & NSControlKeyMask) != 0)
|
||||
m |= uiModifierCtrl;
|
||||
if ((mods & NSAlternateKeyMask) != 0)
|
||||
m |= uiModifierAlt;
|
||||
if ((mods & NSShiftKeyMask) != 0)
|
||||
m |= uiModifierShift;
|
||||
if ((mods & NSCommandKeyMask) != 0)
|
||||
m |= uiModifierSuper;
|
||||
return m;
|
||||
}
|
||||
|
||||
- (void)setupNewTrackingArea
|
||||
{
|
||||
self->libui_ta = [[NSTrackingArea alloc] initWithRect:[self bounds]
|
||||
|
@ -178,7 +159,7 @@ struct uiArea {
|
|||
break;
|
||||
}
|
||||
|
||||
me.Modifiers = [self parseModifiers:e];
|
||||
me.Modifiers = parseModifiers(e);
|
||||
|
||||
pmb = [NSEvent pressedMouseButtons];
|
||||
me.Held1To64 = 0;
|
||||
|
@ -260,7 +241,7 @@ mouseEvent(otherMouseUp)
|
|||
ke.ExtKey = 0;
|
||||
ke.Modifier = 0;
|
||||
|
||||
ke.Modifiers = [self parseModifiers:e];
|
||||
ke.Modifiers = parseModifiers(e);
|
||||
|
||||
ke.Up = up;
|
||||
|
||||
|
@ -292,7 +273,7 @@ mouseEvent(otherMouseUp)
|
|||
if (!uiprivKeycodeModifier([e keyCode], &whichmod))
|
||||
return 0;
|
||||
ke.Modifier = whichmod;
|
||||
ke.Modifiers = [self parseModifiers:e];
|
||||
ke.Modifiers = parseModifiers(e);
|
||||
ke.Up = (ke.Modifiers & ke.Modifier) == 0;
|
||||
// and then drop the current modifier from Modifiers
|
||||
ke.Modifiers &= ~ke.Modifier;
|
||||
|
|
|
@ -157,3 +157,21 @@ BOOL uiprivKeycodeModifier(unsigned short keycode, uiModifiers *mod)
|
|||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
uiModifiers parseModifiers(NSEvent *e)
|
||||
{
|
||||
NSEventModifierFlags mods;
|
||||
uiModifiers m;
|
||||
|
||||
m = 0;
|
||||
mods = [e modifierFlags];
|
||||
if ((mods & NSControlKeyMask) != 0)
|
||||
m |= uiModifierCtrl;
|
||||
if ((mods & NSAlternateKeyMask) != 0)
|
||||
m |= uiModifierAlt;
|
||||
if ((mods & NSShiftKeyMask) != 0)
|
||||
m |= uiModifierShift;
|
||||
if ((mods & NSCommandKeyMask) != 0)
|
||||
m |= uiModifierSuper;
|
||||
return m;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ struct uiEntry {
|
|||
NSTextField *textfield;
|
||||
void (*onChanged)(uiEntry *, void *);
|
||||
void *onChangedData;
|
||||
int (*onKeyEvent)(uiEntry *, uiAreaKeyEvent *);
|
||||
};
|
||||
|
||||
static BOOL isSearchField(NSTextField *tf)
|
||||
|
@ -66,8 +67,19 @@ static BOOL isSearchField(NSTextField *tf)
|
|||
return [tf isKindOfClass:[NSSearchField class]];
|
||||
}
|
||||
|
||||
static void triggerOnKeyEvent(void *key, void *e, void *data)
|
||||
{
|
||||
uiEntry *entry = (uiEntry *)e;
|
||||
void *firstResponder = [entry->textfield window].firstResponder;
|
||||
BOOL sameObj = (entry->textfield == firstResponder);
|
||||
BOOL currentEditor = (entry->textfield.currentEditor && entry->textfield.currentEditor == firstResponder);
|
||||
if (sameObj || currentEditor)
|
||||
entry->onKeyEvent(entry, data);
|
||||
}
|
||||
|
||||
@interface entryDelegateClass : NSObject<NSTextFieldDelegate> {
|
||||
uiprivMap *entries;
|
||||
id eventMonitor;
|
||||
}
|
||||
- (void)controlTextDidChange:(NSNotification *)note;
|
||||
- (IBAction)onSearch:(id)sender;
|
||||
|
@ -82,11 +94,28 @@ static BOOL isSearchField(NSTextField *tf)
|
|||
self = [super init];
|
||||
if (self)
|
||||
self->entries = uiprivNewMap();
|
||||
|
||||
NSEvent* (^eventHandler)(NSEvent*) = ^(NSEvent *theEvent) {
|
||||
uiAreaKeyEvent ke;
|
||||
ke.Key = 0;
|
||||
ke.ExtKey = 0;
|
||||
ke.Modifier = 0;
|
||||
ke.Modifiers = parseModifiers(theEvent);
|
||||
ke.Up = ([theEvent type] == NSKeyUp ? 1 : 0);
|
||||
|
||||
if (uiprivFromKeycode([theEvent keyCode], &ke))
|
||||
uiprivMapWalkWithData(self->entries, &ke, triggerOnKeyEvent);
|
||||
|
||||
return theEvent;
|
||||
};
|
||||
eventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:(NSKeyDownMask | NSKeyUpMask) handler:eventHandler];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[NSEvent removeMonitor:eventMonitor];
|
||||
uiprivMapDestroy(self->entries);
|
||||
[super dealloc];
|
||||
}
|
||||
|
@ -155,6 +184,11 @@ void uiEntryOnChanged(uiEntry *e, void (*f)(uiEntry *, void *), void *data)
|
|||
e->onChangedData = data;
|
||||
}
|
||||
|
||||
void uiEntryOnKeyEvent(uiEntry *e, int (*f)(uiEntry *, uiAreaKeyEvent *))
|
||||
{
|
||||
e->onKeyEvent = f;
|
||||
}
|
||||
|
||||
int uiEntryReadOnly(uiEntry *e)
|
||||
{
|
||||
return [e->textfield isEditable] == NO;
|
||||
|
@ -175,6 +209,12 @@ static void defaultOnChanged(uiEntry *e, void *data)
|
|||
// do nothing
|
||||
}
|
||||
|
||||
static int defaultOnKeyEvent(uiEntry *e, uiAreaKeyEvent *ke)
|
||||
{
|
||||
// do nothing
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// these are based on interface builder defaults; my comments in the old code weren't very good so I don't really know what talked about what, sorry :/
|
||||
void uiprivFinishNewTextField(NSTextField *t, BOOL isEntry)
|
||||
{
|
||||
|
@ -220,6 +260,7 @@ static uiEntry *finishNewEntry(Class class)
|
|||
}
|
||||
[entryDelegate registerEntry:e];
|
||||
uiEntryOnChanged(e, defaultOnChanged, NULL);
|
||||
uiEntryOnKeyEvent(e, defaultOnKeyEvent);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
|
14
darwin/map.m
14
darwin/map.m
|
@ -55,6 +55,20 @@ void uiprivMapWalk(uiprivMap *m, void (*f)(void *key, void *value))
|
|||
NSEndMapTableEnumeration(&e);
|
||||
}
|
||||
|
||||
void uiprivMapWalkWithData(uiprivMap *m, void *data, void (*f)(void *key, void *value, void *data))
|
||||
{
|
||||
NSMapEnumerator e;
|
||||
void *k, *v;
|
||||
|
||||
e = NSEnumerateMapTable(m->m);
|
||||
k = NULL;
|
||||
v = NULL;
|
||||
while (NSNextMapEnumeratorPair(&e, &k, &v))
|
||||
f(k, v, data);
|
||||
NSEndMapTableEnumeration(&e);
|
||||
}
|
||||
|
||||
|
||||
void uiprivMapReset(uiprivMap *m)
|
||||
{
|
||||
NSResetMapTable(m->m);
|
||||
|
|
|
@ -31,6 +31,7 @@ extern void *uiprivMapGet(uiprivMap *m, void *key);
|
|||
extern void uiprivMapSet(uiprivMap *m, void *key, void *value);
|
||||
extern void uiprivMapDelete(uiprivMap *m, void *key);
|
||||
extern void uiprivMapWalk(uiprivMap *m, void (*f)(void *key, void *value));
|
||||
extern void uiprivMapWalkWithData(uiprivMap *m, void *data, void (*f)(void *key, void *value, void *data));
|
||||
extern void uiprivMapReset(uiprivMap *m);
|
||||
|
||||
// menu.m
|
||||
|
@ -110,6 +111,7 @@ extern int uiprivSendAreaEvents(NSEvent *);
|
|||
// areaevents.m
|
||||
extern BOOL uiprivFromKeycode(unsigned short keycode, uiAreaKeyEvent *ke);
|
||||
extern BOOL uiprivKeycodeModifier(unsigned short keycode, uiModifiers *mod);
|
||||
extern uiModifiers parseModifiers(NSEvent *e);
|
||||
|
||||
// draw.m
|
||||
extern uiDrawContext *uiprivDrawNewContext(CGContextRef, CGFloat);
|
||||
|
|
12
ui.h
12
ui.h
|
@ -45,6 +45,12 @@ _UI_ENUM(uiForEach) {
|
|||
uiForEachStop,
|
||||
};
|
||||
|
||||
typedef struct uiArea uiArea;
|
||||
typedef struct uiAreaHandler uiAreaHandler;
|
||||
typedef struct uiAreaDrawParams uiAreaDrawParams;
|
||||
typedef struct uiAreaMouseEvent uiAreaMouseEvent;
|
||||
typedef struct uiAreaKeyEvent uiAreaKeyEvent;
|
||||
|
||||
typedef struct uiInitOptions uiInitOptions;
|
||||
|
||||
struct uiInitOptions {
|
||||
|
@ -162,6 +168,7 @@ typedef struct uiEntry uiEntry;
|
|||
_UI_EXTERN char *uiEntryText(uiEntry *e);
|
||||
_UI_EXTERN void uiEntrySetText(uiEntry *e, const char *text);
|
||||
_UI_EXTERN void uiEntryOnChanged(uiEntry *e, void (*f)(uiEntry *e, void *data), void *data);
|
||||
_UI_EXTERN void uiEntryOnKeyEvent(uiEntry *e, int (*f)(uiEntry *e, uiAreaKeyEvent *event));
|
||||
_UI_EXTERN int uiEntryReadOnly(uiEntry *e);
|
||||
_UI_EXTERN void uiEntrySetReadOnly(uiEntry *e, int readonly);
|
||||
_UI_EXTERN uiEntry *uiNewEntry(void);
|
||||
|
@ -297,11 +304,6 @@ _UI_EXTERN char *uiSaveFile(uiWindow *parent);
|
|||
_UI_EXTERN void uiMsgBox(uiWindow *parent, const char *title, const char *description);
|
||||
_UI_EXTERN void uiMsgBoxError(uiWindow *parent, const char *title, const char *description);
|
||||
|
||||
typedef struct uiArea uiArea;
|
||||
typedef struct uiAreaHandler uiAreaHandler;
|
||||
typedef struct uiAreaDrawParams uiAreaDrawParams;
|
||||
typedef struct uiAreaMouseEvent uiAreaMouseEvent;
|
||||
typedef struct uiAreaKeyEvent uiAreaKeyEvent;
|
||||
|
||||
typedef struct uiDrawContext uiDrawContext;
|
||||
|
||||
|
|
124
unix/area.c
124
unix/area.c
|
@ -1,5 +1,6 @@
|
|||
// 4 september 2015
|
||||
#include "uipriv_unix.h"
|
||||
#include "keyboard.h"
|
||||
|
||||
// notes:
|
||||
// - G_DECLARE_DERIVABLE/FINAL_INTERFACE() requires glib 2.44 and that's starting with debian stretch (testing) (GTK+ 3.18) and ubuntu 15.04 (GTK+ 3.14) - debian jessie has 2.42 (GTK+ 3.14)
|
||||
|
@ -170,36 +171,6 @@ static void areaWidget_get_preferred_width(GtkWidget *w, gint *min, gint *nat)
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// capture on drag is done automatically on GTK+
|
||||
static void finishMouseEvent(uiArea *a, uiAreaMouseEvent *me, guint mb, gdouble x, gdouble y, guint state, GdkWindow *window)
|
||||
{
|
||||
|
@ -326,99 +297,14 @@ static gboolean areaWidget_leave_notify_event(GtkWidget *w, GdkEventCrossing *e)
|
|||
// note: there is no equivalent to WM_CAPTURECHANGED on GTK+; there literally is no way to break a grab like that (at least not on X11 and Wayland)
|
||||
// even if I invoke the task switcher and switch processes, the mouse grab will still be held until I let go of all buttons
|
||||
// therefore, no DragBroken()
|
||||
|
||||
// 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 int areaKeyEvent(uiArea *a, int up, GdkEventKey *e)
|
||||
{
|
||||
uiAreaKeyEvent ke;
|
||||
guint state;
|
||||
int i;
|
||||
|
||||
ke.Key = 0;
|
||||
ke.ExtKey = 0;
|
||||
ke.Modifier = 0;
|
||||
|
||||
state = translateModifiers(e->state, e->window);
|
||||
ke.Modifiers = toModifiers(state);
|
||||
|
||||
ke.Up = up;
|
||||
|
||||
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
|
||||
if (fillUiKeyEvent(&ke, e)) {
|
||||
ke.Up = up;
|
||||
return (*(a->ah->KeyEvent))(a->ah, a, &ke);
|
||||
}
|
||||
return 0;
|
||||
|
||||
keyFound:
|
||||
return (*(a->ah->KeyEvent))(a->ah, a, &ke);
|
||||
}
|
||||
|
||||
static gboolean areaWidget_key_press_event(GtkWidget *w, GdkEventKey *e)
|
||||
|
|
28
unix/entry.c
28
unix/entry.c
|
@ -1,5 +1,6 @@
|
|||
// 11 june 2015
|
||||
#include "uipriv_unix.h"
|
||||
#include "keyboard.h"
|
||||
|
||||
struct uiEntry {
|
||||
uiUnixControl c;
|
||||
|
@ -9,6 +10,7 @@ struct uiEntry {
|
|||
void (*onChanged)(uiEntry *, void *);
|
||||
void *onChangedData;
|
||||
gulong onChangedSignal;
|
||||
int (*onKeyEvent)(uiEntry *, uiAreaKeyEvent *);
|
||||
};
|
||||
|
||||
uiUnixControlAllDefaults(uiEntry)
|
||||
|
@ -25,6 +27,22 @@ static void defaultOnChanged(uiEntry *e, void *data)
|
|||
// do nothing
|
||||
}
|
||||
|
||||
static gboolean onKeyEvent(GtkEditable *editable, GdkEventKey *event, gpointer data)
|
||||
{
|
||||
uiEntry *e = (uiEntry*)(data);
|
||||
uiAreaKeyEvent ke;
|
||||
if (fillUiKeyEvent(&ke, event))
|
||||
return (*(e->onKeyEvent))(e, &ke);
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static int defaultOnKeyEvent(uiEntry *e, uiAreaKeyEvent *uke)
|
||||
{
|
||||
// do nothing
|
||||
// return GDK_EVENT_STOP; // to stop further key handling
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
char *uiEntryText(uiEntry *e)
|
||||
{
|
||||
return uiUnixStrdupText(gtk_entry_get_text(e->entry));
|
||||
|
@ -45,6 +63,11 @@ void uiEntryOnChanged(uiEntry *e, void (*f)(uiEntry *, void *), void *data)
|
|||
e->onChangedData = data;
|
||||
}
|
||||
|
||||
void uiEntryOnKeyEvent(uiEntry *e, int (*f)(uiEntry *, uiAreaKeyEvent *))
|
||||
{
|
||||
e->onKeyEvent = f;
|
||||
}
|
||||
|
||||
int uiEntryReadOnly(uiEntry *e)
|
||||
{
|
||||
return gtk_editable_get_editable(e->editable) == FALSE;
|
||||
|
@ -73,6 +96,11 @@ static uiEntry *finishNewEntry(GtkWidget *w, const gchar *signal)
|
|||
e->onChangedSignal = g_signal_connect(e->widget, signal, G_CALLBACK(onChanged), e);
|
||||
uiEntryOnChanged(e, defaultOnChanged, NULL);
|
||||
|
||||
gtk_widget_add_events(e->widget, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
|
||||
g_signal_connect(e->widget, "key_press_event", G_CALLBACK(onKeyEvent), e);
|
||||
g_signal_connect(e->widget, "key_release_event", G_CALLBACK(onKeyEvent), e);
|
||||
uiEntryOnKeyEvent(e, defaultOnKeyEvent);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
#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;
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
// 22 april 2015
|
||||
#pragma once
|
||||
#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_40
|
||||
#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_40
|
||||
#define GDK_VERSION_MIN_REQUIRED GDK_VERSION_3_10
|
||||
|
|
|
@ -1,26 +1,10 @@
|
|||
// 8 september 2015
|
||||
#include "uipriv_windows.hpp"
|
||||
#include "area.hpp"
|
||||
#include "keyboard.hpp"
|
||||
|
||||
// TODO https://github.com/Microsoft/Windows-classic-samples/blob/master/Samples/Win7Samples/multimedia/DirectWrite/PadWrite/TextEditor.cpp notes on explicit RTL handling under MirrorXCoordinate(); also in areadraw.cpp too?
|
||||
|
||||
static uiModifiers getModifiers(void)
|
||||
{
|
||||
uiModifiers m = 0;
|
||||
|
||||
if ((GetKeyState(VK_CONTROL) & 0x80) != 0)
|
||||
m |= uiModifierCtrl;
|
||||
if ((GetKeyState(VK_MENU) & 0x80) != 0)
|
||||
m |= uiModifierAlt;
|
||||
if ((GetKeyState(VK_SHIFT) & 0x80) != 0)
|
||||
m |= uiModifierShift;
|
||||
if ((GetKeyState(VK_LWIN) & 0x80) != 0)
|
||||
m |= uiModifierSuper;
|
||||
if ((GetKeyState(VK_RWIN) & 0x80) != 0)
|
||||
m |= uiModifierSuper;
|
||||
return m;
|
||||
}
|
||||
|
||||
/*
|
||||
Windows doesn't natively support mouse crossing events.
|
||||
|
||||
|
@ -177,81 +161,6 @@ static void onMouseLeft(uiArea *a)
|
|||
uiprivClickCounterReset(&(a->cc));
|
||||
}
|
||||
|
||||
// we use VK_SNAPSHOT as a sentinel because libui will never support the print screen key; that key belongs to the user
|
||||
struct extkeymap {
|
||||
WPARAM vk;
|
||||
uiExtKey extkey;
|
||||
};
|
||||
|
||||
// all mappings come from GLFW - https://github.com/glfw/glfw/blob/master/src/win32_window.c#L152
|
||||
static const struct extkeymap numpadExtKeys[] = {
|
||||
{ VK_HOME, uiExtKeyN7 },
|
||||
{ VK_UP, uiExtKeyN8 },
|
||||
{ VK_PRIOR, uiExtKeyN9 },
|
||||
{ VK_LEFT, uiExtKeyN4 },
|
||||
{ VK_CLEAR, uiExtKeyN5 },
|
||||
{ VK_RIGHT, uiExtKeyN6 },
|
||||
{ VK_END, uiExtKeyN1 },
|
||||
{ VK_DOWN, uiExtKeyN2 },
|
||||
{ VK_NEXT, uiExtKeyN3 },
|
||||
{ VK_INSERT, uiExtKeyN0 },
|
||||
{ VK_DELETE, uiExtKeyNDot },
|
||||
{ VK_SNAPSHOT, 0 },
|
||||
};
|
||||
|
||||
static const struct extkeymap extKeys[] = {
|
||||
{ VK_ESCAPE, uiExtKeyEscape },
|
||||
{ VK_INSERT, uiExtKeyInsert },
|
||||
{ VK_DELETE, uiExtKeyDelete },
|
||||
{ VK_HOME, uiExtKeyHome },
|
||||
{ VK_END, uiExtKeyEnd },
|
||||
{ VK_PRIOR, uiExtKeyPageUp },
|
||||
{ VK_NEXT, uiExtKeyPageDown },
|
||||
{ VK_UP, uiExtKeyUp },
|
||||
{ VK_DOWN, uiExtKeyDown },
|
||||
{ VK_LEFT, uiExtKeyLeft },
|
||||
{ VK_RIGHT, uiExtKeyRight },
|
||||
{ VK_F1, uiExtKeyF1 },
|
||||
{ VK_F2, uiExtKeyF2 },
|
||||
{ VK_F3, uiExtKeyF3 },
|
||||
{ VK_F4, uiExtKeyF4 },
|
||||
{ VK_F5, uiExtKeyF5 },
|
||||
{ VK_F6, uiExtKeyF6 },
|
||||
{ VK_F7, uiExtKeyF7 },
|
||||
{ VK_F8, uiExtKeyF8 },
|
||||
{ VK_F9, uiExtKeyF9 },
|
||||
{ VK_F10, uiExtKeyF10 },
|
||||
{ VK_F11, uiExtKeyF11 },
|
||||
{ VK_F12, uiExtKeyF12 },
|
||||
// numpad numeric keys and . are handled in common/areaevents.c
|
||||
// numpad enter is handled in code below
|
||||
{ VK_ADD, uiExtKeyNAdd },
|
||||
{ VK_SUBTRACT, uiExtKeyNSubtract },
|
||||
{ VK_MULTIPLY, uiExtKeyNMultiply },
|
||||
{ VK_DIVIDE, uiExtKeyNDivide },
|
||||
{ VK_SNAPSHOT, 0 },
|
||||
};
|
||||
|
||||
static const struct {
|
||||
WPARAM vk;
|
||||
uiModifiers mod;
|
||||
} modKeys[] = {
|
||||
// even if the separate left/right aren't necessary, have them here anyway, just to be safe
|
||||
{ VK_CONTROL, uiModifierCtrl },
|
||||
{ VK_LCONTROL, uiModifierCtrl },
|
||||
{ VK_RCONTROL, uiModifierCtrl },
|
||||
{ VK_MENU, uiModifierAlt },
|
||||
{ VK_LMENU, uiModifierAlt },
|
||||
{ VK_RMENU, uiModifierAlt },
|
||||
{ VK_SHIFT, uiModifierShift },
|
||||
{ VK_LSHIFT, uiModifierShift },
|
||||
{ VK_RSHIFT, uiModifierShift },
|
||||
// there's no combined Windows key virtual-key code as there is with the others
|
||||
{ VK_LWIN, uiModifierSuper },
|
||||
{ VK_RWIN, uiModifierSuper },
|
||||
{ VK_SNAPSHOT, 0 },
|
||||
};
|
||||
|
||||
static int areaKeyEvent(uiArea *a, int up, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
uiAreaKeyEvent ke;
|
||||
|
@ -261,9 +170,7 @@ static int areaKeyEvent(uiArea *a, int up, WPARAM wParam, LPARAM lParam)
|
|||
ke.Key = 0;
|
||||
ke.ExtKey = 0;
|
||||
ke.Modifier = 0;
|
||||
|
||||
ke.Modifiers = getModifiers();
|
||||
|
||||
ke.Up = up;
|
||||
|
||||
// the numeric keypad keys when Num Lock is off are considered left-hand keys as the separate navigation buttons were added later
|
||||
|
@ -282,25 +189,7 @@ static int areaKeyEvent(uiArea *a, int up, WPARAM wParam, LPARAM lParam)
|
|||
goto keyFound;
|
||||
}
|
||||
|
||||
// okay, those above cases didn't match anything
|
||||
// first try the extended keys
|
||||
for (i = 0; extKeys[i].vk != VK_SNAPSHOT; i++)
|
||||
if (extKeys[i].vk == wParam) {
|
||||
ke.ExtKey = extKeys[i].extkey;
|
||||
goto keyFound;
|
||||
}
|
||||
|
||||
// then try modifier keys
|
||||
for (i = 0; modKeys[i].vk != VK_SNAPSHOT; i++)
|
||||
if (modKeys[i].vk == wParam) {
|
||||
ke.Modifier = modKeys[i].mod;
|
||||
// and don't include the key in Modifiers
|
||||
ke.Modifiers &= ~ke.Modifier;
|
||||
goto keyFound;
|
||||
}
|
||||
|
||||
// and finally everything else
|
||||
if (uiprivFromScancode((lParam >> 16) & 0xFF, &ke))
|
||||
if (fillKeyEvent(ke, wParam, lParam))
|
||||
goto keyFound;
|
||||
|
||||
// not a supported key, assume unhandled
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// 8 april 2015
|
||||
#include "uipriv_windows.hpp"
|
||||
#include "keyboard.hpp"
|
||||
|
||||
struct uiEntry {
|
||||
uiWindowsControl c;
|
||||
|
@ -7,8 +8,46 @@ struct uiEntry {
|
|||
void (*onChanged)(uiEntry *, void *);
|
||||
void *onChangedData;
|
||||
BOOL inhibitChanged;
|
||||
int (*onKeyEvent)(uiEntry *, uiAreaKeyEvent *);
|
||||
void *self;
|
||||
WNDPROC native_wndproc;
|
||||
};
|
||||
|
||||
|
||||
static LRESULT CALLBACK entryWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
BOOL righthand = FALSE;
|
||||
uiAreaKeyEvent ke;
|
||||
ke.Key = 0;
|
||||
ke.ExtKey = 0;
|
||||
ke.Modifier = 0;
|
||||
ke.Modifiers = getModifiers();
|
||||
ke.Up = 0;
|
||||
|
||||
int (*onKeyEvent)(uiEntry *, uiAreaKeyEvent *) = (int (*)(uiEntry *, uiAreaKeyEvent *))GetProp(hwnd, L"ON_KEY_EVENT");
|
||||
uiEntry *self = (uiEntry *)GetProp(hwnd, L"SELF");
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_GETDLGCODE:
|
||||
return DLGC_HASSETSEL | DLGC_WANTALLKEYS;
|
||||
break;
|
||||
case WM_KEYUP:
|
||||
ke.Up = 1;
|
||||
case WM_KEYDOWN:
|
||||
if (onKeyEvent) {
|
||||
fillKeyEvent(ke, wParam, lParam);
|
||||
if ((*onKeyEvent)(self, &ke)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
WNDPROC native_wndproc = (WNDPROC)GetProp(hwnd, L"NATIVE_WNDPROC");
|
||||
return CallWindowProcW(native_wndproc, hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult)
|
||||
{
|
||||
uiEntry *e = uiEntry(c);
|
||||
|
@ -26,6 +65,11 @@ static void uiEntryDestroy(uiControl *c)
|
|||
{
|
||||
uiEntry *e = uiEntry(c);
|
||||
|
||||
(WNDPROC)SetWindowLongPtrW(e->hwnd, GWLP_WNDPROC, (LONG_PTR)e->native_wndproc);
|
||||
RemoveProp(e->hwnd, L"NATIVE_WNDPROC");
|
||||
RemoveProp(e->hwnd, L"ON_KEY_EVENT");
|
||||
RemoveProp(e->hwnd, L"SELF");
|
||||
|
||||
uiWindowsUnregisterWM_COMMANDHandler(e->hwnd);
|
||||
uiWindowsEnsureDestroyWindow(e->hwnd);
|
||||
uiFreeControl(uiControl(e));
|
||||
|
@ -56,6 +100,13 @@ static void defaultOnChanged(uiEntry *e, void *data)
|
|||
// do nothing
|
||||
}
|
||||
|
||||
static int defaultOnKeyEvent(uiEntry *e, uiAreaKeyEvent *event)
|
||||
{
|
||||
// do nothing
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
char *uiEntryText(uiEntry *e)
|
||||
{
|
||||
return uiWindowsWindowText(e->hwnd);
|
||||
|
@ -76,6 +127,12 @@ void uiEntryOnChanged(uiEntry *e, void (*f)(uiEntry *, void *), void *data)
|
|||
e->onChangedData = data;
|
||||
}
|
||||
|
||||
void uiEntryOnKeyEvent(uiEntry *e, int (*f)(uiEntry *, uiAreaKeyEvent *))
|
||||
{
|
||||
e->onKeyEvent = f;
|
||||
SetProp(e->hwnd, L"ON_KEY_EVENT", (HGLOBAL)(f));
|
||||
}
|
||||
|
||||
int uiEntryReadOnly(uiEntry *e)
|
||||
{
|
||||
return (getStyle(e->hwnd) & ES_READONLY) != 0;
|
||||
|
@ -105,7 +162,13 @@ static uiEntry *finishNewEntry(DWORD style)
|
|||
TRUE);
|
||||
|
||||
uiWindowsRegisterWM_COMMANDHandler(e->hwnd, onWM_COMMAND, uiControl(e));
|
||||
|
||||
e->native_wndproc = (WNDPROC)SetWindowLongPtrW(e->hwnd, GWLP_WNDPROC, (LONG_PTR)entryWndProc);
|
||||
SetProp(e->hwnd, L"NATIVE_WNDPROC", (HGLOBAL)e->native_wndproc);
|
||||
SetProp(e->hwnd, L"SELF", (HGLOBAL)e);
|
||||
|
||||
uiEntryOnChanged(e, defaultOnChanged, NULL);
|
||||
uiEntryOnKeyEvent(e, defaultOnKeyEvent);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
#pragma once
|
||||
|
||||
// we use VK_SNAPSHOT as a sentinel because libui will never support the print screen key; that key belongs to the user
|
||||
struct extkeymap {
|
||||
WPARAM vk;
|
||||
uiExtKey extkey;
|
||||
};
|
||||
|
||||
// all mappings come from GLFW - https://github.com/glfw/glfw/blob/master/src/win32_window.c#L152
|
||||
static const struct extkeymap numpadExtKeys[] = {
|
||||
{ VK_HOME, uiExtKeyN7 },
|
||||
{ VK_UP, uiExtKeyN8 },
|
||||
{ VK_PRIOR, uiExtKeyN9 },
|
||||
{ VK_LEFT, uiExtKeyN4 },
|
||||
{ VK_CLEAR, uiExtKeyN5 },
|
||||
{ VK_RIGHT, uiExtKeyN6 },
|
||||
{ VK_END, uiExtKeyN1 },
|
||||
{ VK_DOWN, uiExtKeyN2 },
|
||||
{ VK_NEXT, uiExtKeyN3 },
|
||||
{ VK_INSERT, uiExtKeyN0 },
|
||||
{ VK_DELETE, uiExtKeyNDot },
|
||||
{ VK_SNAPSHOT, 0 },
|
||||
};
|
||||
|
||||
static const struct extkeymap extKeys[] = {
|
||||
{ VK_ESCAPE, uiExtKeyEscape },
|
||||
{ VK_INSERT, uiExtKeyInsert },
|
||||
{ VK_DELETE, uiExtKeyDelete },
|
||||
{ VK_HOME, uiExtKeyHome },
|
||||
{ VK_END, uiExtKeyEnd },
|
||||
{ VK_PRIOR, uiExtKeyPageUp },
|
||||
{ VK_NEXT, uiExtKeyPageDown },
|
||||
{ VK_UP, uiExtKeyUp },
|
||||
{ VK_DOWN, uiExtKeyDown },
|
||||
{ VK_LEFT, uiExtKeyLeft },
|
||||
{ VK_RIGHT, uiExtKeyRight },
|
||||
{ VK_F1, uiExtKeyF1 },
|
||||
{ VK_F2, uiExtKeyF2 },
|
||||
{ VK_F3, uiExtKeyF3 },
|
||||
{ VK_F4, uiExtKeyF4 },
|
||||
{ VK_F5, uiExtKeyF5 },
|
||||
{ VK_F6, uiExtKeyF6 },
|
||||
{ VK_F7, uiExtKeyF7 },
|
||||
{ VK_F8, uiExtKeyF8 },
|
||||
{ VK_F9, uiExtKeyF9 },
|
||||
{ VK_F10, uiExtKeyF10 },
|
||||
{ VK_F11, uiExtKeyF11 },
|
||||
{ VK_F12, uiExtKeyF12 },
|
||||
// numpad numeric keys and . are handled in common/areaevents.c
|
||||
// numpad enter is handled in code below
|
||||
{ VK_ADD, uiExtKeyNAdd },
|
||||
{ VK_SUBTRACT, uiExtKeyNSubtract },
|
||||
{ VK_MULTIPLY, uiExtKeyNMultiply },
|
||||
{ VK_DIVIDE, uiExtKeyNDivide },
|
||||
{ VK_SNAPSHOT, 0 },
|
||||
};
|
||||
|
||||
static const struct {
|
||||
WPARAM vk;
|
||||
uiModifiers mod;
|
||||
} modKeys[] = {
|
||||
// even if the separate left/right aren't necessary, have them here anyway, just to be safe
|
||||
{ VK_CONTROL, uiModifierCtrl },
|
||||
{ VK_LCONTROL, uiModifierCtrl },
|
||||
{ VK_RCONTROL, uiModifierCtrl },
|
||||
{ VK_MENU, uiModifierAlt },
|
||||
{ VK_LMENU, uiModifierAlt },
|
||||
{ VK_RMENU, uiModifierAlt },
|
||||
{ VK_SHIFT, uiModifierShift },
|
||||
{ VK_LSHIFT, uiModifierShift },
|
||||
{ VK_RSHIFT, uiModifierShift },
|
||||
// there's no combined Windows key virtual-key code as there is with the others
|
||||
{ VK_LWIN, uiModifierSuper },
|
||||
{ VK_RWIN, uiModifierSuper },
|
||||
{ VK_SNAPSHOT, 0 },
|
||||
};
|
||||
|
||||
static uiModifiers getModifiers(void)
|
||||
{
|
||||
uiModifiers m = 0;
|
||||
|
||||
if ((GetKeyState(VK_CONTROL) & 0x80) != 0)
|
||||
m |= uiModifierCtrl;
|
||||
if ((GetKeyState(VK_MENU) & 0x80) != 0)
|
||||
m |= uiModifierAlt;
|
||||
if ((GetKeyState(VK_SHIFT) & 0x80) != 0)
|
||||
m |= uiModifierShift;
|
||||
if ((GetKeyState(VK_LWIN) & 0x80) != 0)
|
||||
m |= uiModifierSuper;
|
||||
if ((GetKeyState(VK_RWIN) & 0x80) != 0)
|
||||
m |= uiModifierSuper;
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
static BOOL fillKeyEvent(uiAreaKeyEvent &ke, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; extKeys[i].vk != VK_SNAPSHOT; i++) {
|
||||
if (extKeys[i].vk == wParam) {
|
||||
ke.ExtKey = extKeys[i].extkey;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; modKeys[i].vk != VK_SNAPSHOT; i++) {
|
||||
if (modKeys[i].vk == wParam) {
|
||||
ke.Modifier = modKeys[i].mod;
|
||||
ke.Modifiers &= ~ke.Modifier;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO the original code only did this if ke.Modifiers == 0 - why?
|
||||
if (uiprivFromScancode((lParam >> 16) & 0xFF, &ke)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
Loading…
Reference in New Issue