Usermode/AxWin3 - Implementing more of the widget code
authorJohn Hodge <[email protected]>
Sun, 6 Nov 2011 06:47:17 +0000 (14:47 +0800)
committerJohn Hodge <[email protected]>
Sun, 6 Nov 2011 06:47:17 +0000 (14:47 +0800)
- Managed to break soemthing, seems to lock now

Usermode/Applications/axwin3_src/Interface/main.c
Usermode/Applications/axwin3_src/WM/Makefile
Usermode/Applications/axwin3_src/WM/include/renderer_widget.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/include/ipcmessages.h
Usermode/Applications/axwin3_src/include/widget_messages.h
Usermode/Applications/axwin3_src/libaxwin3.so_src/r_widget.c
Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c

index 99df835..22b7f81 100644 (file)
@@ -9,8 +9,14 @@
 #include <axwin3/axwin.h>
 #include <axwin3/widget.h>
 
+#define SIDEBAR_WIDTH  32
+
+// === PROTOTYPES ===
+void   create_sidebar(void);
+
 // === GLOBALS ===
 tHWND  gSidebar;
+tAxWin3_Widget *gSidebarRoot;
 
 // === CODE ===
 int sidebar_callback(tHWND Window, int Length, void *Data)
@@ -23,19 +29,48 @@ int main(int argc, char *argv[])
        // Connect to AxWin3 Server
        AxWin3_Connect(NULL);
        
+       create_sidebar();
+       
+       // Idle loop
+       AxWin3_MainLoop();
+       
+       return 0;
+}
+
+void create_sidebar(void)
+{
+       tAxWin3_Widget  *btn, *txt, *ele;
+
        // Create sidebar
-       // TODO: Use the widget library instead
        // TODO: Get screen dimensions somehow
-       gSidebar = AxWin3_Widget_CreateWindow(NULL, 32, 600, 0);
-
+       gSidebar = AxWin3_Widget_CreateWindow(NULL, SIDEBAR_WIDTH, 480, 0);
        AxWin3_MoveWindow(gSidebar, 0, 0);
+       gSidebarRoot = AxWin3_Widget_GetRoot(gSidebar); 
+
+       // - Main menu
+       btn = AxWin3_Widget_AddWidget(gSidebarRoot, ELETYPE_BUTTON, ELEFLAG_NOSTRETCH, "SystemButton");
+       AxWin3_Widget_SetSize(btn, SIDEBAR_WIDTH-4);
+       txt = AxWin3_Widget_AddWidget(btn, ELETYPE_IMAGE, 0, "SystemLogo");
+       AxWin3_Widget_SetText(txt, "file://./AcessLogo.sif");
        
+       // - Plain <hr/> style spacer
+       ele = AxWin3_Widget_AddWidget(gSidebarRoot, ELETYPE_SPACER, ELEFLAG_NOSTRETCH, "SideBar Spacer Top");
+       AxWin3_Widget_SetSize(ele, 4);
+
+       // TODO: Program list
+       ele = AxWin3_Widget_AddWidget(gSidebarRoot, ELETYPE_BOX, ELEFLAG_VERTICAL, "ProgramList");
+
+       // - Plain <hr/> style spacer
+       ele = AxWin3_Widget_AddWidget(gSidebarRoot, ELETYPE_SPACER, ELEFLAG_NOSTRETCH, "SideBar Spacer Top");
+       AxWin3_Widget_SetSize(ele, 4);
+
+       // > Version/Time
+       txt = AxWin3_Widget_AddWidget(gSidebarRoot, ELETYPE_TEXT, ELEFLAG_NOSTRETCH, "Version String");
+       AxWin3_Widget_SetSize(txt, 20);
+       AxWin3_Widget_SetText(txt, "2.0");
+
        // Show!
        AxWin3_ShowWindow(gSidebar, 1); 
-
-       // Idle loop
-       AxWin3_MainLoop();
        
-       return 0;
 }
 
index 8354413..62618b6 100644 (file)
@@ -6,8 +6,8 @@ CPPFLAGS += -I include/ -I ../include/
 
 DIR := Apps/AxWin/3.0
 BIN := AxWinWM
-OBJ := main.o wm.o input.o video.o ipc.o
-OBJ += messageio.o
+OBJ := main.o input.o video.o ipc.o
+OBJ += wm.o wm_render.o
 OBJ += renderer_classes.o renderer_passthru.o renderer_background.o
 OBJ += renderer_widget.o renderer_widget_decorator.o
 
index 700540d..9e4c144 100644 (file)
@@ -54,8 +54,6 @@ struct sAxWin_Element
        // -- Render Cache
        short   CachedX, CachedY;
        short   CachedW, CachedH;
