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>
29 tWindow *Renderer_Framebuffer_Create(int Flags);
30 void Renderer_Framebuffer_Redraw(tWindow *Window);
31 int Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data);
34 tWMRenderer gRenderer_Framebuffer = {
35 .Name = "FrameBuffer",
36 .CreateWindow = Renderer_Framebuffer_Create,
37 .Redraw = Renderer_Framebuffer_Redraw,
38 .HandleMessage = Renderer_Framebuffer_HandleMessage
42 int Renderer_Framebuffer_Init(void)
44 WM_RegisterRenderer(&gRenderer_Framebuffer);
48 tWindow *Renderer_Framebuffer_Create(int Flags)
52 const int max_buffers = 10; // TODO: Have this be configurable
54 ret = WM_CreateWindowStruct( sizeof(*info) + max_buffers*sizeof(tFBBuffer*) );
55 info = ret->RendererInfo;
57 info->BackBuffer.W = 0;
58 info->BackBuffer.H = 0;
59 info->BackBuffer.Data = NULL;
60 info->MaxBufferCount = max_buffers;
61 memset( info->Buffers, 0, sizeof(tFBBuffer*) * max_buffers );
66 void Renderer_Framebuffer_Redraw(tWindow *Window)
72 tFBBuffer *_GetBuffer(tWindow *Win, uint16_t ID)
74 tFBWin *info = Win->RendererInfo;
76 return &info->BackBuffer;
77 else if( ID >= info->MaxBufferCount )
80 return info->Buffers[ ID ];
84 tFBBuffer *Dest, uint16_t DX, uint16_t DY,
85 const tFBBuffer *Src, uint16_t SX, uint16_t SY,
86 uint16_t W, uint16_t H
89 uint32_t *dest_data = Dest->Data;
90 const uint32_t *src_data = Src->Data;
92 if( DX > Dest->W ) return ;
93 if( DY > Dest->H ) return ;
94 if( SX > Src->W ) return ;
95 if( SY > Src->H ) return ;
97 if( DX + W > Dest->W ) W = Dest->W - DX;
98 if( SX + W > Src->W ) W = Src->W - SX;
99 if( DY + H > Dest->H ) H = Dest->H - DY;
100 if( SY + H > Src->H ) H = Src->H - SY;
102 dest_data += (DY * Dest->W) + DX;
103 src_data += (SY * Src->W ) + SX;
104 for( int i = 0; i < H; i ++ )
106 memcpy( dest_data, src_data, W * 4 );
107 dest_data += Dest->W;
112 void _Fill(tFBBuffer *Buf, uint16_t X, uint16_t Y, uint16_t W, uint16_t H, uint32_t Colour)
114 uint32_t *data = Buf->Data;
116 if( X > Buf->W ) return ;
117 if( Y > Buf->H ) return ;
118 if( X + W > Buf->W ) W = Buf->W - X;
119 if( Y + H > Buf->H ) H = Buf->H - Y;
121 data += (Y * Buf->W) + X;
122 for( int i = 0; i < H; i ++ )
124 for( int j = 0; j < W; j ++ )
131 void _Handle_Commit(tWindow *Target, size_t Len, const void *Data)
133 // Do a window invalidate
136 void _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data)
138 const tFBMsg_NewBuf *msg = Data;
140 tFBWin *info = Target->RendererInfo;
142 if( Len < sizeof(*msg) ) return ;
144 if( msg->Buffer == -1 || msg->Buffer >= info->MaxBufferCount ) {
145 // Can't reallocate -1
149 if( info->Buffers[msg->Buffer] ) {
150 free(info->Buffers[msg->Buffer]);
151 info->Buffers[msg->Buffer] = NULL;
154 buf = malloc(sizeof(tFBBuffer) + msg->W * msg->H * 4);
157 buf->Data = buf->_data;
159 info->Buffers[msg->Buffer] = buf;
162 void _Handle_Upload(tWindow *Target, size_t Len, const void *Data)
164 const tFBMsg_Transfer *msg = Data;
165 tFBBuffer *dest, src;
167 if( Len < sizeof(*msg) ) return ;
168 if( Len < sizeof(*msg) + msg->W * msg->H * 4 ) return ;
170 dest = _GetBuffer(Target, msg->Buffer);
174 src.Data = (void*)msg->ImageData;
176 _Blit( dest, msg->X, msg->Y, &src, 0, 0, msg->W, msg->H );
179 void _Handle_Download(tWindow *Target, size_t Len, const void *Data)
182 const tFBMsg_Transfer *msg = Data;
183 tFBBuffer dest, *src;
185 if( Len < sizeof(*msg) ) return ;
186 if( Len < sizeof(*msg) + msg->W * msg->H * 4 ) return ;
188 src = _GetBuffer(Target, msg->Buffer);
192 dest.Data = msg->ImageData;
194 _Blit( &dest, 0, 0, src, msg->X, msg->Y, msg->W, msg->H );
198 void _Handle_LocalBlit(tWindow *Target, size_t Len, const void *Data)
200 const tFBMsg_Blit *msg = Data;
201 tFBBuffer *dest, *src;
203 if( Len < sizeof(*msg) ) return ;
205 src = _GetBuffer(Target, msg->Source);
206 dest = _GetBuffer(Target, msg->Dest);
208 _Blit( dest, msg->DstX, msg->DstY, src, msg->SrcX, msg->SrcY, msg->W, msg->H );
211 void _Handle_FillRect(tWindow *Target, size_t Len, const void *Data)
213 const tFBMsg_Fill *msg = Data;
216 if( Len < sizeof(*msg) ) return ;
218 dest = _GetBuffer(Target, msg->Buffer);
220 _Fill( dest, msg->X, msg->Y, msg->W, msg->H, msg->Colour );
223 int Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
228 // Resize the framebuffer
231 // Messages that get passed on
232 case WNDMSG_MOUSEBTN:
235 // --- Local messages ---
236 // - Drawing completed, do an update
238 _Handle_Commit(Target, Len, Data);
240 // - New Buffer (create a new server-side buffer)
242 _Handle_CreateBuf(Target, Len, Data);
244 // - Upload (Transfer data from client to server)
246 _Handle_Upload(Target, Len, Data);
248 // - Download (Transfer image data from server to client)
249 case MSG_FB_DOWNLOAD:
250 _Handle_Download(Target, Len, Data);
252 // - Local Blit (Transfer from server to server)
254 _Handle_LocalBlit(Target, Len, Data);
256 // - Fill a rectangle
258 _Handle_FillRect(Target, Len, Data);