X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;ds=sidebyside;f=Usermode%2FApplications%2Faxwin3_src%2FWM%2Frenderers%2Fpassthru.c;h=c8d61cfd088684547710250228faf9046f1d32e6;hb=58716e08fd3ce62861636a300879e10e930b177b;hp=9cd112c02f5c25f614626b44ea7e326610d83312;hpb=2f16fec349eabb42f5e23ea2b821f149fa6b767e;p=tpg%2Facess2.git 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; }