-       
-       char    DebugName[];
 };
 struct sWidgetWin
 {
index 3f55930..8c957b9 100644 (file)
@@ -257,6 +257,27 @@ void IPC_int_SetWindow(tIPC_Client *Client, uint32_t WindowID, tWindow *WindowPt
 }
 
 // --- IPC Message Handlers ---
+int IPC_Msg_SendMsg(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
+{
+       tIPCMsg_SendMsg *info = (void*)Msg->Data;
+       tWindow *src, *dest;
+       
+       // - Sanity checks
+       if( Msg->Size < sizeof(tIPCMsg_SendMsg) )
+               return -1;
+       if( Msg->Size < sizeof(tIPCMsg_SendMsg) + info->Length )
+               return -1;
+       
+       src = IPC_int_GetWindow(Client, Msg->Window);
+       if(!src)        return 1;
+       dest = IPC_int_GetWindow(Client, info->Dest);
+       if(!dest)       return 1;
+
+       WM_SendMessage(src, dest, info->ID, info->Length, info->Data);  
+
+       return 0;
+}
+
 int IPC_Msg_CreateWin(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
 {
        tIPCMsg_CreateWin       *info = (void*)Msg->Data;
@@ -348,6 +369,12 @@ void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxW
                }
                break;
 
+       // --- Send a message
+       case IPCMSG_SENDMSG:
+               _SysDebug(" IPC_Handle: IPCMSG_SENDMSG %i", ((tIPCMsg_SendMsg*)Msg->Data)->ID);
+               rv = IPC_Msg_SendMsg(client, Msg);
+               break;
+
        // --- Create window
        case IPCMSG_CREATEWIN:
                _SysDebug(" IPC_Handle: IPCMSG_CREATEWIN");
index bea68c2..505c5e3 100644 (file)
@@ -10,6 +10,9 @@
 #include <renderer_widget.h>
 #include <string.h>
 #include <wm_messages.h>
+#include <stdlib.h>
+
+#define DEFAULT_ELETABLE_SIZE  64
 
 // === PROTOTYPES ===
  int   Renderer_Widget_Init(void);
@@ -42,9 +45,14 @@ tWindow      *Renderer_Widget_Create(int Flags)
 {
        tWindow *ret;
        tWidgetWin      *info;
-       ret = WM_CreateWindowStruct( sizeof(tWidgetWin) );
+        int    eletable_size = DEFAULT_ELETABLE_SIZE;
+
+       // TODO: Use `Flags` as default element count?
+
+       ret = WM_CreateWindowStruct( sizeof(tWidgetWin) + sizeof(tElement*)*eletable_size );
        info = ret->RendererInfo;
        
+       info->TableSize = eletable_size;
        info->RootElement.BackgroundColour = 0xCCCCCC;
        
        return ret;
@@ -257,7 +265,7 @@ tElement *Widget_GetElementById(tWidgetWin *Info, uint32_t ID)
 void Widget_NewWidget(tWidgetWin *Info, size_t Len, tWidgetMsg_Create *Msg)
 {
        const int       max_debugname_len = Len - sizeof(tWidgetMsg_Create);
-       tElement        *parent;        
+       tElement        *parent, *new;
 
        // Sanity check
        if( Len < sizeof(tWidgetMsg_Create) )
@@ -267,6 +275,61 @@ void Widget_NewWidget(tWidgetWin *Info, size_t Len, tWidgetMsg_Create *Msg)
        
        // Create
        parent = Widget_GetElementById(Info, Msg->Parent);
+       if(!parent)
+       {
+               _SysDebug("Widget_NewWidget - Bad parent ID %i", Msg->Parent);
+               return ;
+       }
+
+       // Check if the ID is already in use
+       if( Widget_GetElementById(Info, Msg->NewID) )
+               return ;
+
+       // Create new element
+       new = calloc(sizeof(tElement), 1);
+       new->ID = Msg->NewID;
+       new->Type = Msg->Type;
+       new->Parent = parent;
+       new->Flags = Msg->Flags;
+       new->PaddingT = 2;
+       new->PaddingB = 2;
+       new->PaddingL = 2;
+       new->PaddingR = 2;
+       
+       // Add to parent's list
+       if(parent->LastChild)
+               parent->LastChild->NextSibling = new;
+       else
+               parent->FirstChild = new;
+       new->NextSibling = parent->LastChild;
+       parent->LastChild = new;
+
+       // Add to info
+       {
+               tElement        *ele, *prev = NULL;
+               for(ele = Info->ElementTable[new->ID % Info->TableSize]; ele; prev = ele, ele = ele->ListNext);
+               if(prev)
+                       prev->ListNext = new;
+               else
+                       Info->ElementTable[new->ID % Info->TableSize] = new;
+       }
+}
+
+void Widget_SetSize(tWidgetWin *Info, int Len, tWidgetMsg_SetSize *Msg)
+{
+       tElement        *ele;
+       
+       if( Len < sizeof(tWidgetMsg_SetSize) )
+               return ;
+       
+       ele = Widget_GetElementById(Info, Msg->WidgetID);
+       if(!ele)        return ;
+       
+       ele->FixedWith = Msg->Value;
+}
+
+void Widget_SetText(tWidgetWin *Info, int Len, tWidgetMsg_SetText *Msg)
+{
        
 }
 
@@ -287,6 +350,16 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, void *Data)
        case MSG_WIDGET_CREATE:
                Widget_NewWidget(info, Len, Data);
                return 0;
+       
+       // Set length
+       case MSG_WIDGET_SETSIZE:
+               Widget_SetSize(info, Len, Data);
+               return 0;
+       // Set text
+       case MSG_WIDGET_SETTEXT:
+               Widget_SetText(info, Len, Data);
+               return 0;
+       
        // 
        default:
                return 1;       // Unhandled, pass to user
index 8066a1b..3793ce6 100644 (file)
@@ -67,14 +67,10 @@ void Video_Setup(void)
        
        // Create local framebuffer (back buffer)
        gpScreenBuffer = malloc( giScreenWidth*giScreenHeight*4 );
-//     memset(gpScreenBufferi
-//     Video_FillRect(0, 0, giScreenWidth, giScreenHeight, 0x8080FF);
 
        // Set cursor position and bitmap
        ioctl(giTerminalFD, TERM_IOCTL_SETCURSORBITMAP, &cCursorBitmap);
        Video_SetCursorPos( giScreenWidth/2, giScreenHeight/2 );
-
-       Video_Update();
 }
 
 void Video_Update(void)
index 786c338..464901e 100644 (file)
@@ -225,141 +225,3 @@ void WM_Update(void)
        Video_Update();
 }
 
-// --- WM Render Routines
-// TODO: Move to another file?
-void WM_Render_FillRect(tWindow *Window, int X, int Y, int W, int H, tColour Colour)
-{
-       uint32_t        *dest;
-        int    i;
-//     _SysDebug("WM_Render_FilledRect(%p, 0x%x...", Window, Colour);
-//     _SysDebug(" (%i,%i), %ix%i)", X, Y, W, H);
-       // Clip to window dimensions
-       if(X < 0) { W += X; X = 0; }
-       if(Y < 0) { H += Y; Y = 0; }
-       if(X >= Window->W)      return;
-       if(Y >= Window->H)      return;
-       if(X + W > Window->W)   W = Window->W - X;
-       if(Y + H > Window->H)   H = Window->H - Y;
-//     _SysDebug(" Clipped to (%i,%i), %ix%i", X, Y, W, H);
-
-       // Render to buffer
-       // Create if needed?
-
-       if(!Window->RenderBuffer) {
-               Window->RenderBuffer = malloc(Window->W*Window->H*4);
-       }
-
-       dest = (uint32_t*)Window->RenderBuffer + Y*Window->W + X;
-       while( H -- )
-       {
-               for( i = W; i --; )
-                       *dest++ = Colour;
-               dest += Window->W - W;
-       }
-}
-
-void WM_Render_DrawRect(tWindow *Window, int X, int Y, int W, int H, tColour Colour)
-{      
-       WM_Render_FillRect(Window, X, Y, W, 1, Colour);
-       WM_Render_FillRect(Window, X, Y+H-1, W, 1, Colour);
-       WM_Render_FillRect(Window, X, Y, 1, H, Colour);
-       WM_Render_FillRect(Window, X+W-1, Y, 1, H, Colour);
-}
-
-void WM_Render_DrawText(tWindow *Window, int X, int Y, int W, int H, void *Font, tColour Colour, const char *Text)
-{
-       // TODO: Implement
-       _SysDebug("WM_Render_DrawText - TODO: Implement");
-}
-
-/**
- * \brief Draw an image to the screen
- * \todo Maybe have support for an offset in the image
- */
-void WM_Render_DrawImage(tWindow *Window, int X, int Y, int W, int H, tImage *Image)
-{
-        int    x, y;
-       uint32_t        *dest;
-       uint8_t *data;
-       
-       // Sanity please
-       if( !Image )    return ;
-
-       // Allocate
-       if(!Window->RenderBuffer) {
-               Window->RenderBuffer = malloc(Window->W*Window->H*4);
-       }
-       
-       // Bounds Check
-       if( X >= Window->W )    return ;
-       if( Y >= Window->H )    return ;
-       
-       // Wrap to image size
-       if( W > Image->Width )  W = Image->Width;
-       if( H > Image->Height ) H = Image->Height;
-       
-       // Wrap to screen size
-       if( X + W > Window->W ) W = Window->W - X;
-       if( Y + H > Window->H ) H = Window->H - Y;
-
-       dest = (uint32_t*)Window->RenderBuffer + Y * Window->W + X;
-       data = Image->Data;
-
-       // Do the render
-       switch( Image->Format )
-       {
-       case IMGFMT_BGRA:
-               for( y = 0; y < H; y ++ )
-               {
-                        int    r, g, b, a;     // New
-                        int    or, og, ob;     // Original
-                       for( x = 0; x < W; x ++ )
-                       {
-                               b = data[x*4+0]; g = data[x*4+1]; r = data[x*4+2]; a = data[x*4+3];
-                               if( a == 0 )    continue;       // 100% transparent
-                               ob = dest[x]&0xFF; og = (dest[x] >> 8)&0xFF; or = (dest[x] >> 16)&0xFF;
-                               // Handle Alpha
-                               switch(a)
-                               {
-                               // Transparent: Handled above
-                               // Solid
-                               case 0xFF:      break;
-                               // Half
-                               case 0x80:
-                                       r = (or + r) / 2;
-                                       g = (og + g) / 2;
-                                       b = (ob + b) / 2;
-                                       break;
-                               // General
-                               default:
-                                       r = (or * (255-a) + r * a) / 255;
-                                       g = (og * (255-a) + g * a) / 255;
-                                       b = (ob * (255-a) + b * a) / 255;
-                                       break;
-                               }
-                               dest[x] = b | (g << 8) | (r << 16);
-                       }
-                       data += Image->Width * 4;
-                       dest += Window->W;
-               }
-               break;
-       
-       // RGB
-       case IMGFMT_RGB:
-               for( y = 0; y < H; y ++ )
-               {
-                       for( x = 0; x < W; x ++ )
-                       {
-                               //        Blue           Green                Red
-                               dest[x] = data[x*3+2] | (data[x*3+1] << 8) | (data[x*3+0] << 16);
-                       }
-                       data += W * 3;
-                       dest += Window->W;
-               }
-               break;
-       default:
-               _SysDebug("ERROR: Unknown image format %i\n", Image->Format);
-               break;
-       }
-}
-
index b7e78e5..aa69d34 100644 (file)
@@ -52,7 +52,7 @@ struct sIPCMsg_CreateWin
 struct sIPCMsg_SendMsg
 {
        uint32_t        Dest;
-        int    ID;
+       uint16_t        ID;
        uint16_t        Length;
        char    Data[];
 };
index e4f09ed..fa2013a 100644 (file)
 
 enum
 {
-       MSG_WIDGET_CREATE,
+       MSG_WIDGET_CREATE = 0x1000,
        MSG_WIDGET_DELETE,
-       MSG_WIDGET_SETTEXT
+       MSG_WIDGET_SETSIZE,
+       MSG_WIDGET_SETTEXT,
+       MSG_WIDGET_SETCOLOUR
 };
 
 
@@ -20,8 +22,34 @@ typedef struct
 {
        uint32_t        Parent;
        uint32_t        NewID;
+       uint32_t        Type;
+       uint32_t        Flags;
        char    DebugName[];
 } tWidgetMsg_Create;
 
+typedef struct
+{
+       uint32_t        WidgetID;
+} tWidgetMsg_Delete;
+
+typedef struct
+{
+       uint32_t        WidgetID;
+       uint32_t        Value;
+} tWidgetMsg_SetSize;
+
+typedef struct
+{
+       uint32_t        WidgetID;
+       char    Text[];
+} tWidgetMsg_SetText;
+
+typedef struct
+{
+       uint32_t        WidgetID;
+       uint32_t        Index;
+       uint32_t        Colour;
+} tWidgetMsg_SetColour;
+
 #endif
 
index 9eb55bb..0e39a04 100644 (file)
@@ -10,6 +10,7 @@
 #include "include/internal.h"
 #include <stdlib.h>
 #include <widget_messages.h>
+#include <string.h>
 
 // === STRUCTURES ===
 struct sAxWin3_Widget
@@ -24,6 +25,7 @@ typedef struct
         int    nElements;
        tAxWin3_Widget  **Elements;
         int    FirstFreeID;
+       tAxWin3_Widget  RootElement;
        // Callbacks for each element
 } tWidgetWindowInfo;
 
@@ -44,10 +46,8 @@ tHWND AxWin3_Widget_CreateWindow(tHWND Parent, int W, int H, int RootEleFlags)
                );
        info = AxWin3_int_GetDataPtr(ret);
 
-       info->nElements = 1;
-       info->Elements = malloc(sizeof(tAxWin3_Widget*));
-       info->Elements[0] = (void*)(info + 1);  // Get end of *info
-       info->FirstFreeID = 1;
+       info->RootElement.Window = ret;
+       info->RootElement.ID = -1;
 
        AxWin3_ResizeWindow(ret, W, H);
        
@@ -66,7 +66,7 @@ void AxWin3_Widget_DestroyWindow(tHWND Window)
 tAxWin3_Widget *AxWin3_Widget_GetRoot(tHWND Window)
 {
        tWidgetWindowInfo       *info = AxWin3_int_GetDataPtr(Window);
-       return info->Elements[0];
+       return &info->RootElement;
 }
 
 tAxWin3_Widget *AxWin3_Widget_AddWidget(tAxWin3_Widget *Parent, int Type, int Flags, const char *DebugName)
@@ -86,7 +86,7 @@ tAxWin3_Widget *AxWin3_Widget_AddWidget(tAxWin3_Widget *Parent, int Type, int Fl
                if( info->Elements[newID] == NULL )
                        break;
        }
