Usermode/AxWin3 - Working on a bitmap/framebuffer window type
authorJohn Hodge <[email protected]>
Sun, 20 May 2012 08:30:48 +0000 (16:30 +0800)
committerJohn Hodge <[email protected]>
Sun, 20 May 2012 08:30:48 +0000 (16:30 +0800)
Usermode/Applications/axwin3_src/WM/main.c
Usermode/Applications/axwin3_src/WM/renderers/passthru.c
Usermode/Applications/axwin3_src/include/framebuffer_messages.h [new file with mode: 0644]

index 0d15046..66fe14e 100644 (file)
@@ -16,6 +16,7 @@ extern void   WM_Initialise(void);
 extern int     Renderer_Menu_Init(void);
 extern int     Renderer_Widget_Init(void);
 extern int     Renderer_Background_Init(void);
+extern int     Renderer_Framebuffer_Init(void);
 extern void    WM_Update(void);
 
 // === PROTOTYPES ===
@@ -59,6 +60,7 @@ int main(int argc, char *argv[])
        Renderer_Menu_Init();
        Renderer_Widget_Init();
        Renderer_Background_Init();
+       Renderer_Framebuffer_Init();
        WM_Initialise();
        
        // Spawn interface root
index 9cd112c..c8d61cf 100644 (file)
  */
 #include <common.h>
 #include <wm_renderer.h>
+#include <string.h>
+#include <framebuffer_messages.h>
+#include <wm_messages.h>
+
+// === TYPES ===
+typedef struct
+{
+       short   W, H;
+       void    *Data;
+       char    _data[];
+} tFBBuffer;
+typedef struct
+{
+       tFBBuffer       BackBuffer;
+        int    MaxBufferCount;
+       tFBBuffer       *Buffers[];
+} tFBWin;
 
 // === PROTOTYPES ===
-tWindow        *Renderer_Passthru_Create(int Flags);
-void   Renderer_Passthru_Redraw(tWindow *Window);
- int   Renderer_Passthru_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data);
+tWindow        *Renderer_Framebuffer_Create(int Flags);
+void   Renderer_Framebuffer_Redraw(tWindow *Window);
+ int   Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data);
 
 // === GLOBALS ===
