From: John Hodge Date: Sun, 6 Nov 2011 06:47:17 +0000 (+0800) Subject: Usermode/AxWin3 - Implementing more of the widget code X-Git-Tag: rel0.14~141 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=08309c482bda11b6a86066409d08a99789ab2f5d;p=tpg%2Facess2.git Usermode/AxWin3 - Implementing more of the widget code - Managed to break soemthing, seems to lock now --- diff --git a/Usermode/Applications/axwin3_src/Interface/main.c b/Usermode/Applications/axwin3_src/Interface/main.c index 99df8359..22b7f818 100644 --- a/Usermode/Applications/axwin3_src/Interface/main.c +++ b/Usermode/Applications/axwin3_src/Interface/main.c @@ -9,8 +9,14 @@ #include #include +#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
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
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; } diff --git a/Usermode/Applications/axwin3_src/WM/Makefile b/Usermode/Applications/axwin3_src/WM/Makefile index 83544130..62618b64 100644 --- a/Usermode/Applications/axwin3_src/WM/Makefile +++ b/Usermode/Applications/axwin3_src/WM/Makefile @@ -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 diff --git a/Usermode/Applications/axwin3_src/WM/include/renderer_widget.h b/Usermode/Applications/axwin3_src/WM/include/renderer_widget.h index 700540d5..9e4c144c 100644 --- a/Usermode/Applications/axwin3_src/WM/include/renderer_widget.h +++ b/Usermode/Applications/axwin3_src/WM/include/renderer_widget.h @@ -54,8 +54,6 @@ struct sAxWin_Element // -- Render Cache short CachedX, CachedY; short CachedW, CachedH; - - char DebugName[]; }; struct sWidgetWin { diff --git a/Usermode/Applications/axwin3_src/WM/ipc.c b/Usermode/Applications/axwin3_src/WM/ipc.c index 3f55930b..8c957b9f 100644 --- a/Usermode/Applications/axwin3_src/WM/ipc.c +++ b/Usermode/Applications/axwin3_src/WM/ipc.c @@ -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"); diff --git a/Usermode/Applications/axwin3_src/WM/renderer_widget.c b/Usermode/Applications/axwin3_src/WM/renderer_widget.c index bea68c2f..505c5e3a 100644 --- a/Usermode/Applications/axwin3_src/WM/renderer_widget.c +++ b/Usermode/Applications/axwin3_src/WM/renderer_widget.c @@ -10,6 +10,9 @@ #include #include #include +#include + +#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 diff --git a/Usermode/Applications/axwin3_src/WM/video.c b/Usermode/Applications/axwin3_src/WM/video.c index 8066a1ba..3793ce61 100644 --- a/Usermode/Applications/axwin3_src/WM/video.c +++ b/Usermode/Applications/axwin3_src/WM/video.c @@ -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) diff --git a/Usermode/Applications/axwin3_src/WM/wm.c b/Usermode/Applications/axwin3_src/WM/wm.c index 786c338e..464901e4 100644 --- a/Usermode/Applications/axwin3_src/WM/wm.c +++ b/Usermode/Applications/axwin3_src/WM/wm.c @@ -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; - } -} - diff --git a/Usermode/Applications/axwin3_src/include/ipcmessages.h b/Usermode/Applications/axwin3_src/include/ipcmessages.h index b7e78e53..aa69d34c 100644 --- a/Usermode/Applications/axwin3_src/include/ipcmessages.h +++ b/Usermode/Applications/axwin3_src/include/ipcmessages.h @@ -52,7 +52,7 @@ struct sIPCMsg_CreateWin struct sIPCMsg_SendMsg { uint32_t Dest; - int ID; + uint16_t ID; uint16_t Length; char Data[]; }; diff --git a/Usermode/Applications/axwin3_src/include/widget_messages.h b/Usermode/Applications/axwin3_src/include/widget_messages.h index e4f09ed6..fa2013ae 100644 --- a/Usermode/Applications/axwin3_src/include/widget_messages.h +++ b/Usermode/Applications/axwin3_src/include/widget_messages.h @@ -10,9 +10,11 @@ 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 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 9eb55bbd..0e39a049 100644 --- a/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_widget.c +++ b/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_widget.c @@ -10,6 +10,7 @@ #include "include/internal.h" #include #include +#include // === 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); +} diff --git a/Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c b/Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c index fc5ed649..55eec69a 100644 --- a/Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c +++ b/Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c @@ -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)