Merge branch 'master' of git://localhost/acess2
[tpg/acess2.git] / Usermode / Applications / axwin3_src / WM / renderers / passthru.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         char    _data[];
20 } tFBBuffer;
21 typedef struct
22 {
23         tFBBuffer       BackBuffer;
24          int    MaxBufferCount;
25         tFBBuffer       *Buffers[];
26 } tFBWin;
27
28 // === PROTOTYPES ===
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);
32
33 // === GLOBALS ===
34 tWMRenderer     gRenderer_Framebuffer = {
35         .Name = "FrameBuffer",
36         .CreateWindow = Renderer_Framebuffer_Create,
37         .Redraw = Renderer_Framebuffer_Redraw,
38         .HandleMessage = Renderer_Framebuffer_HandleMessage
39 };
40
41 // === CODE ===
42 int Renderer_Framebuffer_Init(void)
43 {
44         WM_RegisterRenderer(&gRenderer_Framebuffer);
45         return 0;
46 }
47
48 tWindow *Renderer_Framebuffer_Create(int Flags)
49 {
50         tWindow *ret;
51         tFBWin  *info;
52         const int       max_buffers = 10;       // TODO: Have this be configurable
53         
54         ret = WM_CreateWindowStruct( sizeof(*info) + max_buffers*sizeof(tFBBuffer*) );
55         info = ret->RendererInfo;
56         
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 );
62         
63         return ret;
64 }
65
66 void Renderer_Framebuffer_Redraw(tWindow *Window)
67 {
68         
69 }
70
71 // --- ---
72 tFBBuffer *_GetBuffer(tWindow *Win, uint16_t ID)
73 {
74         tFBWin  *info = Win->RendererInfo;
75         if( ID == 0xFFFF )
76                 return &info->BackBuffer;
77         else if( ID >= info->MaxBufferCount )
78                 return NULL;
79         else
80                 return info->Buffers[ ID ];
81 }
82
83 void _Blit(
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
87         )
88 {
89         uint32_t        *dest_data = Dest->Data;
90         const uint32_t  *src_data = Src->Data;
91         // First, some sanity
92         if( DX > Dest->W )      return ;
93         if( DY > Dest->H )      return ;
94         if( SX > Src->W )       return ;
95         if( SY > Src->H )       return ;
96         
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;
101         
102         dest_data += (DY * Dest->W) + DX;
103         src_data  += (SY * Src->W ) + SX;
104         for( int i = 0; i < H; i ++ )
105         {
106                 memcpy( dest_data, src_data, W * 4 );
107                 dest_data += Dest->W;
108                 src_data += Src->W;
109         }
110 }
111
112 void _Fill(tFBBuffer *Buf, uint16_t X, uint16_t Y, uint16_t W, uint16_t H, uint32_t Colour)
113 {
114         uint32_t        *data = Buf->Data;
115         
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;
120         
121         data += (Y * Buf->W) + X;
122         for( int i = 0; i < H; i ++ )
123         {
124                 for( int j = 0; j < W; j ++ )
125                         *data++ = Colour;
126                 data += Buf->W - W;
127         }
128 }
129
130 // --- ---
131 void _Handle_Commit(tWindow *Target, size_t Len, const void *Data)
132 {
133         // Do a window invalidate
134 }
135
136 void _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data)
137 {
138         const tFBMsg_NewBuf     *msg = Data;
139         tFBBuffer       *buf;
140         tFBWin  *info = Target->RendererInfo;
141         
142         if( Len < sizeof(*msg) )        return ;
143         
144         if( msg->Buffer == -1 || msg->Buffer >= info->MaxBufferCount ) {
145                 // Can't reallocate -1
146                 return ;
147         }
148         
149         if( info->Buffers[msg->Buffer] ) {
150                 free(info->Buffers[msg->Buffer]);
151                 info->Buffers[msg->Buffer] = NULL;
152         }
153         
154         buf = malloc(sizeof(tFBBuffer) + msg->W * msg->H * 4);
155         buf->W = msg->W;
156         buf->H = msg->H;
157         buf->Data = buf->_data;
158         
159         info->Buffers[msg->Buffer] = buf;
160 }
161
162 void _Handle_Upload(tWindow *Target, size_t Len, const void *Data)
163 {
164         const tFBMsg_Transfer   *msg = Data;
165         tFBBuffer       *dest, src;
166         
167         if( Len < sizeof(*msg) )        return ;
168         if( Len < sizeof(*msg) + msg->W * msg->H * 4 )  return ;
169         
170         dest = _GetBuffer(Target, msg->Buffer);
171
172         src.W = msg->W; 
173         src.H = msg->H; 
174         src.Data = (void*)msg->ImageData;
175
176         _Blit( dest, msg->X, msg->Y,  &src, 0, 0,  msg->W, msg->H );
177 }
178
179 void _Handle_Download(tWindow *Target, size_t Len, const void *Data)
180 {
181         #if 0
182         const tFBMsg_Transfer   *msg = Data;
183         tFBBuffer       dest, *src;
184         
185         if( Len < sizeof(*msg) )        return ;
186         if( Len < sizeof(*msg) + msg->W * msg->H * 4 )  return ;
187         
188         src = _GetBuffer(Target, msg->Buffer);
189
190         dest.W = msg->W;        
191         dest.H = msg->H;        
192         dest.Data = msg->ImageData;
193         
194         _Blit( &dest, 0, 0,  src, msg->X, msg->Y,  msg->W, msg->H );
195         #endif
196 }
197
198 void _Handle_LocalBlit(tWindow *Target, size_t Len, const void *Data)
199 {
200         const tFBMsg_Blit       *msg = Data;
201         tFBBuffer       *dest, *src;
202         
203         if( Len < sizeof(*msg) )        return ;
204         
205         src = _GetBuffer(Target, msg->Source);
206         dest = _GetBuffer(Target, msg->Dest);
207
208         _Blit( dest, msg->DstX, msg->DstY,  src, msg->SrcX, msg->SrcY,  msg->W, msg->H );
209 }
210
211 void _Handle_FillRect(tWindow *Target, size_t Len, const void *Data)
212 {
213         const tFBMsg_Fill       *msg = Data;
214         tFBBuffer       *dest;
215         
216         if( Len < sizeof(*msg) )        return ;
217         
218         dest = _GetBuffer(Target, msg->Buffer);
219         
220         _Fill( dest, msg->X, msg->Y, msg->W, msg->H, msg->Colour );
221 }
222
223 int Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
224 {
225         switch(Msg)
226         {
227         case WNDMSG_RESIZE:
228                 // Resize the framebuffer
229                 return 1;       // Pass on
230         
231         // Messages that get passed on
232         case WNDMSG_MOUSEBTN:
233                 return 1;
234         
235         // --- Local messages ---
236         // - Drawing completed, do an update
237         case MSG_FB_COMMIT:
238                 _Handle_Commit(Target, Len, Data);
239                 return 0;
240         // - New Buffer (create a new server-side buffer)
241         case MSG_FB_NEWBUF:
242                 _Handle_CreateBuf(Target, Len, Data);
243                 return 0;
244         // - Upload (Transfer data from client to server)
245         case MSG_FB_UPLOAD:
246                 _Handle_Upload(Target, Len, Data);
247                 return 0;
248         // - Download (Transfer image data from server to client)
249         case MSG_FB_DOWNLOAD:
250                 _Handle_Download(Target, Len, Data);
251                 return 0;
252         // - Local Blit (Transfer from server to server)
253         case MSG_FB_BLIT:
254                 _Handle_LocalBlit(Target, Len, Data);
255                 return 0;
256         // - Fill a rectangle
257         case MSG_FB_FILL:
258                 _Handle_FillRect(Target, Len, Data);
259                 return 0;
260         }
261         return 1;
262 }
263
264

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