From 54ee7218058b4285be6b02195cba4e90c4e12a2d Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 20 May 2012 16:30:48 +0800 Subject: [PATCH] Usermode/AxWin3 - Working on a bitmap/framebuffer window type --- Usermode/Applications/axwin3_src/WM/main.c | 2 + .../axwin3_src/WM/renderers/passthru.c | 245 +++++++++++++++++- .../axwin3_src/include/framebuffer_messages.h | 53 ++++ 3 files changed, 287 insertions(+), 13 deletions(-) create mode 100644 Usermode/Applications/axwin3_src/include/framebuffer_messages.h diff --git a/Usermode/Applications/axwin3_src/WM/main.c b/Usermode/Applications/axwin3_src/WM/main.c index 0d150467..66fe14e7 100644 --- a/Usermode/Applications/axwin3_src/WM/main.c +++ b/Usermode/Applications/axwin3_src/WM/main.c @@ -16,6 +16,7 @@ extern void WM_Initialise(void); extern int Renderer_Menu_Init(void); extern int Renderer_Widget_Init(void); extern int Renderer_Background_Init(void); +extern int Renderer_Framebuffer_Init(void); extern void WM_Update(void); // === PROTOTYPES === @@ -59,6 +60,7 @@ int main(int argc, char *argv[]) Renderer_Menu_Init(); Renderer_Widget_Init(); Renderer_Background_Init(); + Renderer_Framebuffer_Init(); WM_Initialise(); // Spawn interface root diff --git a/Usermode/Applications/axwin3_src/WM/renderers/passthru.c b/Usermode/Applications/axwin3_src/WM/renderers/passthru.c index 9cd112c0..c8d61cfd 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/passthru.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/passthru.c @@ -7,38 +7,257 @@ */ #include #include +#include +#include +#include + +// === TYPES === +typedef struct +{ + short W, H; + void *Data; + char _data[]; +} tFBBuffer; +typedef struct +{ + tFBBuffer BackBuffer; + int MaxBufferCount; + tFBBuffer *Buffers[]; +} tFBWin; // === PROTOTYPES === -tWindow *Renderer_Passthru_Create(int Flags); -void Renderer_Passthru_Redraw(tWindow *Window); - int Renderer_Passthru_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data); +tWindow *Renderer_Framebuffer_Create(int Flags); +void Renderer_Framebuffer_Redraw(tWindow *Window); + int Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data); // === GLOBALS === -tWMRenderer gRenderer_Passthru = { - .Name = "Passthru", - .CreateWindow = Renderer_Passthru_Create, - .Redraw = Renderer_Passthru_Redraw, - .HandleMessage = Renderer_Passthru_HandleMessage +tWMRenderer gRenderer_Framebuffer = { + .Name = "FrameBuffer", + .CreateWindow = Renderer_Framebuffer_Create, + .Redraw = Renderer_Framebuffer_Redraw, + .HandleMessage = Renderer_Framebuffer_HandleMessage }; // === CODE === -int Renderer_Passthru_Init(void) +int Renderer_Framebuffer_Init(void) { + WM_RegisterRenderer(&gRenderer_Framebuffer); return 0; } -tWindow *Renderer_Passthru_Create(int Flags) +tWindow *Renderer_Framebuffer_Create(int Flags) +{ + tWindow *ret; + tFBWin *info; + const int max_buffers = 10; // TODO: Have this be configurable + + ret = WM_CreateWindowStruct( sizeof(*info) + max_buffers*sizeof(tFBBuffer*) ); + info = ret->RendererInfo; + + info->BackBuffer.W = 0; + info->BackBuffer.H = 0; + info->BackBuffer.Data = NULL; + info->MaxBufferCount = max_buffers; + memset( info->Buffers, 0, sizeof(tFBBuffer*) * max_buffers ); + + return ret; +} + +void Renderer_Framebuffer_Redraw(tWindow *Window) +{ + +} + +// --- --- +tFBBuffer *_GetBuffer(tWindow *Win, uint16_t ID) +{ + tFBWin *info = Win->RendererInfo; + if( ID == 0xFFFF ) + return &info->BackBuffer; + else if( ID >= info->MaxBufferCount ) + return NULL; + else + return info->Buffers[ ID ]; +} + +void _Blit( + tFBBuffer *Dest, uint16_t DX, uint16_t DY, + const tFBBuffer *Src, uint16_t SX, uint16_t SY, + uint16_t W, uint16_t H + ) +{ + uint32_t *dest_data = Dest->Data; + const uint32_t *src_data = Src->Data; + // First, some sanity + if( DX > Dest->W ) return ; + if( DY > Dest->H ) return ; + if( SX > Src->W ) return ; + if( SY > Src->H ) return ; + + if( DX + W > Dest->W ) W = Dest->W - DX; + if( SX + W > Src->W ) W = Src->W - SX; + if( DY + H > Dest->H ) H = Dest->H - DY; + if( SY + H > Src->H ) H = Src->H - SY; + + dest_data += (DY * Dest->W) + DX; + src_data += (SY * Src->W ) + SX; + for( int i = 0; i < H; i ++ ) + { + memcpy( dest_data, src_data, W * 4 ); + dest_data += Dest->W; + src_data += Src->W; + } +} + +void _Fill(tFBBuffer *Buf, uint16_t X, uint16_t Y, uint16_t W, uint16_t H, uint32_t Colour) +{ + uint32_t *data = Buf->Data; + + if( X > Buf->W ) return ; + if( Y > Buf->H ) return ; + if( X + W > Buf->W ) W = Buf->W - X; + if( Y + H > Buf->H ) H = Buf->H - Y; + + data += (Y * Buf->W) + X; + for( int i = 0; i < H; i ++ ) + { + for( int j = 0; j < W; j ++ ) + *data++ = Colour; + data += Buf->W - W; + } +} + +// --- --- +void _Handle_Commit(tWindow *Target, size_t Len, const void *Data) +{ + // Do a window invalidate +} + +void _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data) { - return NULL; + const tFBMsg_NewBuf *msg = Data; + tFBBuffer *buf; + tFBWin *info = Target->RendererInfo; + + if( Len < sizeof(*msg) ) return ; + + if( msg->Buffer == -1 || msg->Buffer >= info->MaxBufferCount ) { + // Can't reallocate -1 + return ; + } + + if( info->Buffers[msg->Buffer] ) { + free(info->Buffers[msg->Buffer]); + info->Buffers[msg->Buffer] = NULL; + } + + buf = malloc(sizeof(tFBBuffer) + msg->W * msg->H * 4); + buf->W = msg->W; + buf->H = msg->H; + buf->Data = buf->_data; + + info->Buffers[msg->Buffer] = buf; } -void Renderer_Passthru_Redraw(tWindow *Window) +void _Handle_Upload(tWindow *Target, size_t Len, const void *Data) { + const tFBMsg_Transfer *msg = Data; + tFBBuffer *dest, src; + + if( Len < sizeof(*msg) ) return ; + if( Len < sizeof(*msg) + msg->W * msg->H * 4 ) return ; + + dest = _GetBuffer(Target, msg->Buffer); + + src.W = msg->W; + src.H = msg->H; + src.Data = (void*)msg->ImageData; + + _Blit( dest, msg->X, msg->Y, &src, 0, 0, msg->W, msg->H ); +} + +void _Handle_Download(tWindow *Target, size_t Len, const void *Data) +{ + #if 0 + const tFBMsg_Transfer *msg = Data; + tFBBuffer dest, *src; + + if( Len < sizeof(*msg) ) return ; + if( Len < sizeof(*msg) + msg->W * msg->H * 4 ) return ; + + src = _GetBuffer(Target, msg->Buffer); + + dest.W = msg->W; + dest.H = msg->H; + dest.Data = msg->ImageData; + _Blit( &dest, 0, 0, src, msg->X, msg->Y, msg->W, msg->H ); + #endif } -int Renderer_Passthru_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data) +void _Handle_LocalBlit(tWindow *Target, size_t Len, const void *Data) { + const tFBMsg_Blit *msg = Data; + tFBBuffer *dest, *src; + + if( Len < sizeof(*msg) ) return ; + + src = _GetBuffer(Target, msg->Source); + dest = _GetBuffer(Target, msg->Dest); + + _Blit( dest, msg->DstX, msg->DstY, src, msg->SrcX, msg->SrcY, msg->W, msg->H ); +} + +void _Handle_FillRect(tWindow *Target, size_t Len, const void *Data) +{ + const tFBMsg_Fill *msg = Data; + tFBBuffer *dest; + + if( Len < sizeof(*msg) ) return ; + + dest = _GetBuffer(Target, msg->Buffer); + + _Fill( dest, msg->X, msg->Y, msg->W, msg->H, msg->Colour ); +} + +int Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data) +{ + switch(Msg) + { + case WNDMSG_RESIZE: + // Resize the framebuffer + return 1; // Pass on + + // Messages that get passed on + case WNDMSG_MOUSEBTN: + return 1; + + // --- Local messages --- + // - Drawing completed, do an update + case MSG_FB_COMMIT: + _Handle_Commit(Target, Len, Data); + return 0; + // - New Buffer (create a new server-side buffer) + case MSG_FB_NEWBUF: + _Handle_CreateBuf(Target, Len, Data); + return 0; + // - Upload (Transfer data from client to server) + case MSG_FB_UPLOAD: + _Handle_Upload(Target, Len, Data); + return 0; + // - Download (Transfer image data from server to client) + case MSG_FB_DOWNLOAD: + _Handle_Download(Target, Len, Data); + return 0; + // - Local Blit (Transfer from server to server) + case MSG_FB_BLIT: + _Handle_LocalBlit(Target, Len, Data); + return 0; + // - Fill a rectangle + case MSG_FB_FILL: + _Handle_FillRect(Target, Len, Data); + return 0; + } return 1; } diff --git a/Usermode/Applications/axwin3_src/include/framebuffer_messages.h b/Usermode/Applications/axwin3_src/include/framebuffer_messages.h new file mode 100644 index 00000000..034999b8 --- /dev/null +++ b/Usermode/Applications/axwin3_src/include/framebuffer_messages.h @@ -0,0 +1,53 @@ +/* + * Acess2 Window Manager v3 + * - By John Hodge (thePowersGang) + * + * framebuffer_messages.h + * - Drawing Surface / Framebuffer Window Type + */ +#ifndef _AXWIN3__FRAMEBUFFER_MESSAGES_H_ +#define _AXWIN3__FRAMEBUFFER_MESSAGES_H_ + +enum +{ + MSG_FB_COMMIT = 0x1000, + MSG_FB_NEWBUF, + MSG_FB_UPLOAD, + MSG_FB_DOWNLOAD, + MSG_FB_BLIT, + MSG_FB_FILL +}; + +typedef struct +{ + uint16_t Buffer; + uint16_t W, H; +} tFBMsg_NewBuf; + +typedef struct +{ + uint16_t Buffer; + uint16_t W, H; + uint16_t X, Y; + uint32_t ImageData[]; +} tFBMsg_Transfer; + +typedef struct +{ + uint16_t Source; + uint16_t Dest; + uint16_t SrcX, SrcY; + uint16_t DstX, DstY; + uint16_t W, H; +} tFBMsg_Blit; + +typedef struct +{ + uint16_t Buffer; + uint16_t X, Y; + uint16_t W, H; + uint32_t Colour; +} tFBMsg_Fill; + +#endif + -- 2.20.1