From e2256d66964923bc4c01ac067b7cbb7544429051 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 5 Nov 2011 12:26:52 +0800 Subject: [PATCH] Usermode/AxWin3 - Working on window rendering, root window renders now :) --- .../axwin3_src/WM/include/video.h | 15 +++++ .../Applications/axwin3_src/WM/include/wm.h | 2 +- Usermode/Applications/axwin3_src/WM/main.c | 6 +- .../axwin3_src/WM/renderer_background.c | 2 +- .../axwin3_src/WM/resources/cursor.h | 4 +- Usermode/Applications/axwin3_src/WM/video.c | 34 ++++++++++- Usermode/Applications/axwin3_src/WM/wm.c | 60 +++++++++++++++++-- 7 files changed, 111 insertions(+), 12 deletions(-) create mode 100644 Usermode/Applications/axwin3_src/WM/include/video.h diff --git a/Usermode/Applications/axwin3_src/WM/include/video.h b/Usermode/Applications/axwin3_src/WM/include/video.h new file mode 100644 index 00000000..344b9a44 --- /dev/null +++ b/Usermode/Applications/axwin3_src/WM/include/video.h @@ -0,0 +1,15 @@ +/* + * Acess2 Window Manager v3 (axwin3) + * - By John Hodge (thePowersGang) + * + * include/video.h + * - Video code header + */ +#ifndef _VIDEO_H_ +#define _VIDEO_H_ + +extern void Video_Update(void); +extern void Video_Blit(uint32_t *Source, short DstX, short DstY, short W, short H); + +#endif + diff --git a/Usermode/Applications/axwin3_src/WM/include/wm.h b/Usermode/Applications/axwin3_src/WM/include/wm.h index 75292b55..884fc812 100644 --- a/Usermode/Applications/axwin3_src/WM/include/wm.h +++ b/Usermode/Applications/axwin3_src/WM/include/wm.h @@ -16,7 +16,7 @@ //! Render the window #define WINFLAG_SHOW 0x00000001 //! Window contents are valid -#define WINFLAG_CLEAN 0x00000001 +#define WINFLAG_CLEAN 0x00000002 #define WINFLAG_RENDER_MASK 0x00FFFF00 #define WINFLAG_USR_MASK 0xFF000000 diff --git a/Usermode/Applications/axwin3_src/WM/main.c b/Usermode/Applications/axwin3_src/WM/main.c index 0562d7d5..5b0e5ff3 100644 --- a/Usermode/Applications/axwin3_src/WM/main.c +++ b/Usermode/Applications/axwin3_src/WM/main.c @@ -11,9 +11,11 @@ #include // === IMPORTS === -extern void WM_Update(void); extern void Video_Setup(void); +extern void WM_Initialise(void); extern int Renderer_Widget_Init(void); +extern int Renderer_Background_Init(void); +extern void WM_Update(void); // === PROTOTYPES === void ParseCommandline(int argc, char **argv); @@ -55,6 +57,8 @@ int main(int argc, char *argv[]) Input_Init(); Renderer_Widget_Init(); + Renderer_Background_Init(); + WM_Initialise(); // Spawn interface root if( clone(CLONE_VM, 0) == 0 ) diff --git a/Usermode/Applications/axwin3_src/WM/renderer_background.c b/Usermode/Applications/axwin3_src/WM/renderer_background.c index d17cf9d6..df28c833 100644 --- a/Usermode/Applications/axwin3_src/WM/renderer_background.c +++ b/Usermode/Applications/axwin3_src/WM/renderer_background.c @@ -51,7 +51,7 @@ void Renderer_Background_Redraw(tWindow *Window) { struct sBgWin *info = Window->RendererInfo; - WM_Render_FilledRect(Window, 0, 0, 0xFFFF, 0xFFFF, info->Colour); + WM_Render_FilledRect(Window, info->Colour, 0, 0, 0xFFFF, 0xFFFF); } int Renderer_Background_HandleMessage(tWindow *Target, int Msg, int Len, void *Data) diff --git a/Usermode/Applications/axwin3_src/WM/resources/cursor.h b/Usermode/Applications/axwin3_src/WM/resources/cursor.h index 3cce1f25..0fda4fce 100644 --- a/Usermode/Applications/axwin3_src/WM/resources/cursor.h +++ b/Usermode/Applications/axwin3_src/WM/resources/cursor.h @@ -20,9 +20,9 @@ static struct { 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000, - 0xFF000000, 0xFF000000, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000, + 0xFF000000, 0xFFFFFFFF, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000, + 0xFF000000, 0xFF000000, 0x00000000, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0xFF000000, 0x00000000, 0x00000000, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFF000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFF000000, 0xFF000000, 0x00000000, diff --git a/Usermode/Applications/axwin3_src/WM/video.c b/Usermode/Applications/axwin3_src/WM/video.c index d0476d09..6a400a80 100644 --- a/Usermode/Applications/axwin3_src/WM/video.c +++ b/Usermode/Applications/axwin3_src/WM/video.c @@ -11,6 +11,7 @@ #include #include "resources/cursor.h" #include +#include // === PROTOTYPES === void Video_Setup(void); @@ -77,9 +78,10 @@ void Video_Setup(void) void Video_Update(void) { - //seek(giTerminalFD, 0, SEEK_SET); + _SysDebug("Video_Update - gpScreenBuffer[0] = 0x%x", gpScreenBuffer[0]); seek(giTerminalFD, 0, 1); write(giTerminalFD, gpScreenBuffer, giScreenWidth*giScreenHeight*4); + _SysDebug("Video_Update - Done"); } void Video_SetCursorPos(short X, short Y) @@ -123,6 +125,36 @@ void Video_DrawRect(short X, short Y, short W, short H, uint32_t Color) Video_FillRect(X+W-1, Y, 1, H, Color); } +/** + * \brief Blit an entire buffer to the screen + * \note Assumes Pitch = 4*W + */ +void Video_Blit(uint32_t *Source, short DstX, short DstY, short W, short H) +{ + int i; + uint32_t *buf; + + _SysDebug("Video_Blit: (%p (%i, %i) %ix%i)", Source, DstX, DstY, W, H); + + // 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( W <= 0 || H <= 0 ) return; + + _SysDebug(" Clipped to (%i, %i) %ix%i", DstX, DstY, W, H); + _SysDebug(" Source[0] = 0x%x", Source[0]); + buf = gpScreenBuffer + DstY*giScreenWidth + DstX; + while( H -- ) + { + for( i = W; i --; ) + *buf++ = *Source++; + buf += giScreenWidth - W; + } +} + /** * \brief Draw an image to the screen * \todo Maybe have support for an offset in the image diff --git a/Usermode/Applications/axwin3_src/WM/wm.c b/Usermode/Applications/axwin3_src/WM/wm.c index 74e458ac..7a7a8d8e 100644 --- a/Usermode/Applications/axwin3_src/WM/wm.c +++ b/Usermode/Applications/axwin3_src/WM/wm.c @@ -9,16 +9,19 @@ #include #include #include +#include // === GLOBALS === tWMRenderer *gpWM_Renderers; -// - Render order list (gpWM_FirstWindow is rendered first) tWindow *gpWM_RootWindow; // === CODE === void WM_Initialise(void) { - WM_CreateWindow(NULL, 0x8888FF, "Background"); + WM_CreateWindow(NULL, 0x0088FF, "Background"); + gpWM_RootWindow->W = giScreenWidth; + gpWM_RootWindow->H = giScreenHeight; + gpWM_RootWindow->Flags = WINFLAG_SHOW; } void WM_RegisterRenderer(tWMRenderer *Renderer) @@ -45,6 +48,7 @@ tWindow *WM_CreateWindow(tWindow *Parent, int RendererArg, const char *RendererN // - Call create window function ret = renderer->CreateWindow(RendererArg); ret->Parent = Parent; + ret->Renderer = renderer; if(!Parent) Parent = gpWM_RootWindow; @@ -70,7 +74,12 @@ tWindow *WM_CreateWindow(tWindow *Parent, int RendererArg, const char *RendererN tWindow *WM_CreateWindowStruct(size_t ExtraSize) { - return calloc( sizeof(tWindow) + ExtraSize, 1 ); + tWindow *ret; + + ret = calloc( sizeof(tWindow) + ExtraSize, 1 ); + ret->RendererInfo = ret + 1; // Get end of tWindow + + return ret; } void WM_int_UpdateWindow(tWindow *Window) @@ -96,17 +105,45 @@ void WM_int_UpdateWindow(tWindow *Window) Window->Flags |= WINFLAG_CLEAN; } +void WM_int_BlitWindow(tWindow *Window) +{ + tWindow *child; + + // Ignore hidden windows + if( !(Window->Flags & WINFLAG_SHOW) ) + return ; + + Video_Blit(Window->RenderBuffer, Window->X, Window->Y, Window->W, Window->H); + + for( child = Window->FirstChild; child; child = child->NextSibling ) + { + WM_int_BlitWindow(child); + } +} + void WM_Update(void) { + // Don't redraw if nothing has changed + if( gpWM_RootWindow->Flags & WINFLAG_CLEAN ) + return ; + // - Iterate through visible windows, updating them as needed + WM_int_UpdateWindow(gpWM_RootWindow); // - Draw windows from back to front to the render buffer - - // - Blit the buffer to the screen + WM_int_BlitWindow(gpWM_RootWindow); + + Video_Update(); } +// --- WM Render Routines +// TODO: Move to another file? void WM_Render_FilledRect(tWindow *Window, tColour Colour, int X, int Y, int W, int H) { + 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; } @@ -114,10 +151,21 @@ void WM_Render_FilledRect(tWindow *Window, tColour Colour, int X, int Y, int W, 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? - UNIMPLEMENTED(); + 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; + } } -- 2.20.1