From e33b0db4c03c7664cc34a45e1da2981287e0cd0c Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 5 Nov 2011 14:53:25 +0800 Subject: [PATCH] Usermode/AxWin3 - Added window invalidation, sub-windows render now --- .../Applications/axwin3_src/WM/include/wm.h | 3 ++ Usermode/Applications/axwin3_src/WM/ipc.c | 28 +++++++--- .../axwin3_src/WM/renderer_widget.c | 14 ++++- Usermode/Applications/axwin3_src/WM/video.c | 5 +- Usermode/Applications/axwin3_src/WM/wm.c | 54 ++++++++++++++----- .../axwin3_src/libaxwin3.so_src/r_widget.c | 31 ++++++++++- Usermode/include/axwin3/widget.h | 2 +- 7 files changed, 111 insertions(+), 26 deletions(-) diff --git a/Usermode/Applications/axwin3_src/WM/include/wm.h b/Usermode/Applications/axwin3_src/WM/include/wm.h index 89cedbd9..2766c68d 100644 --- a/Usermode/Applications/axwin3_src/WM/include/wm.h +++ b/Usermode/Applications/axwin3_src/WM/include/wm.h @@ -17,6 +17,8 @@ #define WINFLAG_SHOW 0x00000001 //! Window contents are valid #define WINFLAG_CLEAN 0x00000002 +//! All child windows are un-changed +#define WINFLAG_CHILDCLEAN 0x00000004 #define WINFLAG_RENDER_MASK 0x00FFFF00 #define WINFLAG_USR_MASK 0xFF000000 @@ -32,6 +34,7 @@ typedef uint32_t tColour; // === FUNCTIONS === // --- Management extern tWindow *WM_CreateWindow(tWindow *Parent, int Flags, const char *Renderer); +extern void WM_Invalidate(tWindow *Window); extern void WM_ShowWindow(tWindow *Window, int bShow); extern int WM_ResizeWindow(tWindow *Window, int W, int H); extern int WM_MoveWindow(tWindow *Window, int X, int Y); diff --git a/Usermode/Applications/axwin3_src/WM/ipc.c b/Usermode/Applications/axwin3_src/WM/ipc.c index 94691ccf..3f55930b 100644 --- a/Usermode/Applications/axwin3_src/WM/ipc.c +++ b/Usermode/Applications/axwin3_src/WM/ipc.c @@ -141,7 +141,7 @@ int IPC_Type_Sys_GetSize(const void *Ident) int IPC_Type_Sys_Compare(const void *Ident1, const void *Ident2) { - return *(const int*)Ident1 - *(const int*)Ident2; + return *(const tid_t*)Ident1 - *(const tid_t*)Ident2; } void IPC_Type_Sys_Send(const void *Ident, size_t Length, const void *Data) @@ -163,11 +163,12 @@ int _CompareClientPtrs(const void *_a, const void *_b) tIPC_Client *IPC_int_GetClient(const tIPC_Type *IPCType, const void *Ident) { - int pos; // Position where the new client will be inserted + int pos = 0; // Position where the new client will be inserted int ident_size; tIPC_Client *ret; // - Search list of registered clients + if(giIPC_ClientCount > 0) { tIPC_Client target; int div; @@ -183,6 +184,7 @@ tIPC_Client *IPC_int_GetClient(const tIPC_Type *IPCType, const void *Ident) { div /= 2; cmp = _CompareClientPtrs(&ret, &gIPC_Clients[pos]); +// _SysDebug("Checking against %i gives %i", pos, cmp); if(cmp == 0) break; if(cmp < 0) pos -= div; @@ -201,10 +203,11 @@ tIPC_Client *IPC_int_GetClient(const tIPC_Type *IPCType, const void *Ident) // - Create a new client entry ident_size = IPCType->GetIdentSize(Ident); +// _SysDebug("ident_size = %i", ident_size); ret = malloc( sizeof(tIPC_Client) + ident_size ); if(!ret) return NULL; ret->IPCType = IPCType; - ret->Ident = &ret + 1; // Get the end of the structure + ret->Ident = ret + 1; // Get the end of the structure memcpy( (void*)ret->Ident, Ident, ident_size ); ret->nWindows = 0; ret->Windows = NULL; @@ -227,8 +230,10 @@ tWindow *IPC_int_GetWindow(tIPC_Client *Client, uint32_t WindowID) if( WindowID == -1 ) return NULL; - if( WindowID >= Client->nWindows ) + if( WindowID >= Client->nWindows ) { +// _SysDebug("Window %i out of range for %p (%i)", WindowID, Client, Client->nWindows); return NULL; + } return Client->Windows[WindowID]; } @@ -244,8 +249,10 @@ void IPC_int_SetWindow(tIPC_Client *Client, uint32_t WindowID, tWindow *WindowPt Client->nWindows = WindowID + 1; Client->Windows = realloc(Client->Windows, Client->nWindows*sizeof(tWindow*)); memset( &Client->Windows[oldCount], 0, (Client->nWindows-oldCount)*sizeof(tWindow*) ); + _SysDebug("Expanded %p's window list from %i to %i", Client, oldCount, Client->nWindows); } - + + _SysDebug("Assigned %p to window %i for %p", WindowPtr, WindowID, Client); Client->Windows[WindowID] = WindowPtr; } @@ -301,6 +308,8 @@ int IPC_Msg_SetWinPos(tIPC_Client *Client, tAxWin_IPCMessage *Msg) win = IPC_int_GetWindow(Client, Msg->Window); if(!win) return 1; + _SysDebug("info = {..., bSetPos=%i,bSetDims=%i}", info->bSetPos, info->bSetDims); + if(info->bSetPos) WM_MoveWindow(win, info->X, info->Y); if(info->bSetDims) @@ -312,6 +321,7 @@ int IPC_Msg_SetWinPos(tIPC_Client *Client, tAxWin_IPCMessage *Msg) void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxWin_IPCMessage *Msg) { tIPC_Client *client; + int rv = 0; _SysDebug("IPC_Handle: (IPCType=%p, Ident=%p, MsgLen=%i, Msg=%p)", IPCType, Ident, MsgLen, Msg); @@ -341,17 +351,17 @@ void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxW // --- Create window case IPCMSG_CREATEWIN: _SysDebug(" IPC_Handle: IPCMSG_CREATEWIN"); - IPC_Msg_CreateWin(client, Msg); + rv = IPC_Msg_CreateWin(client, Msg); break; // --- Show/Hide a window case IPCMSG_SHOWWINDOW: _SysDebug(" IPC_Handle: IPCMSG_SHOWWINDOW"); - IPC_Msg_ShowWindow(client, Msg); + rv = IPC_Msg_ShowWindow(client, Msg); break; // --- Move/Resize a window case IPCMSG_SETWINPOS: _SysDebug(" IPC_Handle: IPCMSG_SETWINPOS"); - IPC_Msg_SetWinPos(client, Msg); + rv = IPC_Msg_SetWinPos(client, Msg); break; // --- Unknown message @@ -360,5 +370,7 @@ void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxW _SysDebug("WARNING: Unknown message %i (%p)", Msg->ID, IPCType); break; } + if(rv) + _SysDebug("IPC_Handle: rv = %i", rv); } diff --git a/Usermode/Applications/axwin3_src/WM/renderer_widget.c b/Usermode/Applications/axwin3_src/WM/renderer_widget.c index 6da79e39..53788da0 100644 --- a/Usermode/Applications/axwin3_src/WM/renderer_widget.c +++ b/Usermode/Applications/axwin3_src/WM/renderer_widget.c @@ -38,6 +38,8 @@ struct sAxWin_Element short FixedWith; //!< Fixed lengthways Size attribute (height) short FixedCross; //!< Fixed Cross Size attribute (width) + tColour BackgroundColour; + char *Text; // -- Attributes maitained by the element code @@ -83,12 +85,20 @@ int Renderer_Widget_Init(void) tWindow *Renderer_Widget_Create(int Flags) { - // TODO: Add info - return WM_CreateWindowStruct( sizeof(tWidgetWin) ); + tWindow *ret; + tWidgetWin *info; + ret = WM_CreateWindowStruct( sizeof(tWidgetWin) ); + info = ret->RendererInfo; + + info->RootElement.BackgroundColour = 0xCCCCCC; + + return ret; } void Renderer_Widget_Redraw(tWindow *Window) { + tWidgetWin *info = Window->RendererInfo; + WM_Render_FilledRect(Window, info->RootElement.BackgroundColour, 0, 0, 0xFFF, 0xFFF); } // --- Render / Resize --- diff --git a/Usermode/Applications/axwin3_src/WM/video.c b/Usermode/Applications/axwin3_src/WM/video.c index 6a400a80..10bd1988 100644 --- a/Usermode/Applications/axwin3_src/WM/video.c +++ b/Usermode/Applications/axwin3_src/WM/video.c @@ -136,11 +136,14 @@ void Video_Blit(uint32_t *Source, short DstX, short DstY, short W, short H) _SysDebug("Video_Blit: (%p (%i, %i) %ix%i)", Source, DstX, DstY, W, H); + if( DstX >= giScreenWidth) return ; + if( DstY >= giScreenHeight) return ; // TODO: Handle -ve X/Y by clipping if( DstX < 0 || DstY < 0 ) return ; // TODO: Handle out of bounds by clipping too if( DstX + W > giScreenWidth ) return; - if( DstY + H > giScreenHeight ) return; + if( DstY + H > giScreenHeight ) + H = giScreenWidth - DstY; if( W <= 0 || H <= 0 ) return; diff --git a/Usermode/Applications/axwin3_src/WM/wm.c b/Usermode/Applications/axwin3_src/WM/wm.c index 7031e379..b40d1c61 100644 --- a/Usermode/Applications/axwin3_src/WM/wm.c +++ b/Usermode/Applications/axwin3_src/WM/wm.c @@ -46,13 +46,14 @@ tWindow *WM_CreateWindow(tWindow *Parent, int RendererArg, const char *RendererN if(renderer == NULL) return NULL; + if(!Parent) + Parent = gpWM_RootWindow; + // - Call create window function ret = renderer->CreateWindow(RendererArg); ret->Parent = Parent; ret->Renderer = renderer; - - if(!Parent) - Parent = gpWM_RootWindow; + ret->Flags = WINFLAG_CLEAN; // Note, not acutally clean, but it makes invaidate work // Append to parent if(Parent) @@ -90,6 +91,7 @@ void WM_ShowWindow(tWindow *Window, int bShow) Window->Flags |= WINFLAG_SHOW; else Window->Flags &= ~WINFLAG_SHOW; + WM_Invalidate(Window); } int WM_MoveWindow(tWindow *Window, int X, int Y) @@ -101,7 +103,9 @@ int WM_MoveWindow(tWindow *Window, int X, int Y) if(Y >= giScreenHeight) Y = giScreenHeight - 1; Window->X = X; Window->Y = Y; - + + WM_Invalidate(Window); + return 0; } @@ -112,10 +116,30 @@ int WM_ResizeWindow(tWindow *Window, int W, int H) if(Window->Y + H < 0) Window->Y = -H + 1; Window->W = W; Window->H = H; + + WM_Invalidate(Window); return 0; } +void WM_Invalidate(tWindow *Window) +{ + // Don't invalidate twice (speedup) + if( !(Window->Flags & WINFLAG_CLEAN) ) return; + + _SysDebug("Invalidating %p"); + + // Mark for re-render + Window->Flags &= ~WINFLAG_CLEAN; + + // Mark up the tree that a child window has changed + while( (Window = Window->Parent) ) + { + _SysDebug("Childclean removed from %p", Window); + Window->Flags &= ~WINFLAG_CHILDCLEAN; + } +} + // --- Rendering / Update void WM_int_UpdateWindow(tWindow *Window) { @@ -124,20 +148,24 @@ void WM_int_UpdateWindow(tWindow *Window) // Ignore hidden windows if( !(Window->Flags & WINFLAG_SHOW) ) return ; - // Ignore unchanged windows - if( Window->Flags & WINFLAG_CLEAN ) - return; - + // Render - Window->Renderer->Redraw(Window); + if( !(Window->Flags & WINFLAG_CLEAN) ) + { + Window->Renderer->Redraw(Window); + Window->Flags |= WINFLAG_CLEAN; + } // Process children - for( child = Window->FirstChild; child; child = child->NextSibling ) + if( !(Window->Flags & WINFLAG_CHILDCLEAN) ) { - WM_int_UpdateWindow(child); + for( child = Window->FirstChild; child; child = child->NextSibling ) + { + WM_int_UpdateWindow(child); + } + Window->Flags |= WINFLAG_CHILDCLEAN; } - Window->Flags |= WINFLAG_CLEAN; } void WM_int_BlitWindow(tWindow *Window) @@ -159,7 +187,7 @@ void WM_int_BlitWindow(tWindow *Window) void WM_Update(void) { // Don't redraw if nothing has changed - if( gpWM_RootWindow->Flags & WINFLAG_CLEAN ) + if( (gpWM_RootWindow->Flags & WINFLAG_CHILDCLEAN) ) return ; // - Iterate through visible windows, updating them as needed diff --git a/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_widget.c b/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_widget.c index 64c15b33..0c945d30 100644 --- a/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_widget.c +++ b/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_widget.c @@ -8,11 +8,13 @@ #include #include #include "include/internal.h" +#include // === STRUCTURES === struct sAxWin3_Widget { tHWND Window; + uint32_t ID; tAxWin3_Widget_Callback Callback; }; @@ -36,10 +38,37 @@ tHWND AxWin3_Widget_CreateWindow(tHWND Parent, int W, int H, int RootEleFlags) ret = AxWin3_CreateWindow( Parent, "Widget", RootEleFlags, - sizeof(*info), AxWin3_Widget_MessageHandler + sizeof(*info) + sizeof(tAxWin3_Widget), AxWin3_Widget_MessageHandler ); info = AxWin3_int_GetDataPtr(ret); + + info->nElements = 1; + info->Elements = malloc(sizeof(tAxWin3_Widget*)); + info->Elements[0] = (void*)(info + 1); // Get end of *info + + AxWin3_ResizeWindow(ret, W, H); return ret; } +void AxWin3_Widget_DestroyWindow(tHWND Window) +{ + // Free all element structures + + // Free array + + // Request window to be destroyed (will clean up any data stored in tHWND) +} + +tAxWin3_Widget *AxWin3_Widget_GetRoot(tHWND Window) +{ + tWidgetWindowInfo *info = AxWin3_int_GetDataPtr(Window); + return info->Elements[0]; +} + +tAxWin3_Widget *AxWin3_Widget_AddWidget(tAxWin3_Widget *Parent, int Type, int Flags, const char *DebugName) +{ + // Assign ID + + return NULL; +} diff --git a/Usermode/include/axwin3/widget.h b/Usermode/include/axwin3/widget.h index 4fef39ce..6542664e 100644 --- a/Usermode/include/axwin3/widget.h +++ b/Usermode/include/axwin3/widget.h @@ -16,7 +16,7 @@ typedef int (*tAxWin3_Widget_Callback)(tAxWin3_Widget Widget, int EventType, uns extern tHWND AxWin3_Widget_CreateWindow(tHWND Parent, int W, int H, int RootEleFlags); extern void AxWin3_Widget_DestroyWindow(tHWND Window); -extern tAxWin3_Widget *AxWin3_WidgeT_GetRoot(tHWND Window); +extern tAxWin3_Widget *AxWin3_Widget_GetRoot(tHWND Window); extern tAxWin3_Widget *AxWin3_Widget_AddWidget(tAxWin3_Widget *Parent, int Type, int Flags, const char *DebugName); extern void AxWin3_Widget_DelWidget(tAxWin3_Widget *Widget); -- 2.20.1