2 * Acess2 Window Manager v3
3 * - By John Hodge (thePowersGang)
6 * - Hotkey and key shortcut code
9 #include <wm_internals.h>
10 #include <wm_messages.h>
11 #include <wm_hotkeys.h>
17 #define MAX_STATE_SCANCODE 256
20 char gbWM_HasBeenKeyDown = true;
21 uint8_t gWM_KeyStates[MAX_STATE_SCANCODE/8];
22 tHotkey *gpWM_Hotkeys;
23 tHotkeyTarget *gpWM_HotkeyTargets;
24 tHotkeyTarget *gpWM_HotkeyTargets_Last;
27 static void _SetKey(uint32_t sc);
28 static void _UnsetKey(uint32_t sc);
29 static int _IsKeySet(uint32_t sc);
30 void WM_Hotkey_FireEvent(const char *Target);
33 void WM_Hotkey_Register(int nKeys, uint32_t *Keys, const char *ActionName)
35 // TODO: Duplicate detection
37 // Create new structure
38 tHotkey *h = malloc(sizeof(tHotkey) + nKeys * sizeof(uint32_t) + strlen(ActionName) + 1);
40 h->Target = (void*)( h->Keys + nKeys );
41 strcpy((char*)h->Target, ActionName);
42 memcpy(h->Keys, Keys, nKeys * sizeof(uint32_t));
45 void WM_Hotkey_RegisterAction(const char *ActionName, tWindow *Target, uint16_t Index)
47 // Check for a duplicate registration
48 for( tHotkeyTarget *t = gpWM_HotkeyTargets; t; t = t->Next )
50 if( strcmp(t->Name, ActionName) != 0 )
56 // Create new structure
57 tHotkeyTarget *t = malloc(sizeof(tHotkeyTarget) + strlen(ActionName) + 1);
58 t->Name = (void*)(t + 1);
59 strcpy((char*)t->Name, ActionName);
63 // TODO: Register to be informed when the window dies/closes?
66 if( gpWM_HotkeyTargets ) {
67 gpWM_HotkeyTargets_Last->Next = t;
70 gpWM_HotkeyTargets = t;
72 gpWM_HotkeyTargets_Last = t;
75 void WM_Hotkey_KeyDown(uint32_t Scancode)
78 gbWM_HasBeenKeyDown = true;
81 void WM_Hotkey_KeyUp(uint32_t Scancode)
85 if( !gbWM_HasBeenKeyDown )
88 for( tHotkey *hk = gpWM_Hotkeys; hk; hk = hk->Next )
91 for( i = 0; i < hk->nKeys; i ++ )
93 if( hk->Keys[i] == Scancode ) continue ;
94 if( _IsKeySet(hk->Keys[i]) ) continue ;
101 WM_Hotkey_FireEvent(hk->Target);
106 gbWM_HasBeenKeyDown = false;
109 void WM_Hotkey_FireEvent(const char *Target)
111 // - Internal events (Alt-Tab, Close, Maximize, etc...)
112 // TODO: Internal event handling
114 // - Application registered events
115 for( tHotkeyTarget *t = gpWM_HotkeyTargets, *prev=NULL; t; t = t->Next )
117 if( strcmp(t->Name, Target) != 0 )
120 struct sWndMsg_Hotkey info = {.ID=t->Index};
121 WM_SendMessage(NULL, t->Window, WNDMSG_HOTKEY, sizeof(info), &info);
123 // Sort the list by most-recently-used
125 prev->Next = t->Next;
126 t->Next = gpWM_HotkeyTargets;
127 gpWM_HotkeyTargets = t;
134 static void _SetKey(uint32_t sc)
136 if( sc >= MAX_STATE_SCANCODE ) return;
137 gWM_KeyStates[sc/8] |= 1 << (sc % 8);
139 static void _UnsetKey(uint32_t sc)
141 if( sc >= MAX_STATE_SCANCODE ) return;
142 gWM_KeyStates[sc/8] &= ~(1 << (sc % 8));
144 static int _IsKeySet(uint32_t sc)
146 if( sc >= MAX_STATE_SCANCODE ) return 0;
148 return !!(gWM_KeyStates[sc/8] & (1 << (sc % 8)));