-       if( info->Elements[newID] )
+       if( info->nElements == 0 || info->Elements[newID] )
        {
                info->nElements ++;
                info->Elements = realloc(info->Elements, sizeof(*info->Elements)*info->nElements);
@@ -114,3 +114,47 @@ tAxWin3_Widget *AxWin3_Widget_AddWidget(tAxWin3_Widget *Parent, int Type, int Fl
 
        return ret;
 }
+
+void AxWin3_Widget_DelWidget(tAxWin3_Widget *Widget)
+{
+       tWidgetMsg_Delete       msg;
+       tWidgetWindowInfo       *info = AxWin3_int_GetDataPtr(Widget->Window);
+       
+       msg.WidgetID = Widget->ID;
+       AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_DELETE, sizeof(msg), &msg);
+       
+       info->Elements[Widget->ID] = NULL;
+       if(Widget->ID < info->FirstFreeID)
+               info->FirstFreeID = Widget->ID;
+       free(Widget);
+}
+
+void AxWin3_Widget_SetSize(tAxWin3_Widget *Widget, int Size)
+{
+       tWidgetMsg_SetSize      msg;
+       
+       msg.WidgetID = Widget->ID;
+       msg.Value = Size;
+       AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETSIZE, sizeof(msg), &msg);
+}
+
+void AxWin3_Widget_SetText(tAxWin3_Widget *Widget, const char *Text)
+{
+       char    buf[sizeof(tWidgetMsg_SetText) + strlen(Text) + 1];
+       tWidgetMsg_SetText      *msg = (void*)buf;
+       
+       msg->WidgetID = Widget->ID;
+       strcpy(msg->Text, Text);
+       
+       AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETTEXT, sizeof(buf), buf);
+}
+
+void AxWin3_Widget_SetColour(tAxWin3_Widget *Widget, int Index, tAxWin3_Colour Colour)
+{
+       tWidgetMsg_SetColour    msg;
+       
+       msg.WidgetID = Widget->ID;
+       msg.Index = Index;
+       msg.Colour = Colour;
+       AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETCOLOUR, sizeof(msg), &msg);
+}
index fc5ed64..55eec69 100644 (file)
@@ -122,7 +122,7 @@ void AxWin3_DestroyWindow(tHWND Window)
 
 void *AxWin3_int_GetDataPtr(tHWND Window)
 {
-       return &Window->Data;
+       return Window->Data;
 }
 
 void AxWin3_SendMessage(tHWND Window, tHWND Destination, int Message, int Length, void *Data)
@@ -133,6 +133,12 @@ void AxWin3_SendMessage(tHWND Window, tHWND Destination, int Message, int Length
        msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SENDMSG, 0, sizeof(*info)+Length);
        info = (void*)msg->Data;
        info->Dest = AxWin3_int_GetWindowID(Destination);
+       info->ID = Message;
+       info->Length = Length;
+       memcpy(info->Data, Data, Length);
+       
+       AxWin3_int_SendIPCMessage(msg);
+       free(msg);
 }
 
 void AxWin3_ShowWindow(tHWND Window, int bShow)

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