2 * Acess2 Window Manager v3
3 * - By John Hodge (thePowersGang)
6 * - Passthrough window render (framebuffer essentially)
9 #include <wm_renderer.h>
11 #include <framebuffer_messages.h>
12 #include <wm_messages.h>
28 tWindow *Renderer_Framebuffer_Create(int Flags);
29 void Renderer_Framebuffer_Redraw(tWindow *Window);
30 int _Handle_Commit(tWindow *Target, size_t Len, const void *Data);
31 int _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data);
32 int Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data);
35 tWMRenderer gRenderer_Framebuffer = {
36 .Name = "FrameBuffer",
37 .CreateWindow = Renderer_Framebuffer_Create,
38 .Redraw = Renderer_Framebuffer_Redraw,
39 .HandleMessage = Renderer_Framebuffer_HandleMessage,
40 .nIPCHandlers = N_IPC_FB,
42 [IPC_FB_COMMIT] = _Handle_Commit,
43 [IPC_FB_NEWBUF] = _Handle_CreateBuf,
44 //[IPC_FB_SUBBUF] = _Handle_SubBuf,
49 int Renderer_Framebuffer_Init(void)
51 WM_RegisterRenderer(&gRenderer_Framebuffer);
55 tWindow *Renderer_Framebuffer_Create(int Flags)
59 const int max_buffers = 10; // TODO: Have this be configurable
61 ret = WM_CreateWindowStruct( sizeof(*info) + max_buffers*sizeof(tFBBuffer*) );
62 info = ret->RendererInfo;
64 info->BackBuffer.W = 0;
65 info->BackBuffer.H = 0;
66 info->BackBuffer.Data = NULL;
67 info->MaxBufferCount = max_buffers;
68 memset( info->Buffers, 0, sizeof(tFBBuffer*) * max_buffers );
73 void Renderer_Framebuffer_Redraw(tWindow *Window)
79 tFBBuffer *_GetBuffer(tWindow *Win, uint16_t ID)
81 tFBWin *info = Win->RendererInfo;
83 return &info->BackBuffer;
84 else if( ID >= info->MaxBufferCount )
87 return info->Buffers[ ID ];
91 tFBBuffer *Dest, uint16_t DX, uint16_t DY,
92 const tFBBuffer *Src, uint16_t SX, uint16_t SY,
93 uint16_t W, uint16_t H
96 uint32_t *dest_data = Dest->Data;
97 const uint32_t *src_data = Src->Data;
99 if( DX > Dest->W ) return ;
100 if( DY > Dest->H ) return ;
101 if( SX > Src->W ) return ;
102 if( SY > Src->H ) return ;
104 if( DX + W > Dest->W ) W = Dest->W - DX;
105 if( SX + W > Src->W ) W = Src->W - SX;
106 if( DY + H > Dest->H ) H = Dest->H - DY;
107 if( SY + H > Src->H ) H = Src->H - SY;
109 dest_data += (DY * Dest->W) + DX;
110 src_data += (SY * Src->W ) + SX;
111 for( int i = 0; i < H; i ++ )
113 memcpy( dest_data, src_data, W * 4 );
114 dest_data += Dest->W;
119 void _Fill(tFBBuffer *Buf, uint16_t X, uint16_t Y, uint16_t W, uint16_t H, uint32_t Colour)
121 uint32_t *data = Buf->Data;
123 if( X > Buf->W ) return ;
124 if( Y > Buf->H ) return ;
125 if( X + W > Buf->W ) W = Buf->W - X;
126 if( Y + H > Buf->H ) H = Buf->H - Y;
128 data += (Y * Buf->W) + X;
129 for( int i = 0; i < H; i ++ )
131 for( int j = 0; j < W; j ++ )
138 int _Handle_Commit(tWindow *Target, size_t Len, const void *Data)
140 // Do a window invalidate
144 int _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data)
146 const tFBIPC_NewBuf *msg = Data;
148 tFBWin *info = Target->RendererInfo;
150 if( Len < sizeof(*msg) ) return -1;
152 if( msg->Buffer == -1 || msg->Buffer >= info->MaxBufferCount ) {
153 // Can't reallocate -1
157 if( info->Buffers[msg->Buffer] ) {
158 free(info->Buffers[msg->Buffer]);
159 info->Buffers[msg->Buffer] = NULL;
162 buf = malloc(sizeof(tFBBuffer) + msg->W * msg->H * 4);
167 info->Buffers[msg->Buffer] = buf;
172 int _Handle_Upload(tWindow *Target, size_t Len, const void *Data)
174 const tFBIPC_Transfer *msg = Data;
175 tFBBuffer *dest, src;
177 if( Len < sizeof(*msg) ) return -1;
178 if( Len < sizeof(*msg) + msg->W * msg->H * 4 ) return -1;
180 dest = _GetBuffer(Target, msg->Buffer);
184 src.Data = (void*)msg->ImageData;
186 _Blit( dest, msg->X, msg->Y, &src, 0, 0, msg->W, msg->H );
190 int _Handle_Download(tWindow *Target, size_t Len, const void *Data)
192 const tFBIPC_Transfer *msg = Data;
193 tFBBuffer dest, *src;
195 if( Len < sizeof(*msg) ) return -1;
197 src = _GetBuffer(Target, msg->Buffer);
199 tFBIPC_Transfer *ret;
200 int retlen = sizeof(*ret) + msg->W*msg->H*4;
201 ret = malloc( retlen );
203 dest.W = ret->W = msg->W;
204 dest.H = ret->H = msg->H;
205 dest.Data = ret->ImageData;
207 _Blit( &dest, 0, 0, src, msg->X, msg->Y, msg->W, msg->H );
209 WM_SendIPCReply(Target, IPC_FB_DOWNLOAD, retlen, ret);
216 int _Handle_LocalBlit(tWindow *Target, size_t Len, const void *Data)
218 const tFBIPC_Blit *msg = Data;
219 tFBBuffer *dest, *src;
221 if( Len < sizeof(*msg) ) return -1;
223 src = _GetBuffer(Target, msg->Source);
224 dest = _GetBuffer(Target, msg->Dest);
226 _Blit( dest, msg->DstX, msg->DstY, src, msg->SrcX, msg->SrcY, msg->W, msg->H );
230 int _Handle_FillRect(tWindow *Target, size_t Len, const void *Data)
232 const tFBIPC_Fill *msg = Data;
235 if( Len < sizeof(*msg) ) return -1;
237 dest = _GetBuffer(Target, msg->Buffer);
239 _Fill( dest, msg->X, msg->Y, msg->W, msg->H, msg->Colour );
243 int Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
248 // Resize the framebuffer
251 // Messages that get passed on
252 case WNDMSG_MOUSEBTN: