From 94478ae8163d1ce92ed54550f03e76bb9f2e1802 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 20 Nov 2011 22:29:18 +0800 Subject: [PATCH] Usermode/AxWin3 - Working on keyboard input --- .../Applications/axwin3_src/WM/decorator.c | 2 - .../axwin3_src/WM/include/wm_input.h | 18 +++++ .../axwin3_src/WM/include/wm_messages.h | 6 ++ Usermode/Applications/axwin3_src/WM/input.c | 24 ++++++- .../axwin3_src/WM/renderers/widget.c | 69 ++++++++++++++++++- .../WM/renderers/widget/textinput.c | 11 ++- Usermode/Applications/axwin3_src/WM/video.c | 2 +- .../Applications/axwin3_src/WM/wm_input.c | 25 +++++++ .../axwin3_src/include/widget_messages.h | 6 ++ 9 files changed, 154 insertions(+), 9 deletions(-) create mode 100644 Usermode/Applications/axwin3_src/WM/include/wm_input.h diff --git a/Usermode/Applications/axwin3_src/WM/decorator.c b/Usermode/Applications/axwin3_src/WM/decorator.c index 99ceed27..f91c0cad 100644 --- a/Usermode/Applications/axwin3_src/WM/decorator.c +++ b/Usermode/Applications/axwin3_src/WM/decorator.c @@ -41,8 +41,6 @@ void Decorator_UpdateBorderSize(tWindow *Window) if( Window->Flags & WINFLAG_MAXIMIZED ) return ; - _SysDebug("BorderL = %i", ciSideBorderWidth); - Window->BorderB = ciBottomBorderWidth; Window->BorderR = ciSideBorderWidth; Window->BorderL = ciSideBorderWidth; diff --git a/Usermode/Applications/axwin3_src/WM/include/wm_input.h b/Usermode/Applications/axwin3_src/WM/include/wm_input.h new file mode 100644 index 00000000..cc32a07c --- /dev/null +++ b/Usermode/Applications/axwin3_src/WM/include/wm_input.h @@ -0,0 +1,18 @@ +/* + * Acess2 GUI (AxWin) Version 3 + * - By John Hodge (thePowersGang) + * + * wm_input.h + * - Window Manager Input + */ +#ifndef _WM_INPUT_H_ +#define _WM_INPUT_H_ + +extern void WM_Input_MouseMoved(int OldX, int OldY, int NewX, int NewY); +extern void WM_Input_MouseButton(int X, int Y, int Button, int Pressed); +extern void WM_Input_KeyDown(uint32_t Character, uint32_t Scancode); +extern void WM_Input_KeyFire(uint32_t Character, uint32_t Scancode); +extern void WM_Input_KeyUp (uint32_t Character, 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 a64ac99e..c7955f63 100644 --- a/Usermode/Applications/axwin3_src/WM/include/wm_messages.h +++ b/Usermode/Applications/axwin3_src/WM/include/wm_messages.h @@ -55,4 +55,10 @@ struct sWndMsg_MouseButton uint8_t bPressed; }; +struct sWndMsg_KeyAction +{ + uint32_t KeySym; + uint32_t UCS32; +}; + #endif diff --git a/Usermode/Applications/axwin3_src/WM/input.c b/Usermode/Applications/axwin3_src/WM/input.c index a35f913e..45985028 100644 --- a/Usermode/Applications/axwin3_src/WM/input.c +++ b/Usermode/Applications/axwin3_src/WM/input.c @@ -7,6 +7,7 @@ */ #include #include +#include // TODO: Move out to a common header typedef struct @@ -19,8 +20,6 @@ typedef struct // === IMPORTS === extern void Video_SetCursorPos(short X, short Y); -extern void WM_Input_MouseMoved(int OldX, int OldY, int NewX, int NewY); -extern void WM_Input_MouseButton(int X, int Y, int Button, int Pressed); const char *gsMouseDevice; extern int giTerminalFD; extern int giScreenWidth; @@ -69,10 +68,31 @@ void Input_HandleSelect(fd_set *set) if(FD_ISSET(giTerminalFD, set)) { uint32_t codepoint; + static uint32_t scancode; + #define KEY_CODEPOINT_MASK 0x3FFFFFFF + if( read(giTerminalFD, &codepoint, sizeof(codepoint)) != sizeof(codepoint) ) { // oops, error } + + switch(codepoint & 0xC0000000) + { + case 0x00000000: // Key pressed + WM_Input_KeyDown(codepoint & KEY_CODEPOINT_MASK, scancode); + case 0x40000000: // Key refire + WM_Input_KeyFire(codepoint & KEY_CODEPOINT_MASK, scancode); + scancode = 0; + break; + case 0x80000000: // Key release + WM_Input_KeyUp(codepoint & KEY_CODEPOINT_MASK, scancode); + scancode = 0; + break; + case 0xC0000000: // Raw scancode + scancode = codepoint & KEY_CODEPOINT_MASK; + break; + } + // TODO: pass on to message handler _SysDebug("Keypress 0x%x", codepoint); } diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget.c b/Usermode/Applications/axwin3_src/WM/renderers/widget.c index 7fd5e00c..586a5069 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/widget.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget.c @@ -79,7 +79,6 @@ void Widget_int_SetTypeDef(int Type, tWidgetDef *Ptr) } gaWM_WidgetTypes[Type] = Ptr; - _SysDebug("Registered type %i to %p", Type, Ptr); } tWindow *Renderer_Widget_Create(int Flags) @@ -98,6 +97,7 @@ tWindow *Renderer_Widget_Create(int Flags) info = ret->RendererInfo; info->TableSize = eletable_size; + info->FocusedElement = &info->RootElement; info->RootElement.Window = ret; info->RootElement.ID = -1; info->RootElement.BackgroundColour = 0xCCCCCC; @@ -492,6 +492,13 @@ void Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg Widget_UpdateMinDims(parent); } +void Widget_SetFocus(tWidgetWin *Info, tElement *Ele) +{ + // TODO: Callbacks + + Info->FocusedElement = Ele; +} + void Widget_SetFlags(tWidgetWin *Info, int Len, const tWidgetMsg_SetFlags *Msg) { tElement *ele; @@ -548,6 +555,7 @@ void Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg) int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data) { tWidgetWin *info = Target->RendererInfo; + tElement *ele; switch(Msg) { case WNDMSG_RESIZE: { @@ -568,7 +576,6 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void case WNDMSG_MOUSEBTN: { const struct sWndMsg_MouseButton *msg = Data; tWidgetMsg_MouseBtn client_msg; - tElement *ele; int x, y; int rv; @@ -579,6 +586,7 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void client_msg.bPressed = msg->bPressed; ele = Widget_GetElementByPos(info, x, y); + Widget_SetFocus(info, ele); // Send event to all elements from `ele` upwards for( ; ele; ele = ele->Parent ) { @@ -603,15 +611,72 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void } return 0; } + case WNDMSG_KEYDOWN: { + const struct sWndMsg_KeyAction *msg = Data; + if(Len < sizeof(*msg)) return -1; + + if(!info->FocusedElement) return 0; + ele = info->FocusedElement; + + if(gaWM_WidgetTypes[ele->Type]->KeyDown) + gaWM_WidgetTypes[ele->Type]->KeyDown(ele, msg->KeySym, msg->UCS32); + else + { + // TODO: Pass to user + } + + return 0; } + + case WNDMSG_KEYFIRE: { + const struct sWndMsg_KeyAction *msg = Data; + if(Len < sizeof(*msg)) return -1; + + if(!info->FocusedElement) return 0; + ele = info->FocusedElement; + + if(gaWM_WidgetTypes[ele->Type]->KeyFire) + gaWM_WidgetTypes[ele->Type]->KeyFire(ele, msg->KeySym, msg->UCS32); + else + { + // TODO: Pass the buck + } + return 0; } + + case WNDMSG_KEYUP: { + const struct sWndMsg_KeyAction *msg = Data; + if(Len < sizeof(*msg)) return -1; + + if(!info->FocusedElement) return 0; + ele = info->FocusedElement; + + if(gaWM_WidgetTypes[ele->Type]->KeyUp) + gaWM_WidgetTypes[ele->Type]->KeyUp(ele, msg->KeySym); + else + { + // TODO: Pass the buck + } + return 0; } + // New Widget case MSG_WIDGET_CREATE: Widget_NewWidget(info, Len, Data); return 0; + // Delete a widget case MSG_WIDGET_DELETE: _SysDebug("TODO: Implement MSG_WIDGET_DELETE"); return 0; + // Set focused widget + case MSG_WIDGET_SETFOCUS: { + tElement *ele; + const tWidgetMsg_SetFocus *msg = Data; + if(Len < sizeof(*msg)) return -1; + + ele = Widget_GetElementById(info, msg->WidgetID); + Widget_SetFocus(info, ele); + return 0; } + // Set Flags case MSG_WIDGET_SETFLAGS: Widget_SetFlags(info, Len, Data); diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget/textinput.c b/Usermode/Applications/axwin3_src/WM/renderers/widget/textinput.c index 853d28c8..7c077003 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/widget/textinput.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget/textinput.c @@ -53,7 +53,7 @@ void Widget_TextInput_Render(tWindow *Window, tElement *Element) WM_Render_SetTextCursor(Window, Element->CachedX+2+info->CursorXOfs, Element->CachedY+2, - Element->CachedW-4, 1, + 1, Element->CachedH-4, TEXTINPUT_TEXT ); } @@ -79,9 +79,16 @@ void Widget_TextInput_Init(tElement *Element) // No need to explicitly update parent min dims, as the AddElement routine does that } +int Widget_TextInput_KeyFire(tElement *Ele, int KeySym, int Character) +{ + _SysDebug("Key 0x%x fired ('%c')", Character, Character); + return 0; +} + DEFWIDGETTYPE(ELETYPE_TEXTINPUT, WIDGETTYPE_FLAG_NOCHILDREN, .Render = Widget_TextInput_Render, - .Init = Widget_TextInput_Init + .Init = Widget_TextInput_Init, + .KeyFire = Widget_TextInput_KeyFire ); diff --git a/Usermode/Applications/axwin3_src/WM/video.c b/Usermode/Applications/axwin3_src/WM/video.c index f3598848..a65ddf96 100644 --- a/Usermode/Applications/axwin3_src/WM/video.c +++ b/Usermode/Applications/axwin3_src/WM/video.c @@ -104,7 +104,7 @@ void Video_FillRect(int X, int Y, int W, int H, uint32_t Colour) dest = gpScreenBuffer + Y * giScreenWidth + X; while(H --) { - for( i = W; W --; dest ++) *dest = Colour; + for( i = W; i --; dest ++ ) *dest = Colour; dest += giScreenWidth - W; } } diff --git a/Usermode/Applications/axwin3_src/WM/wm_input.c b/Usermode/Applications/axwin3_src/WM/wm_input.c index f15d25a7..dc8d8acb 100644 --- a/Usermode/Applications/axwin3_src/WM/wm_input.c +++ b/Usermode/Applications/axwin3_src/WM/wm_input.c @@ -13,6 +13,7 @@ // === IMPORTS === extern tWindow *gpWM_RootWindow; +extern tWindow *gpWM_FocusedWindow; // === GLOBALS === //! Window in which the mouse button was originally pressed @@ -110,3 +111,27 @@ void WM_Input_MouseButton(int X, int Y, int ButtonIndex, int Pressed) WM_Input_int_SendBtnMsg(win, X, Y, ButtonIndex, Pressed); } +void WM_Input_KeyDown(uint32_t Character, uint32_t Scancode) +{ + struct sWndMsg_KeyAction msg; + msg.KeySym = Scancode; + msg.UCS32 = Character; + WM_SendMessage(NULL, gpWM_FocusedWindow, WNDMSG_KEYDOWN, sizeof(msg), &msg); +} + +void WM_Input_KeyFire(uint32_t Character, uint32_t Scancode) +{ + struct sWndMsg_KeyAction msg; + msg.KeySym = Scancode; + msg.UCS32 = Character; + WM_SendMessage(NULL, gpWM_FocusedWindow, WNDMSG_KEYFIRE, sizeof(msg), &msg); +} + +void WM_Input_KeyUp(uint32_t Character, uint32_t Scancode) +{ + struct sWndMsg_KeyAction msg; + msg.KeySym = Scancode; + msg.UCS32 = Character; + WM_SendMessage(NULL, gpWM_FocusedWindow, WNDMSG_KEYUP, sizeof(msg), &msg); +} + diff --git a/Usermode/Applications/axwin3_src/include/widget_messages.h b/Usermode/Applications/axwin3_src/include/widget_messages.h index 1974f3f6..53e7dcc5 100644 --- a/Usermode/Applications/axwin3_src/include/widget_messages.h +++ b/Usermode/Applications/axwin3_src/include/widget_messages.h @@ -13,6 +13,7 @@ enum // Control (Client->Server) messages MSG_WIDGET_CREATE = 0x1000, MSG_WIDGET_DELETE, + MSG_WIDGET_SETFOCUS, MSG_WIDGET_SETFLAGS, MSG_WIDGET_SETSIZE, MSG_WIDGET_SETTEXT, @@ -39,6 +40,11 @@ typedef struct uint32_t WidgetID; } tWidgetMsg_Delete; +typedef struct +{ + uint32_t WidgetID; +} tWidgetMsg_SetFocus; + typedef struct { uint32_t WidgetID; -- 2.20.1