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,
48 int Renderer_Framebuffer_Init(void)
50 WM_RegisterRenderer(&gRenderer_Framebuffer);
54 tWindow *Renderer_Framebuffer_Create(int Flags)
58 const int max_buffers = 10; // TODO: Have this be configurable
60 ret = WM_CreateWindowStruct( sizeof(*info) + max_buffers*sizeof(tFBBuffer*) );
61 info = ret->RendererInfo;
63 info->BackBuffer.W = 0;
64 info->BackBuffer.H = 0;
65 info->BackBuffer.Data = NULL;
66 info->MaxBufferCount = max_buffers;
67 memset( info->Buffers, 0, sizeof(tFBBuffer*) * max_buffers );
72 void Renderer_Framebuffer_Redraw(tWindow *Window)
78 tFBBuffer *_GetBuffer(tWindow *Win, uint16_t ID)
80 tFBWin *info = Win->RendererInfo;
82 return &info->BackBuffer;
83 else if( ID >= info->MaxBufferCount )
86 return info->Buffers[ ID ];
90 tFBBuffer *Dest, uint16_t DX, uint16_t DY,
91 const tFBBuffer *Src, uint16_t SX, uint16_t SY,
92 uint16_t W, uint16_t H
95 uint32_t *dest_data = Dest->Data;
96 const uint32_t *src_data = Src->Data;
98 if( DX > Dest->W ) return ;
99 if( DY > Dest->H ) return ;
100 if( SX > Src->W ) return ;
101 if( SY > Src->H ) return ;
103 if( DX + W > Dest->W ) W = Dest->W - DX;
104 if( SX + W > Src->W ) W = Src->W - SX;
105 if( DY + H > Dest->H ) H = Dest->H - DY;
106 if( SY + H > Src->H ) H = Src->H - SY;
108 dest_data += (DY * Dest->W) + DX;
109 src_data += (SY * Src->W ) + SX;
110 for( int i = 0; i < H; i ++ )
112 memcpy( dest_data, src_data, W * 4 );
113 dest_data += Dest->W;
118 void _Fill(tFBBuffer *Buf, uint16_t X, uint16_t Y, uint16_t W, uint16_t H, uint32_t Colour)
120 uint32_t *data = Buf->Data;
122 if( X > Buf->W ) return ;
123 if( Y > Buf->H ) return ;
124 if( X + W > Buf->W ) W = Buf->W - X;
125 if( Y + H > Buf->H ) H = Buf->H - Y;
127 data += (Y * Buf->W) + X;
128 for( int i = 0; i < H; i ++ )
130 for( int j = 0; j < W; j ++ )
137 int _Handle_Commit(tWindow *Target, size_t Len, const void *Data)
139 // Do a window invalidate
143 int _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data)
145 const tFBIPC_NewBuf *msg = Data;
147 tFBWin *info = Target->RendererInfo;
149 if( Len < sizeof(*msg) ) return -1;
151 if( msg->Buffer == -1 || msg->Buffer >= info->MaxBufferCount ) {
152 // Can't reallocate -1
156 if( info->Buffers[msg->Buffer] ) {
157 free(info->Buffers[msg->Buffer]);
158 info->Buffers[msg->Buffer] = NULL;
161 buf = malloc(sizeof(tFBBuffer) + msg->W * msg->H * 4);
166 info->Buffers[msg->Buffer] = buf;
171 int _Handle_Upload(tWindow *Target, size_t Len, const void *Data)
173 const tFBIPC_Transfer *msg = Data;
174 tFBBuffer *dest, src;
176 if( Len < sizeof(*msg) ) return -1;
177 if( Len < sizeof(*msg) + msg->W * msg->H * 4 ) return -1;
179 dest = _GetBuffer(Target, msg->Buffer);
183 src.Data = (void*)msg->ImageData;
185 _Blit( dest, msg->X, msg->Y, &src, 0, 0, msg->W, msg->H );
189 int _Handle_Download(tWindow *Target, size_t Len, const void *Data)
191 const tFBIPC_Transfer *msg = Data;
192 tFBBuffer dest, *src;
194 if( Len < sizeof(*msg) ) return -1;
196 src = _GetBuffer(Target, msg->Buffer);
198 tFBIPC_Transfer *ret;
199 int retlen = sizeof(*ret) + msg->W*msg->H*4;
200 ret = malloc( retlen );
202 dest.W = ret->W = msg->W;
203 dest.H = ret->H = msg->H;
204 dest.Data = ret->ImageData;
206 _Blit( &dest, 0, 0, src, msg->X, msg->Y, msg->W, msg->H );
208 WM_SendIPCReply(Target, IPC_FB_DOWNLOAD, retlen, ret);
215 int _Handle_LocalBlit(tWindow *Target, size_t Len, const void *Data)
217 const tFBIPC_Blit *msg = Data;
218 tFBBuffer *dest, *src;
220 if( Len < sizeof(*msg) ) return -1;
222 src = _GetBuffer(Target, msg->Source);
223 dest = _GetBuffer(Target, msg->Dest);
225 _Blit( dest, msg->DstX, msg->DstY, src, msg->SrcX, msg->SrcY, msg->W, msg->H );
229 int _Handle_FillRect(tWindow *Target, size_t Len, const void *Data)
231 const tFBIPC_Fill *msg = Data;
234 if( Len < sizeof(*msg) ) return -1;
236 dest = _GetBuffer(Target, msg->Buffer);
238 _Fill( dest, msg->X, msg->Y, msg->W, msg->H, msg->Colour );
242 int Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
247 // Resize the framebuffer
250 // Messages that get passed on
251 case WNDMSG_MOUSEBTN: