axwin2 - Working on GUI, implemented image loading
authorJohn Hodge <[email protected]>
Sun, 27 Feb 2011 10:44:54 +0000 (18:44 +0800)
committerJohn Hodge <[email protected]>
Sun, 27 Feb 2011 10:44:54 +0000 (18:44 +0800)
- Also fixed URI/URL handling code (needs correctness though)

13 files changed:
Usermode/Applications/axwin2_src/Makefile [new file with mode: 0644]
Usermode/Applications/axwin2_src/WM/Makefile
Usermode/Applications/axwin2_src/WM/decorator.c
Usermode/Applications/axwin2_src/WM/image.c
Usermode/Applications/axwin2_src/WM/interface.c
Usermode/Applications/axwin2_src/WM/video.c
Usermode/Applications/axwin2_src/WM/wm.c
Usermode/Applications/axwin2_src/WM/wm.h
Usermode/Libraries/libimage_sif.so_src/main.c
Usermode/Libraries/liburi.so_src/main.c
Usermode/include/axwin/axwin.h
Usermode/include/image.h [new file with mode: 0644]
Usermode/include/uri.h

diff --git a/Usermode/Applications/axwin2_src/Makefile b/Usermode/Applications/axwin2_src/Makefile
new file mode 100644 (file)
index 0000000..e47c829
--- /dev/null
@@ -0,0 +1,4 @@
+
+%:
+       $(MAKE) -C WM/ $@
+       $(MAKE) -C Shell_src/ $@
index 154d2cf..d740d1c 100644 (file)
@@ -10,4 +10,13 @@ OBJ := main.o helpers.o commandline.o video.o video_text.o
 OBJ += messages.o interface.o wm.o decorator.o
 OBJ += image.o
 
+LDFLAGS += -limage_sif -luri
+
 -include ../../Makefile.tpl
+
+all: resources/LogoSmall.sif.res.h
+
+%.res.h: % Makefile
+       echo "#define RESOURCE_$(notdir $<) \\"| sed -e 's/\./_/g' > $@
+       base64 $< | sed -e 's/.*/"&"\\/' >> $@
+       echo "" >> $@
index c224d6f..9eb6a62 100644 (file)
@@ -7,6 +7,8 @@
 #include "common.h"
 #include "wm.h"
 
+#define BORDER_EVERYTHING      1
+
 #define BOX_BGCOLOUR    0xC0C0C0
 #define BOX_BORDER      0xA0A0A0
 #define BUTTON_BGCOLOUR 0xD0D0D0
@@ -22,6 +24,13 @@ void Decorator_RenderWidget(tElement *Element)
                Element->CachedW, Element->CachedH
                );
        