-tWMRenderer    gRenderer_Passthru = {
-       .Name = "Passthru",
-       .CreateWindow = Renderer_Passthru_Create,
-       .Redraw = Renderer_Passthru_Redraw,
-       .HandleMessage = Renderer_Passthru_HandleMessage
+tWMRenderer    gRenderer_Framebuffer = {
+       .Name = "FrameBuffer",
+       .CreateWindow = Renderer_Framebuffer_Create,
+       .Redraw = Renderer_Framebuffer_Redraw,
+       .HandleMessage = Renderer_Framebuffer_HandleMessage
 };
 
 // === CODE ===
-int Renderer_Passthru_Init(void)
+int Renderer_Framebuffer_Init(void)
 {
+       WM_RegisterRenderer(&gRenderer_Framebuffer);
        return 0;
 }
 
-tWindow        *Renderer_Passthru_Create(int Flags)
+tWindow        *Renderer_Framebuffer_Create(int Flags)
+{
+       tWindow *ret;
+       tFBWin  *info;
+       const int       max_buffers = 10;       // TODO: Have this be configurable
+       
+       ret = WM_CreateWindowStruct( sizeof(*info) + max_buffers*sizeof(tFBBuffer*) );
+       info = ret->RendererInfo;
+       
+       info->BackBuffer.W = 0;
+       info->BackBuffer.H = 0;
+       info->BackBuffer.Data = NULL;
+       info->MaxBufferCount = max_buffers;
+       memset( info->Buffers, 0, sizeof(tFBBuffer*) * max_buffers );
+       
+       return ret;
+}
+
+void Renderer_Framebuffer_Redraw(tWindow *Window)
+{
+       
+}
+
+// --- ---
+tFBBuffer *_GetBuffer(tWindow *Win, uint16_t ID)
+{
+       tFBWin  *info = Win->RendererInfo;
+       if( ID == 0xFFFF )
+               return &info->BackBuffer;
+       else if( ID >= info->MaxBufferCount )
+               return NULL;
+       else
+               return info->Buffers[ ID ];
+}
+
+void _Blit(
+       tFBBuffer *Dest, uint16_t DX, uint16_t DY,
+       const tFBBuffer *Src, uint16_t SX, uint16_t SY,
+       uint16_t W, uint16_t H
+       )
+{
+       uint32_t        *dest_data = Dest->Data;
+       const uint32_t  *src_data = Src->Data;
+       // First, some sanity
+       if( DX > Dest->W )      return ;
+       if( DY > Dest->H )      return ;
+       if( SX > Src->W )       return ;
+       if( SY > Src->H )       return ;
+       
+       if( DX + W > Dest->W )  W = Dest->W - DX;
+       if( SX + W > Src->W )   W = Src->W - SX;
+       if( DY + H > Dest->H )  H = Dest->H - DY;
+       if( SY + H > Src->H )   H = Src->H - SY;
+       
+       dest_data += (DY * Dest->W) + DX;
+       src_data  += (SY * Src->W ) + SX;
+       for( int i = 0; i < H; i ++ )
+       {
+               memcpy( dest_data, src_data, W * 4 );
+               dest_data += Dest->W;
+               src_data += Src->W;
+       }
+}
+
+void _Fill(tFBBuffer *Buf, uint16_t X, uint16_t Y, uint16_t W, uint16_t H, uint32_t Colour)
+{
+       uint32_t        *data = Buf->Data;
+       
+       if( X > Buf->W )        return ;
+       if( Y > Buf->H )        return ;
+       if( X + W > Buf->W )    W = Buf->W - X;
+       if( Y + H > Buf->H )    H = Buf->H - Y;
+       
+       data += (Y * Buf->W) + X;
+       for( int i = 0; i < H; i ++ )
+       {
+               for( int j = 0; j < W; j ++ )
+                       *data++ = Colour;
+               data += Buf->W - W;
+       }
+}
+
+// --- ---
+void _Handle_Commit(tWindow *Target, size_t Len, const void *Data)
+{
+       // Do a window invalidate
+}
+
+void _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data)
 {
-       return NULL;
+       const tFBMsg_NewBuf     *msg = Data;
+       tFBBuffer       *buf;
+       tFBWin  *info = Target->RendererInfo;
+       
+       if( Len < sizeof(*msg) )        return ;
+       
+       if( msg->Buffer == -1 || msg->Buffer >= info->MaxBufferCount ) {
+               // Can't reallocate -1
+               return ;
+       }
+       
+       if( info->Buffers[msg->Buffer] ) {
+               free(info->Buffers[msg->Buffer]);
+               info->Buffers[msg->Buffer] = NULL;
+       }
+       
+       buf = malloc(sizeof(tFBBuffer) + msg->W * msg->H * 4);
+       buf->W = msg->W;
+       buf->H = msg->H;
+       buf->Data = buf->_data;
+       
+       info->Buffers[msg->Buffer] = buf;
 }
 
-void Renderer_Passthru_Redraw(tWindow *Window)
+void _Handle_Upload(tWindow *Target, size_t Len, const void *Data)
 {
+       const tFBMsg_Transfer   *msg = Data;
+       tFBBuffer       *dest, src;
+       
+       if( Len < sizeof(*msg) )        return ;
+       if( Len < sizeof(*msg) + msg->W * msg->H * 4 )  return ;
+       
+       dest = _GetBuffer(Target, msg->Buffer);
+
+       src.W = msg->W; 
+       src.H = msg->H; 
+       src.Data = (void*)msg->ImageData;
+
+       _Blit( dest, msg->X, msg->Y,  &src, 0, 0,  msg->W, msg->H );
+}
+
+void _Handle_Download(tWindow *Target, size_t Len, const void *Data)
+{
+       #if 0
+       const tFBMsg_Transfer   *msg = Data;
+       tFBBuffer       dest, *src;
+       
+       if( Len < sizeof(*msg) )        return ;
+       if( Len < sizeof(*msg) + msg->W * msg->H * 4 )  return ;
+       
+       src = _GetBuffer(Target, msg->Buffer);
+
+       dest.W = msg->W;        
+       dest.H = msg->H;        
+       dest.Data = msg->ImageData;
        
+       _Blit( &dest, 0, 0,  src, msg->X, msg->Y,  msg->W, msg->H );
+       #endif
 }
 
