From 305bad29632e0cf47307e010ae7dea55617f2dfd Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 18 May 2012 17:37:14 +0800 Subject: [PATCH] Usermode/AxWin3 - Wokring on hotkeys --- Usermode/Applications/axwin3_src/WM/Makefile | 3 +- .../axwin3_src/WM/include/messages.h | 21 --- .../axwin3_src/WM/include/wm_hotkeys.h | 40 +++++ .../axwin3_src/WM/include/wm_messages.h | 7 + .../Applications/axwin3_src/WM/wm_hotkeys.c | 150 ++++++++++++++++++ .../Applications/axwin3_src/WM/wm_input.c | 9 +- 6 files changed, 207 insertions(+), 23 deletions(-) delete mode 100644 Usermode/Applications/axwin3_src/WM/include/messages.h create mode 100644 Usermode/Applications/axwin3_src/WM/include/wm_hotkeys.h create mode 100644 Usermode/Applications/axwin3_src/WM/wm_hotkeys.c diff --git a/Usermode/Applications/axwin3_src/WM/Makefile b/Usermode/Applications/axwin3_src/WM/Makefile index f0f93216..fae6cbef 100644 --- a/Usermode/Applications/axwin3_src/WM/Makefile +++ b/Usermode/Applications/axwin3_src/WM/Makefile @@ -3,11 +3,12 @@ -include ../../Makefile.cfg CPPFLAGS += -I include/ -I ../include/ +CFLAGS += -std=gnu99 DIR := Apps/AxWin/3.0 BIN := AxWinWM OBJ := main.o input.o video.o ipc.o image.o utf-8.o -OBJ += wm.o wm_input.o wm_render.o wm_render_text.o +OBJ += wm.o wm_input.o wm_render.o wm_render_text.o wm_hotkeys.o OBJ += decorator.o OBJ += renderers/passthru.o OBJ += renderers/background.o diff --git a/Usermode/Applications/axwin3_src/WM/include/messages.h b/Usermode/Applications/axwin3_src/WM/include/messages.h deleted file mode 100644 index 3219ea01..00000000 --- a/Usermode/Applications/axwin3_src/WM/include/messages.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Acess2 GUI (AxWin3) - */ -#ifndef _MESSAGES_H_ -#define _MESSAGES_H_ - -struct sAxWin_Message -{ - uint16_t ID; -}; - -typedef struct sAxWin_Message tAxWin_Message; - -enum eMessages -{ - MSG_NULL, - MSG_CREATEWIN -}; - -#endif - diff --git a/Usermode/Applications/axwin3_src/WM/include/wm_hotkeys.h b/Usermode/Applications/axwin3_src/WM/include/wm_hotkeys.h new file mode 100644 index 00000000..44675d21 --- /dev/null +++ b/Usermode/Applications/axwin3_src/WM/include/wm_hotkeys.h @@ -0,0 +1,40 @@ +/* + * Acess2 Window Manager v3 + * - By John Hodge (thePowersGang) + * + * wm_hotkeys.h + * - Hotkey and key shortcut code + */ +#ifndef _WM_HOTKEYS_H_ +#define _WM_HOTKEYS_H_ + +typedef struct sHotkey tHotkey; +typedef struct sHotkeyTarget tHotkeyTarget; + +struct sHotkey +{ + tHotkey *Next; + + const char *Target; + + int nKeys; + uint32_t Keys[]; +}; + +struct sHotkeyTarget +{ + struct sHotkeyTarget *Next; + + const char *Name; + + tWindow *Window; + int Index; +}; + + +extern void WM_Hotkey_Register(int nKeys, uint32_t *Keys, const char *ActionName); +extern void WM_Hotkey_KeyDown(uint32_t Scancode); +extern void WM_Hotkey_KeyUp(uint32_t Scancode); + +#endif + diff --git a/Usermode/Applications/axwin3_src/WM/include/wm_messages.h b/Usermode/Applications/axwin3_src/WM/include/wm_messages.h index c7955f63..2308c284 100644 --- a/Usermode/Applications/axwin3_src/WM/include/wm_messages.h +++ b/Usermode/Applications/axwin3_src/WM/include/wm_messages.h @@ -27,6 +27,8 @@ enum eWM_WindowMessages WNDMSG_KEYDOWN, WNDMSG_KEYFIRE, WNDMSG_KEYUP, + + WNDMSG_HOTKEY, WNDMSG_CLASS_MIN = 0x1000, WNDMSG_CLASS_MAX = 0x2000, @@ -61,4 +63,9 @@ struct sWndMsg_KeyAction uint32_t UCS32; }; +struct sWndMsg_Hotkey +{ + uint16_t ID; +}; + #endif diff --git a/Usermode/Applications/axwin3_src/WM/wm_hotkeys.c b/Usermode/Applications/axwin3_src/WM/wm_hotkeys.c new file mode 100644 index 00000000..3fbe4f76 --- /dev/null +++ b/Usermode/Applications/axwin3_src/WM/wm_hotkeys.c @@ -0,0 +1,150 @@ +/* + * Acess2 Window Manager v3 + * - By John Hodge (thePowersGang) + * + * wm_hotkeys.c + * - Hotkey and key shortcut code + */ +#include +#include +#include +#include +#include + +#define true 1 +#define false 0 + +#define MAX_STATE_SCANCODE 256 + +// === GOBALS === +char gbWM_HasBeenKeyDown = true; +uint8_t gWM_KeyStates[MAX_STATE_SCANCODE/8]; +tHotkey *gpWM_Hotkeys; +tHotkeyTarget *gpWM_HotkeyTargets; +tHotkeyTarget *gpWM_HotkeyTargets_Last; + +// === PROTOTYPES === +static void _SetKey(uint32_t sc); +static void _UnsetKey(uint32_t sc); +static int _IsKeySet(uint32_t sc); +void WM_Hotkey_FireEvent(const char *Target); + +// === CODE === +void WM_Hotkey_Register(int nKeys, uint32_t *Keys, const char *ActionName) +{ + // TODO: Duplicate detection + + // Create new structure + tHotkey *h = malloc(sizeof(tHotkey) + nKeys * sizeof(uint32_t) + strlen(ActionName) + 1); + h->nKeys = nKeys; + h->Target = (void*)( h->Keys + nKeys ); + strcpy((char*)h->Target, ActionName); + memcpy(h->Keys, Keys, nKeys * sizeof(uint32_t)); +} + +void WM_Hotkey_RegisterAction(const char *ActionName, tWindow *Target, uint16_t Index) +{ + // Check for a duplicate registration + for( tHotkeyTarget *t = gpWM_HotkeyTargets; t; t = t->Next ) + { + if( strcmp(t->Name, ActionName) != 0 ) + continue ; + // Duplicate! + return ; + } + + // Create new structure + tHotkeyTarget *t = malloc(sizeof(tHotkeyTarget) + strlen(ActionName) + 1); + t->Name = (void*)(t + 1); + strcpy((char*)t->Name, ActionName); + t->Window = Target; + t->Index = Index; + + // TODO: Register to be informed when the window dies/closes? + + // Append to list + if( gpWM_HotkeyTargets ) { + gpWM_HotkeyTargets_Last->Next = t; + } + else { + gpWM_HotkeyTargets = t; + } + gpWM_HotkeyTargets_Last = t; +} + +void WM_Hotkey_KeyDown(uint32_t Scancode) +{ + _SetKey(Scancode); + gbWM_HasBeenKeyDown = true; +} + +void WM_Hotkey_KeyUp(uint32_t Scancode) +{ + _UnsetKey(Scancode); + + if( !gbWM_HasBeenKeyDown ) + return ; + + for( tHotkey *hk = gpWM_Hotkeys; hk; hk = hk->Next ) + { + int i; + for( i = 0; i < hk->nKeys; i ++ ) + { + if( hk->Keys[i] == Scancode ) continue ; + if( _IsKeySet(hk->Keys[i]) ) continue ; + break; + } + if( i == hk->nKeys ) + continue ; + + // Fire shortcut + WM_Hotkey_FireEvent(hk->Target); + + break; + } + + gbWM_HasBeenKeyDown = false; +} + +void WM_Hotkey_FireEvent(const char *Target) +{ + // - Internal events (Alt-Tab, Close, Maximize, etc...) + // TODO: Internal event handling + + // - Application registered events + for( tHotkeyTarget *t = gpWM_HotkeyTargets, *prev=NULL; t; t = t->Next ) + { + if( strcmp(t->Name, Target) != 0 ) + continue ; + + struct sWndMsg_Hotkey info = {.ID=t->Index}; + WM_SendMessage(NULL, t->Window, WNDMSG_HOTKEY, sizeof(info), &info); + + // Sort the list by most-recently-used + if(prev != NULL) { + prev->Next = t->Next; + t->Next = gpWM_HotkeyTargets; + gpWM_HotkeyTargets = t; + } + + return ; + } +} + +static void _SetKey(uint32_t sc) +{ + if( sc >= MAX_STATE_SCANCODE ) return; + gWM_KeyStates[sc/8] |= 1 << (sc % 8); +} +static void _UnsetKey(uint32_t sc) +{ + if( sc >= MAX_STATE_SCANCODE ) return; + gWM_KeyStates[sc/8] &= ~(1 << (sc % 8)); +} +static int _IsKeySet(uint32_t sc) +{ + if( sc >= MAX_STATE_SCANCODE ) return 0; + + return !!(gWM_KeyStates[sc/8] & (1 << (sc % 8))); +} + diff --git a/Usermode/Applications/axwin3_src/WM/wm_input.c b/Usermode/Applications/axwin3_src/WM/wm_input.c index 232407ae..223dbef9 100644 --- a/Usermode/Applications/axwin3_src/WM/wm_input.c +++ b/Usermode/Applications/axwin3_src/WM/wm_input.c @@ -8,6 +8,7 @@ #include #include #include +#include #define MAX_BUTTONS 3 @@ -70,7 +71,7 @@ void WM_Input_MouseMoved(int OldX, int OldY, int NewX, int NewY) WM_SendMessage(NULL, win, WNDMSG_MOUSEMOVE, sizeof(msg), &msg); } -inline void WM_Input_int_SendBtnMsg(tWindow *Win, int X, int Y, int Index, int Pressed) +void WM_Input_int_SendBtnMsg(tWindow *Win, int X, int Y, int Index, int Pressed) { struct sWndMsg_MouseButton msg; @@ -114,6 +115,9 @@ void WM_Input_MouseButton(int X, int Y, int ButtonIndex, int Pressed) void WM_Input_KeyDown(uint32_t Character, uint32_t Scancode) { struct sWndMsg_KeyAction msg; + + WM_Hotkey_KeyDown(Scancode); + msg.KeySym = Scancode; msg.UCS32 = Character; WM_SendMessage(NULL, gpWM_FocusedWindow, WNDMSG_KEYDOWN, sizeof(msg), &msg); @@ -135,6 +139,9 @@ void WM_Input_KeyFire(uint32_t Character, uint32_t Scancode) void WM_Input_KeyUp(uint32_t Character, uint32_t Scancode) { struct sWndMsg_KeyAction msg; + + WM_Hotkey_KeyUp(Scancode); + msg.KeySym = Scancode; msg.UCS32 = Character; WM_SendMessage(NULL, gpWM_FocusedWindow, WNDMSG_KEYUP, sizeof(msg), &msg); -- 2.20.1