+       #if BORDER_EVERYTHING
+       Video_DrawRect(Element->CachedX, Element->CachedY,
+                       Element->CachedW, Element->CachedH,
+                       0
+                       );
+       #endif
+       
        switch(Element->Type)
        {
        case ELETYPE_NONE:
index eab1d0e..1d7d343 100644 (file)
 // === IMPORTS ===
 extern tImage *Image_SIF_Parse(void *Buffer, size_t Size);
 
+// === PROTOTYPES ===
+ int   UnBase64(uint8_t *Dest, char *Src, int BufSize);
+
 // === CODE ===
 /**
  * \brief Open an image from a URI
  */
 tImage *Image_Load(const char *URI)
 {
-       #if 0
        tURI    *uri;
         int    filesize;
        void    *buf;
        tImage  *img;
-       void    *fp;
        
        uri = URI_Parse(URI);
-       
-       fp = URI_Open(URI_MODE_READ, uri);
-       if(!fp) return NULL;
-       free(uri);
-       
-       filesize = URI_GetSize(fp);
-       buf = malloc( filesize );
-       if(!buf) {
-               URI_Close(fp);
+       if( !uri ) {
+               _SysDebug("Image_Load: Unable parse as URI '%s'\n", URI);
                return NULL;
        }
        
-       URI_Read(fp, filesize, buf);
-       URI_Close(fp);
+       if( strcmp(uri->Proto, "file") == 0 )
+       {
+               FILE    *fp;
+               fp = fopen(uri->Path, "rb");
+               if(!fp) {
+                       _SysDebug("Image_Load: Unable to open '%s'\n", uri->Path);
+                       free(uri);
+                       return NULL;
+               }
+               
+               fseek(fp, 0, SEEK_END);
+               filesize = ftell(fp);
+               buf = malloc( filesize );
+               if(!buf) {
+                       _SysDebug("Image_Load: malloc() failed!\n");
+                       fclose(fp);
+                       free(uri);
+                       return NULL;
+               }
+               
+               fread(buf, filesize, 1, buf);
+               fclose(fp);
+       }
+       else if( strcmp(uri->Proto, "base64") == 0 )
+       {
+               // 4 bytes of base64 = 3 bytes of binary (base 256)
+               filesize = strlen( uri->Path ) * 3 / 4;
+               buf = malloc(filesize);
+               if(!buf) {
+                       _SysDebug("Image_Load: malloc() failed!\n");
+                       free(uri);
+                       return NULL;
+               }
+               
+               filesize = UnBase64(buf, uri->Path, filesize);
+       }
+       else
+       {
+               _SysDebug("Image_Load: Unknow protocol '%s'\n", uri->Proto);
+               free(uri);
+               return NULL;
+       }
        
        img = Image_SIF_Parse(buf, filesize);
        free(buf);
+       free(uri);
+       if( !img ) {
+               _SysDebug("Image_Load: Unable to parse SIF from '%s'\n", URI);
+               return NULL;
+       }
        
        return img;
-       #else
-       return NULL;
-       #endif
+}
+
+/**
+ * \brief Decode a Base64 value
+ */
+int UnBase64(uint8_t *Dest, char *Src, int BufSize)
+{
+       uint32_t        val;
+        int    i, j;
+       char    *start_src = Src;
+       
+       for( i = 0; i+2 < BufSize; i += 3 )
+       {
+               val = 0;
+               for( j = 0; j < 4; j++, Src ++ ) {
+                       if('A' <= *Src && *Src <= 'Z')
+                               val |= (*Src - 'A') << ((3-j)*6);
+                       else if('a' <= *Src && *Src <= 'z')
+                               val |= (*Src - 'a' + 26) << ((3-j)*6);
+                       else if('0' <= *Src && *Src <= '9')
+                               val |= (*Src - '0' + 52) << ((3-j)*6);
+                       else if(*Src == '+')
+                               val |= 62 << ((3-j)*6);
+                       else if(*Src == '/')
+                               val |= 63 << ((3-j)*6);
+                       else if(!*Src)
+                               break;
+                       else if(*Src != '=')
+                               j --;   // Ignore invalid characters
+               }
+               Dest[i  ] = (val >> 16) & 0xFF;
+               Dest[i+1] = (val >> 8) & 0xFF;
+               Dest[i+2] = val & 0xFF;
+               if(j != 4)      break;
+       }
+       
+       // Finish things off
+       if(i   < BufSize)
+               Dest[i] = (val >> 16) & 0xFF;
+       if(i+1 < BufSize)
+               Dest[i+1] = (val >> 8) & 0xFF;
+       
+       return Src - start_src;
 }
index d4ad424..630b1f4 100644 (file)
@@ -6,6 +6,7 @@
  * > Main Overarching UI
  */
 #include "common.h"
+#include "resources/LogoSmall.sif.res.h"
 
 // === GLOBALS ==
  int   giInterface_Width = 0;
@@ -17,6 +18,7 @@ tElement      *gpInterface_MainArea;
 tElement       *gpInterface_HeaderBar;
 tElement       *gpInterface_TabBar;
 tElement       *gpInterface_TabContent;
+const char     csLogoSmall[] = "base64:///"RESOURCE_LogoSmall_sif;
 
 // === CODE ===
 /**
@@ -41,9 +43,11 @@ void Interface_Init(void)
        btn = WM_CreateElement(gpInterface_Sidebar, ELETYPE_BUTTON, ELEFLAG_NOSTRETCH, "SystemMenu");
        WM_SetSize(btn, giInterface_Width-4);
        // TODO: Once image loading is implemented, switch to a logo
-       #if 0
-       text = WM_CreateElement(btn, ELETYPE_IMAGE, ELEFLAG_SCALE);
-       WM_SetText(text, "asset://LogoSmall.sif");
+       #if 1
+       //text = WM_CreateElement(btn, ELETYPE_IMAGE, ELEFLAG_SCALE);
+       text = WM_CreateElement(btn, ELETYPE_IMAGE, 0, "MenuLogo");
+       //WM_SetText(text, "file:///LogoSmall.sif");
+       WM_SetText(text, csLogoSmall);
        #else
        text = WM_CreateElement(btn, ELETYPE_TEXT, 0, NULL);
        WM_SetText(text, "Acess");
index 7e25360..5c60425 100644 (file)
@@ -104,7 +104,11 @@ void Video_DrawImage(short X, short Y, short W, short H, tImage *Image)
 {
         int    x, y;
        uint8_t *buf = (uint8_t *)(gpScreenBuffer + Y*giScreenWidth + X);
-       uint8_t *data = Image->Data;
+       uint8_t *data;
+       
+       // Sanity please
+       if( !Image )
+               return ;
        
        // Bounds Check
        if( X >= giScreenWidth )        return ;
@@ -118,6 +122,8 @@ void Video_DrawImage(short X, short Y, short W, short H, tImage *Image)
        if( X + W > giScreenWidth )     W = giScreenWidth - X;
        if( Y + H > giScreenHeight )    H = giScreenHeight - Y;
        
+       // Do the render
+       data = Image->Data;
        switch( Image->Format )
        {
        case IMGFMT_BGRA:
index ad441b3..f107ae7 100644 (file)
@@ -18,7 +18,7 @@ tElement      *WM_CreateElement(tElement *Parent, int Type, int Flags, const char *De
 void   WM_UpdateMinDims(tElement *Element);
 void   WM_SetFlags(tElement *Element, int Flags);
 void   WM_SetSize(tElement *Element, int Size);
-void   WM_SetText(tElement *Element, char *Text);
+void   WM_SetText(tElement *Element, const char *Text);
 void   WM_UpdateDimensions(tElement *Element, int Pass);
 void   WM_UpdatePosition(tElement *Element);
 void   WM_RenderWidget(tElement *Element);
@@ -100,7 +100,7 @@ void WM_SetSize(tElement *Element, int Size)
  * \brief Set the text field of an element
  * \note Used for the image path on ELETYPE_IMAGE
  */
-void WM_SetText(tElement *Element, char *Text)
+void WM_SetText(tElement *Element, const char *Text)
 {
        if(!Element)    return ;
        if(Element->Text)       free(Element->Text);
index 0f5edf2..cd4ab90 100644 (file)
@@ -145,6 +145,6 @@ enum eElementTypes
 extern tElement        *WM_CreateElement(tElement *Parent, int Type, int Flags, const char *DebugName);
 extern void    WM_SetFlags(tElement *Element, int Flags);
 extern void    WM_SetSize(tElement *Element, int Size);
-extern void    WM_SetText(tElement *Element, char *Text);
+extern void    WM_SetText(tElement *Element, const char *Text);
 
 #endif
index 7b076a3..4ce0a2d 100644 (file)
@@ -7,6 +7,17 @@
 #include <image.h>
 //#include <image_sif.h>
 
+// === STRUCTURES ===
+struct sHeader
+{
+       uint16_t        Magic;
+       uint16_t        Flags;
+       uint16_t        Width;
+       uint16_t        Height;
+};
+
+// === CONSTANTS ===
+
 // === CODE ===
 int SoMain(void)
 {
@@ -17,8 +28,6 @@ int SoMain(void)
  */
 tImage *Image_SIF_Parse(void *Buffer, size_t Size)
 {
-       uint16_t        magic;
-       uint16_t        flags;
        uint16_t        w, h;
         int    ofs, i;
        tImage  *ret;
@@ -26,25 +35,30 @@ tImage *Image_SIF_Parse(void *Buffer, size_t Size)
         int    fileOfs = 0;
         int    comp, fmt;
         int    sampleSize = 4;
+       struct sHeader  *hdr = Buffer;
+        
+       _SysDebug("Image_SIF_Parse: (Buffer=%p, Size=0x%x)", Buffer, Size);
        
        // Get magic word and determine byte ordering
-       magic = *(uint16_t*)Buffer+fileOfs;     fileOfs += 2;
-       if(magic == 0x51F0)
+       if(hdr->Magic == 0x51F0)        // Little Endian
                bRevOrder = 0;
-       else if(magic == 0xF051)
+       else if(hdr->Magic == 0xF051)   // Big Endian
                bRevOrder = 1;
        else {
                return NULL;
        }
        
+       _SysDebug(" Image_SIF_Parse: bRevOrder = %i", bRevOrder);
+       
        // Read flags
-       flags = *(uint16_t*)Buffer+fileOfs;     fileOfs += 2;
-       comp = flags & 7;
-       fmt = (flags >> 3) & 7;
+       comp = hdr->Flags & 7;
+       fmt = (hdr->Flags >> 3) & 7;
        
        // Read dimensions
-       w = *(uint16_t*)Buffer+fileOfs; fileOfs += 2;
-       h = *(uint16_t*)Buffer+fileOfs; fileOfs += 2;
+       w = hdr->Width;
+       h = hdr->Height;
+       
+       _SysDebug(" Image_SIF_Parse: Dimensions %ix%i", w, h);
        
        // Get image format
        switch(fmt)
@@ -58,10 +72,13 @@ tImage *Image_SIF_Parse(void *Buffer, size_t Size)
                sampleSize = 3;
                break;
        default:
-               free(ret);
                return NULL;
        }
        
+       _SysDebug(" Image_SIF_Parse: sampleSize = %i, fmt = %i", sampleSize, fmt);
+       
+       fileOfs = sizeof(struct sHeader);
+       
        // Allocate space
        ret = calloc(1, sizeof(tImage) + w * h * sampleSize);
        ret->Width = w;
index 2d785f3..57de6f6 100644 (file)
@@ -32,11 +32,12 @@ void        URI_Close(tURIFile *File);
 size_t URI_file_Read(int Handle, size_t Bytes, void *Buffer);
 size_t URI_file_Write(int Handle, size_t Bytes, void *Buffer);
 void   URI_file_Close(int Handle);
+size_t URI_file_GetSize(int Handle);
 
 // === CONSTANTS ===
 // Builtin URI protocol handlers
 tURIHandler    caBuiltinHandlers[] = {
-       {"file", 0, URI_file_Open, URI_file_Close, URI_file_Read, URI_file_Write}
+       {"file", 0, URI_file_Open, URI_file_Close, URI_file_Read, URI_file_Write, URI_file_GetSize}
 };
 #define NUM_BUILTIN_HANDLERS   (sizeof(caBuiltinHandlers)/sizeof(caBuiltinHandlers[0]))
 
@@ -55,7 +56,7 @@ tURI *URI_Parse(const char *String)
        if(!String)     return NULL;
        
        protolen = 0;
-       while( isalpha(*tmp)  tmp++, protolen++;
+       while( isalpha(*tmp) || isdigit(*tmp) ) tmp++, protolen++;
        
        // true URI
        if(tmp[0] == ':' && tmp[1] == '/' && tmp[2] == '/')
@@ -75,7 +76,7 @@ tURI *URI_Parse(const char *String)
                if( *tmp == '[' )
                {
                        tmp ++;
-                       while( *tmp != ']' ) {
+                       while( *tmp && *tmp != ']' ) {
                                ret->Host[hostlen] = *tmp;
                                tmp ++;
                                hostlen ++;
@@ -86,7 +87,7 @@ tURI *URI_Parse(const char *String)
                // IPv4/DNS
                else
                {
-                       while( *tmp != '/' && *tmp != ':' )
+                       while( *tmp && *tmp != '/' && *tmp != ':' )
                        {
                                ret->Host[hostlen] = *tmp;
                                tmp ++;
@@ -225,6 +226,19 @@ tURIFile *URI_Open(int Mode, tURI *URI)
        return ret;
 }
 
+int URI_GetSize(tURIFile *File, size_t *Size)
+{
+       if( !File || !Size )    return -1;
+       
+       if( File->Handler->GetSize )
+       {
+               *Size = File->Handler->GetSize(File->Handle);
+               return 0;       // Success
+       }
+       
+       return 1;       // Size not avaliable
+}
+
 /**
  * \brief Read from a URI file
  */
@@ -322,3 +336,12 @@ void URI_file_Close(int Handle)
 {
        close(Handle);
 }
+size_t URI_file_GetSize(int Handle)
+{
+       uint64_t curpos = tell(Handle);
+       size_t ret;
+       seek(Handle, 0, SEEK_END);
+       ret = tell(Handle);
+       seek(Handle, curpos, SEEK_SET);
+       return ret;
+}
index cacf1d8..71af36a 100644 (file)
@@ -11,6 +11,9 @@ typedef void  *tAxWin_Handle;
 
 // === Messaging ===
 #include "messages.h"
+
+extern int     AxWin_Register(const char *Name);
+
 extern int     AxWin_MessageLoop();
 extern int     AxWin_SendMessage(tAxWin_Message *Message);
 extern tAxWin_Message  *AxWin_WaitForMessage(void);
@@ -33,6 +36,7 @@ typedef int   tAxWin_MessageCallback(tAxWin_Message *);
 /**
  * \}
  */
+
 extern tAxWin_Window   *AxWin_CreateWindow(
                int16_t X, int16_t Y, int16_t W, int16_t H,
                uint32_t Flags, tAxWin_MessageCallback *Callback);
diff --git a/Usermode/include/image.h b/Usermode/include/image.h
new file mode 100644 (file)
index 0000000..69e1549
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ */
+#ifndef _IMAGE_H_
+#define _IMAGE_H_
+
+// === TYPES ===
+typedef struct sImage  tImage;
+struct sImage
+{
+       short   Width;
+       short   Height;
+        int    Format;
+       uint8_t Data[];
+};
+
+// === CONSTANTS ===
+enum eImageFormats
+{
+       IMGFMT_BGRA,
+       IMGFMT_RGB,
+       NUM_IMGFMTS
+};
+
+#endif
index 92956b0..20b4b4c 100644 (file)
@@ -33,11 +33,13 @@ struct sURIHandler
        void    (*Close)(int Handle);
        size_t  (*Read)(int Handle, size_t Bytes, void *Buffer);
        size_t  (*Write)(int Handle, size_t Bytes, void *Buffer);
+       size_t  (*GetSize)(int Handle);
 };
 
 // === FUNCTIONS ===
 extern tURI    *URI_Parse(const char *String);
 extern tURIFile        *URI_Open(int Mode, tURI *URI);
+extern int     URI_GetSize(tURIFile *File, size_t *Size);
 extern size_t  URI_Read(tURIFile *File, size_t Bytes, void *Buffer);
 extern size_t  URI_Write(tURIFile *File, size_t Bytes, void *Buffer);
 extern void    URI_Close(tURIFile *File);

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