Usermode/AxWin3 - Added window invalidation, sub-windows render now
authorJohn Hodge <[email protected]>
Sat, 5 Nov 2011 06:53:25 +0000 (14:53 +0800)
committerJohn Hodge <[email protected]>
Sat, 5 Nov 2011 06:53:25 +0000 (14:53 +0800)
Usermode/Applications/axwin3_src/WM/include/wm.h
Usermode/Applications/axwin3_src/WM/ipc.c
Usermode/Applications/axwin3_src/WM/renderer_widget.c
Usermode/Applications/axwin3_src/WM/video.c
Usermode/Applications/axwin3_src/WM/wm.c
Usermode/Applications/axwin3_src/libaxwin3.so_src/r_widget.c
Usermode/include/axwin3/widget.h

index 89cedbd..2766c68 100644 (file)
@@ -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);
index 94691cc..3f55930 100644 (file)
@@ -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);
 }
 
index 6da79e3..53788da 100644 (file)
@@ -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 ---
index 6a400a8..10bd198 100644 (file)
@@ -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;
        
index 7031e37..b40d1c6 100644 (file)
@@ -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
index 64c15b3..0c945d3 100644 (file)
@@ -8,11 +8,13 @@
 #include <axwin3/axwin.h>
 #include <axwin3/widget.h>
 #include "include/internal.h"
+#include <stdlib.h>
 
 // === 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;
+}
index 4fef39c..6542664 100644 (file)
@@ -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);

UCC git Repository :: git.ucc.asn.au