Modules/UDI - (minor) tiny fiddle to udic planning
[tpg/acess2.git] / Usermode / Applications / axwin3_src / WM / renderers / framebuffer.c
1 /*
2  * Acess2 Window Manager v3
3  * - By John Hodge (thePowersGang)
4  *
5  * renderer_passthru.c
6  * - Passthrough window render (framebuffer essentially)
7  */
8 #include <common.h>
9 #include <wm_renderer.h>
10 #include <string.h>
11 #include <framebuffer_messages.h>
12 #include <wm_messages.h>
13
14 // === TYPES ===
15 typedef struct
16 {
17         short   W, H;
18         void    *Data;
19 } tFBBuffer;
20 typedef struct
21 {
22         tFBBuffer       BackBuffer;
23          int    MaxBufferCount;
24         tFBBuffer       *Buffers[];
25 } tFBWin;
26
27 // === PROTOTYPES ===
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);
33
34 // === GLOBALS ===
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,
41         .IPCHandlers = {
42                 [IPC_FB_COMMIT] = _Handle_Commit,
43                 [IPC_FB_NEWBUF] = _Handle_CreateBuf,
44                 //[IPC_FB_SUBBUF] = _Handle_SubBuf,
45         }
46 };
47
48 // === CODE ===
49 int Renderer_Framebuffer_Init(void)
50 {
51         WM_RegisterRenderer(&gRenderer_Framebuffer);
52         return 0;
53 }
54
55 tWindow *Renderer_Framebuffer_Create(int Flags)
56 {
57         tWindow *ret;
58         tFBWin  *info;
59         const int       max_buffers = 10;       // TODO: Have this be configurable
60         
61         ret = WM_CreateWindowStruct( sizeof(*info) + max_buffers*sizeof(tFBBuffer*) );
62         info = ret->RendererInfo;
63         
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 );
69         
70         return ret;
71 }
72
73 void Renderer_Framebuffer_Redraw(tWindow *Window)
74 {
75         
76 }
77
78 // --- ---
79 tFBBuffer *_GetBuffer(tWindow *Win, uint16_t ID)
80 {
81         tFBWin  *info = Win->RendererInfo;
82         if( ID == 0xFFFF )
83                 return &info->BackBuffer;
84         else if( ID >= info->MaxBufferCount )
85                 return NULL;
86         else
87                 return info->Buffers[ ID ];
88 }
89
90 void _Blit(
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
94         )
95 {
96         uint32_t        *dest_data = Dest->Data;
97         const uint32_t  *src_data = Src->Data;
98         // First, some sanity
99         if( DX > Dest->W )      return ;
100         if( DY > Dest->H )      return ;
101         if( SX > Src->W )       return ;
102         if( SY > Src->H )       return ;
103         
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;
108         
109         dest_data += (DY * Dest->W) + DX;
110         src_data  += (SY * Src->W ) + SX;
111         for( int i = 0; i < H; i ++ )
112         {
113                 memcpy( dest_data, src_data, W * 4 );
114                 dest_data += Dest->W;
115                 src_data += Src->W;
116         }
117 }
118
119 void _Fill(tFBBuffer *Buf, uint16_t X, uint16_t Y, uint16_t W, uint16_t H, uint32_t Colour)
120 {
121         uint32_t        *data = Buf->Data;
122         
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;
127         
128         data += (Y * Buf->W) + X;
129         for( int i = 0; i < H; i ++ )
130         {
131                 for( int j = 0; j < W; j ++ )
132                         *data++ = Colour;
133                 data += Buf->W - W;
134         }
135 }
136
137 // --- ---
138 int _Handle_Commit(tWindow *Target, size_t Len, const void *Data)
139 {
140         // Do a window invalidate
141         return 0;
142 }
143
144 int _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data)
145 {
146         const tFBIPC_NewBuf     *msg = Data;
147         tFBBuffer       *buf;
148         tFBWin  *info = Target->RendererInfo;
149         
150         if( Len < sizeof(*msg) )        return -1;
151         
152         if( msg->Buffer == -1 || msg->Buffer >= info->MaxBufferCount ) {
153                 // Can't reallocate -1
154                 return 1;
155         }
156         
157         if( info->Buffers[msg->Buffer] ) {
158                 free(info->Buffers[msg->Buffer]);
159                 info->Buffers[msg->Buffer] = NULL;
160         }
161         
162         buf = malloc(sizeof(tFBBuffer) + msg->W * msg->H * 4);
163         buf->W = msg->W;
164         buf->H = msg->H;
165         buf->Data = buf + 1;
166         
167         info->Buffers[msg->Buffer] = buf;
168         
169         return 0;
170 }
171
172 int _Handle_Upload(tWindow *Target, size_t Len, const void *Data)
173 {
174         const tFBIPC_Transfer   *msg = Data;
175         tFBBuffer       *dest, src;
176         
177         if( Len < sizeof(*msg) )        return -1;
178         if( Len < sizeof(*msg) + msg->W * msg->H * 4 )  return -1;
179         
180         dest = _GetBuffer(Target, msg->Buffer);
181
182         src.W = msg->W; 
183         src.H = msg->H; 
184         src.Data = (void*)msg->ImageData;
185
186         _Blit( dest, msg->X, msg->Y,  &src, 0, 0,  msg->W, msg->H );
187         return 0;
188 }
189
190 int _Handle_Download(tWindow *Target, size_t Len, const void *Data)
191 {
192         const tFBIPC_Transfer   *msg = Data;
193         tFBBuffer       dest, *src;
194         
195         if( Len < sizeof(*msg) )        return -1;
196         
197         src = _GetBuffer(Target, msg->Buffer);
198
199         tFBIPC_Transfer *ret;
200          int    retlen = sizeof(*ret) + msg->W*msg->H*4;
201         ret = malloc( retlen );
202
203         dest.W = ret->W = msg->W;
204         dest.H = ret->H = msg->H;
205         dest.Data = ret->ImageData;
206         
207         _Blit( &dest, 0, 0,  src, msg->X, msg->Y,  msg->W, msg->H );
208
209         WM_SendIPCReply(Target, IPC_FB_DOWNLOAD, retlen, ret);
210
211         free(ret);
212
213         return 0;
214 }
215
216 int _Handle_LocalBlit(tWindow *Target, size_t Len, const void *Data)
217 {
218         const tFBIPC_Blit       *msg = Data;
219         tFBBuffer       *dest, *src;
220         
221         if( Len < sizeof(*msg) )        return -1;
222         
223         src = _GetBuffer(Target, msg->Source);
224         dest = _GetBuffer(Target, msg->Dest);
225
226         _Blit( dest, msg->DstX, msg->DstY,  src, msg->SrcX, msg->SrcY,  msg->W, msg->H );
227         return 0;
228 }
229
230 int _Handle_FillRect(tWindow *Target, size_t Len, const void *Data)
231 {
232         const tFBIPC_Fill       *msg = Data;
233         tFBBuffer       *dest;
234         
235         if( Len < sizeof(*msg) )        return -1;
236         
237         dest = _GetBuffer(Target, msg->Buffer);
238         
239         _Fill( dest, msg->X, msg->Y, msg->W, msg->H, msg->Colour );
240         return 0;
241 }
242
243 int Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
244 {
245         switch(Msg)
246         {
247         case WNDMSG_RESIZE:
248                 // Resize the framebuffer
249                 return 1;       // Pass on
250         
251         // Messages that get passed on
252         case WNDMSG_MOUSEBTN:
253                 return 1;
254         }
255         return 1;
256 }
257
258

UCC git Repository :: git.ucc.asn.au