-int Renderer_Passthru_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
+void _Handle_LocalBlit(tWindow *Target, size_t Len, const void *Data)
 {
+       const tFBMsg_Blit       *msg = Data;
+       tFBBuffer       *dest, *src;
+       
+       if( Len < sizeof(*msg) )        return ;
+       
+       src = _GetBuffer(Target, msg->Source);
+       dest = _GetBuffer(Target, msg->Dest);
+
+       _Blit( dest, msg->DstX, msg->DstY,  src, msg->SrcX, msg->SrcY,  msg->W, msg->H );
+}
+
+void _Handle_FillRect(tWindow *Target, size_t Len, const void *Data)
+{
+       const tFBMsg_Fill       *msg = Data;
+       tFBBuffer       *dest;
+       
+       if( Len < sizeof(*msg) )        return ;
+       
+       dest = _GetBuffer(Target, msg->Buffer);
+       
+       _Fill( dest, msg->X, msg->Y, msg->W, msg->H, msg->Colour );
+}
+
+int Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
+{
+       switch(Msg)
+       {
+       case WNDMSG_RESIZE:
+               // Resize the framebuffer
+               return 1;       // Pass on
+       
+       // Messages that get passed on
+       case WNDMSG_MOUSEBTN:
+               return 1;
+       
+       // --- Local messages ---
+       // - Drawing completed, do an update
+       case MSG_FB_COMMIT:
+               _Handle_Commit(Target, Len, Data);
+               return 0;
+       // - New Buffer (create a new server-side buffer)
+       case MSG_FB_NEWBUF:
+               _Handle_CreateBuf(Target, Len, Data);
+               return 0;
+       // - Upload (Transfer data from client to server)
+       case MSG_FB_UPLOAD:
+               _Handle_Upload(Target, Len, Data);
+               return 0;
+       // - Download (Transfer image data from server to client)
+       case MSG_FB_DOWNLOAD:
+               _Handle_Download(Target, Len, Data);
+               return 0;
+       // - Local Blit (Transfer from server to server)
+       case MSG_FB_BLIT:
+               _Handle_LocalBlit(Target, Len, Data);
+               return 0;
+       // - Fill a rectangle
+       case MSG_FB_FILL:
+               _Handle_FillRect(Target, Len, Data);
+               return 0;
+       }
        return 1;
 }
 
diff --git a/Usermode/Applications/axwin3_src/include/framebuffer_messages.h b/Usermode/Applications/axwin3_src/include/framebuffer_messages.h
new file mode 100644 (file)
index 0000000..034999b
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Acess2 Window Manager v3
+ * - By John Hodge (thePowersGang)
+ *
+ * framebuffer_messages.h
+ * - Drawing Surface / Framebuffer Window Type
+ */
+#ifndef _AXWIN3__FRAMEBUFFER_MESSAGES_H_
+#define _AXWIN3__FRAMEBUFFER_MESSAGES_H_
+
+enum
+{
+       MSG_FB_COMMIT = 0x1000,
+       MSG_FB_NEWBUF,
+       MSG_FB_UPLOAD,
+       MSG_FB_DOWNLOAD,
+       MSG_FB_BLIT,
+       MSG_FB_FILL
+};
+
+typedef struct
+{
+       uint16_t        Buffer;
+       uint16_t        W, H;
+} tFBMsg_NewBuf;
+
+typedef struct
+{
+       uint16_t        Buffer;
+       uint16_t        W, H;
+       uint16_t        X, Y;
+       uint32_t        ImageData[];
+} tFBMsg_Transfer;
+
+typedef struct
+{
+       uint16_t        Source;
+       uint16_t        Dest;
+       uint16_t        SrcX, SrcY;
+       uint16_t        DstX, DstY;
+       uint16_t        W, H;
+} tFBMsg_Blit;
+
+typedef struct
+{
+       uint16_t        Buffer;
+       uint16_t        X, Y;
+       uint16_t        W, H;
+       uint32_t        Colour;
+} tFBMsg_Fill;
+
+#endif
+

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