Many changes, bugfixes to user vsnprintf and to escape code handling
authorJohn Hodge <[email protected]>
Fri, 30 Apr 2010 15:43:46 +0000 (23:43 +0800)
committerJohn Hodge <[email protected]>
Fri, 30 Apr 2010 15:43:46 +0000 (23:43 +0800)
- Added coloured messages to kernel output
- Implemented arguments to staticly compiled modules
- Updated VTerm to only change video modes when needed (not fully
  tested yet)
- Other misc changes to kernel
- Dramatic overhaul of AxWin, nearing completion

29 files changed:
Kernel/Makefile.BuildNum
Kernel/arch/x86/errors.c
Kernel/arch/x86/main.c
Kernel/arch/x86/time.c
Kernel/drv/vterm.c
Kernel/include/acess.h
Kernel/include/tpl_drv_video.h
Kernel/lib.c
Kernel/logging.c
Kernel/modules.c
Kernel/system.c
Kernel/threads.c
Modules/IPStack/ipv4.c
Modules/IPStack/ipv6.c
Usermode/Applications/Makefile.tpl
Usermode/Applications/axwin2_src/WM/Makefile
Usermode/Applications/axwin2_src/WM/common.h
Usermode/Applications/axwin2_src/WM/decorator.c [new file with mode: 0644]
Usermode/Applications/axwin2_src/WM/interface.c
Usermode/Applications/axwin2_src/WM/main.c
Usermode/Applications/axwin2_src/WM/messages.c
Usermode/Applications/axwin2_src/WM/video.c
Usermode/Applications/axwin2_src/WM/wm.c
Usermode/Applications/axwin2_src/WM/wm.h
Usermode/Libraries/libc.so_src/fileIO.c
Usermode/include/axwin/messages.h
Usermode/include/stdio.h
Usermode/include/string.h [deleted file]
Usermode/include/sys/sys.h

index 306f0f3..88ef808 100644 (file)
@@ -1 +1 @@
-BUILD_NUM = 2072
+BUILD_NUM = 2138
index f539183..ac54bc1 100644 (file)
@@ -71,7 +71,7 @@ void ErrorHandler(tRegs *Regs)
                Regs->int_num, csaERROR_NAMES[Regs->int_num], Regs->err_code);
        Warning(" CS:EIP = 0x%04x:%08x", Regs->cs, Regs->eip);
        if(Regs->cs == 0x08)
-               Warning(" SS:ESP = 0x0010:%08x", 0x10, (Uint)Regs+sizeof(tRegs));
+               Warning(" SS:ESP = 0x0010:%08x", (Uint)Regs+sizeof(tRegs));
        else
                Warning(" SS:ESP = 0x%04x:%08x", Regs->ss, Regs->esp);
        Warning(" EFLAGS = 0x%08x", Regs->eflags);
index fa3cb45..2dca563 100644 (file)
@@ -23,11 +23,20 @@ extern int  Time_Setup(void);
 extern Uint    Proc_Clone(Uint *Err, Uint Flags);
 extern void    Threads_Sleep(void);
 extern void    Threads_Exit(void);
+// --- Core ---
+extern void    System_Init(char *Commandline);
 
-extern int     Modules_LoadBuiltins(void);
+// === PROTOTYPES ===
+void   Arch_LoadBootModules(void);
 
 // === GLOBALS ===
 char   *gsBootCmdLine = NULL;
+struct {
+       void    *Base;
+       Uint    Size;
+       char    *ArgString;
+}      *gaArch_BootModules;
+ int   giArch_NumBootModules = 0;
 
 // === CODE ===
 int kmain(Uint MbMagic, void *MbInfoPtr)
@@ -81,35 +90,44 @@ int kmain(Uint MbMagic, void *MbInfoPtr)
        // Load Virtual Filesystem
        VFS_Init();
        
-       // Initialise builtin modules
-       Log_Log("Arch", "Initialising builtin modules...");
-       Modules_LoadBuiltins();
-       
-       Log_Log("Arch", "Loading %i Modules...", mbInfo->ModuleCount);
-       
        // Load initial modules
        mods = (void*)( mbInfo->Modules + KERNEL_BASE );
+       giArch_NumBootModules = mbInfo->ModuleCount;
+       gaArch_BootModules = malloc( giArch_NumBootModules * sizeof(*gaArch_BootModules) );
        for( i = 0; i < mbInfo->ModuleCount; i ++ )
        {
                // Adjust into higher half
-               mods[i].Start += KERNEL_BASE;
-               mods[i].End += KERNEL_BASE;
+               mods[i].Start  += KERNEL_BASE;
+               mods[i].End    += KERNEL_BASE;
                mods[i].String += KERNEL_BASE;
                
-               Log_Log("Arch", "Loading '%s'", mods[i].String);
-               
-               if( !Module_LoadMem( (void *)mods[i].Start, mods[i].End-mods[i].Start, (char *)mods[i].String ) )
-               {
-                       Log_Warning("Arch", "Unable to load module\n");
-               }
+               gaArch_BootModules[i].Base = (void *)mods[i].Start;
+               gaArch_BootModules[i].Size = mods[i].End - mods[i].Start;
+               gaArch_BootModules[i].ArgString = (char *)mods[i].String;
        }
        
        // Pass on to Independent Loader
        Log_Log("Arch", "Starting system");
-       System_Init( gsBootCmdLine );
+       System_Init(gsBootCmdLine);
        
        // Sleep forever (sleeping beauty)
        for(;;)
                Threads_Sleep();
        return 0;
 }
+
+void Arch_LoadBootModules(void)
+{
+        int    i;
+       for( i = 0; i < giArch_NumBootModules; i ++ )
+       {
+               Log_Log("Arch", "Loading '%s'", gaArch_BootModules[i].ArgString);
+               
+               if( !Module_LoadMem( gaArch_BootModules[i].Base, gaArch_BootModules[i].Size, gaArch_BootModules[i].ArgString ) )
+               {
+                       Log_Warning("Arch", "Unable to load module\n");
+               }
+       }
+       Log_Log("Arch", "Boot modules loaded");
+       free( gaArch_BootModules );
+}
index 5f7d592..cdf2370 100644 (file)
@@ -8,8 +8,9 @@
 // === MACROS ===
 #define        NUM_TIMERS      8
 #define        TIMER_QUANTUM   100
-#define TIMER_RATE     13      // (Max: 15, Min: 2) - 15 = 1Hz, 13 = 4Hz, 10 = 1024Hz
-#define TIMER_FREQ     (32768>>TIMER_RATE)     //Hz
+// 2^(15-rate), 15: 1HZ, 5: 1024Hz, 2: 8192Hz
+#define TIMER_RATE     12      // (Max: 15, Min: 2) - 15 = 1Hz, 13 = 4Hz, 12 = 8Hz, 11 = 16Hz 10 = 32Hz, 2
+#define TIMER_FREQ     (0x8000>>TIMER_RATE)    //Hz
 #define MS_PER_TICK_WHOLE      (1000/(TIMER_FREQ))
 #define MS_PER_TICK_FRACT      ((Uint64)(1000*TIMER_FREQ-((Uint64)MS_PER_TICK_WHOLE)*0x80000000/TIMER_FREQ))
 
index ab1e97d..b73e8de 100644 (file)
 #define        NUM_VTS 8
 #define MAX_INPUT_CHARS32      64
 #define MAX_INPUT_CHARS8       (MAX_INPUT_CHARS32*4)
-#define VT_SCROLLBACK  2       // 2 Screens of text
-//#define DEFAULT_OUTPUT       "VGA"
 //#define DEFAULT_OUTPUT       "BochsGA"
 #define DEFAULT_OUTPUT "Vesa"
 #define DEFAULT_INPUT  "PS2Keyboard"
-#define        DEFAULT_WIDTH   80
-#define        DEFAULT_HEIGHT  25
+#define        DEFAULT_WIDTH   640
+#define        DEFAULT_HEIGHT  480
+#define DEFAULT_SCROLLBACK     2       // 2 Screens of text + current screen
+#define        TEXTTERM_WIDTH  (BOOT_WIDTH/8)
+#define        TEXTTERM_HEIGHT (BOOT_WIDTH/16)
 #define        DEFAULT_COLOUR  (VT_COL_BLACK|(0xAAA<<16))
 
 #define        VT_FLAG_HIDECSR 0x01
@@ -71,7 +72,8 @@ tVFS_Node     *VT_FindDir(tVFS_Node *Node, char *Name);
 Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
 Uint64 VT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
  int   VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data);
-void   VT_SetResolution(int IsTextMode, int Width, int Height);
+void   VT_SetResolution(int Width, int Height);
+void   VT_SetMode(int Mode);
 void   VT_SetTerminal(int ID);
 void   VT_KBCallBack(Uint32 Codepoint);
 void   VT_int_PutString(tVTerm *Term, Uint8 *Buffer, Uint Count);
@@ -83,6 +85,8 @@ void  VT_int_ChangeMode(tVTerm *Term, int NewMode);
 
 // === CONSTANTS ===
 const Uint16   caVT100Colours[] = {
+               // Black, Red, Green, Yellow, Blue, Purple, Cyan, Gray
+               // Same again, but bright
                VT_COL_BLACK, 0x700, 0x070, 0x770, 0x007, 0x707, 0x077, 0xAAA,
                VT_COL_GREY, 0xF00, 0x0F0, 0xFF0, 0x00F, 0xF0F, 0x0FF, VT_COL_WHITE
        };
@@ -106,8 +110,9 @@ tVTerm      gVT_Terminals[NUM_VTS];
  int   giVT_CurrentTerminal = 0;
 tVTerm *gpVT_CurTerm = &gVT_Terminals[0];
 // --- Video State ---
-short  giVT_RealWidth; //!< Real Width
-short  giVT_RealHeight;        //!< Real Height
+short  giVT_RealWidth  = DEFAULT_WIDTH;        //!< Screen Width
+short  giVT_RealHeight = DEFAULT_HEIGHT;       //!< Screen Height
+ int   giVT_Scrollback = DEFAULT_SCROLLBACK;
 // --- Driver Handles ---
 char   *gsVT_OutputDevice = NULL;
 char   *gsVT_InputDevice = NULL;
@@ -125,36 +130,35 @@ char      *gsVT_InputDevice = NULL;
  */
 int VT_Install(char **Arguments)
 {
-       char    **args = Arguments;
-       char    *arg;
         int    i;
        
        // Scan Arguments
        if(Arguments)
        {
+               char    **args = Arguments;
+               char    *arg, *opt, *val;
                for( ; (arg = *args); args++ )
                {
-                       if(arg[0] != '-')       continue;
+                       Log_Debug("VTerm", "Argument '%s'", arg);
+                       opt = arg;
+                       val = arg + strpos(arg, '=');   *val++ = '\0';
                        
-                       switch(arg[1])
-                       {
-                       // Set output device
-                       case 'o':
-                               if(args[1] ==  NULL)    break;
+                       if( strcmp(opt, "Video") == 0 ) {
                                if(gsVT_OutputDevice)   free(gsVT_OutputDevice);
-                               gsVT_OutputDevice = malloc(strlen(args[1])+1);
-                               strcpy(gsVT_OutputDevice, args[1]);
-                               args ++;
-                               break;
-                       
-                       // Set input device
-                       case 'i':
-                               if(args[1] == NULL)     break;
+                               gsVT_OutputDevice = strdup(val);
+                       }
+                       else if( strcmp(opt, "Input") == 0 ) {
                                if(gsVT_InputDevice)    free(gsVT_InputDevice);
-                               gsVT_InputDevice = malloc(strlen(args[1])+1);
-                               strcpy(gsVT_InputDevice, args[1]);
-                               args ++;
-                               break;
+                               gsVT_InputDevice = strdup(val);
+                       }
+                       else if( strcmp(opt, "Width") == 0 ) {
+                               giVT_RealWidth = atoi( val );
+                       }
+                       else if( strcmp(opt, "Height") == 0 ) {
+                               giVT_RealHeight = atoi( val );
+                       }
+                       else if( strcmp(opt, "Scrollback") == 0 ) {
+                               giVT_Scrollback = atoi( val );
                        }
                }
        }
@@ -171,13 +175,16 @@ int VT_Install(char **Arguments)
        {
                gVT_Terminals[i].Mode = TERM_MODE_TEXT;
                gVT_Terminals[i].Flags = 0;
-               gVT_Terminals[i].Width = DEFAULT_WIDTH;
-               gVT_Terminals[i].Height = DEFAULT_HEIGHT;
+               gVT_Terminals[i].Width = giVT_RealWidth/giVT_CharWidth;
+               gVT_Terminals[i].Height = giVT_RealHeight/giVT_CharHeight;
                gVT_Terminals[i].CurColour = DEFAULT_COLOUR;
                gVT_Terminals[i].WritePos = 0;
                gVT_Terminals[i].ViewPos = 0;
                
-               gVT_Terminals[i].Buffer = calloc( DEFAULT_WIDTH*DEFAULT_HEIGHT*VT_SCROLLBACK, sizeof(tVT_Char) );
+               gVT_Terminals[i].Buffer = calloc(
+                       gVT_Terminals[i].Width*gVT_Terminals[i].Height*(giVT_Scrollback+1),
+                       sizeof(tVT_Char)
+                       );
                
                gVT_Terminals[i].Name[0] = '0'+i;
                gVT_Terminals[i].Name[1] = '\0';
@@ -214,8 +221,9 @@ void VT_InitOutput()
                Log_Warning("VTerm", "Oh F**k, I can't open the video device '%s'", gsVT_OutputDevice);
                return ;
        }
+       VT_SetResolution(giVT_RealWidth, giVT_RealHeight);
        VT_SetTerminal( 0 );
-       VT_SetResolution(1, 640, 400);
+       VT_SetMode( VIDEO_BUFFMT_TEXT );
 }
 
 /**
@@ -425,6 +433,7 @@ int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data)
        
        switch(Id)
        {
+       // --- Core Defined
        case DRV_IOCTL_TYPE:
                LEAVE('i', DRV_TYPE_TERMINAL);
                return DRV_TYPE_TERMINAL;
@@ -443,7 +452,12 @@ int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data)
        case TERM_IOCTL_MODETYPE:
                if(Data != NULL)
                {
+                       if( CheckMem(Data, sizeof(int)) == 0 ) {
+                               LEAVE('i', -1);
+                               return -1;
+                       }
                        Log_Log("VTerm", "VTerm %i mode set to %i", (int)Node->Inode, *iData);
+                       
                        // Update mode if needed
                        if(term->Mode != *iData)
                                VT_int_ChangeMode(term, *iData);
@@ -457,14 +471,26 @@ int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data)
        
        // Get/set the terminal width
        case TERM_IOCTL_WIDTH:
-               if(Data != NULL)        term->Width = *iData;
+               if(Data != NULL) {
+                       if( CheckMem(Data, sizeof(int)) == 0 ) {
+                               LEAVE('i', -1);
+                               return -1;
+                       }
+                       term->Width = *iData;
+               }
                Log("VT_Terminal_IOCtl - RETURN term->Width = %i", term->Width);
                LEAVE('i', term->Width);
                return term->Width;
        
        // Get/set the terminal height
        case TERM_IOCTL_HEIGHT:
-               if(Data != NULL)        term->Height = *iData;
+               if(Data != NULL) {
+                       if( CheckMem(Data, sizeof(int)) == 0 ) {
+                               LEAVE('i', -1);
+                               return -1;
+                       }
+                       term->Height = *iData;
+               }
                Log("VT_Terminal_IOCtl - RETURN term->Height = %i", term->Height);
                LEAVE('i', term->Height);
                return term->Height;
@@ -480,10 +506,11 @@ int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data)
        return -1;
 }
 
-void VT_SetResolution(int IsTextMode, int Width, int Height)
+void VT_SetResolution(int Width, int Height)
 {
        tVideo_IOCtl_Mode       mode = {0};
         int    tmp;
+        int    i;
        
        // Create the video mode
        mode.width = Width;
@@ -494,12 +521,41 @@ void VT_SetResolution(int IsTextMode, int Width, int Height)
        // Set video mode
        VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_FINDMODE, &mode );
        tmp = mode.id;
-       giVT_RealWidth = mode.width;
-       giVT_RealHeight = mode.height;
+       if( Width != mode.width || Height != mode.height )
+       {
+               Log_Warning("VTerm",
+                       "Selected resolution (%ix%i is not supported) by the device, using (%ix%i)",
+                       giVT_RealWidth, giVT_RealHeight,
+                       mode.width, mode.height
+                       );
+       }
        VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_GETSETMODE, &tmp );
        
-       tmp = IsTextMode ? VIDEO_BUFFMT_TEXT : VIDEO_BUFFMT_FRAMEBUFFER;
-       VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_SETBUFFORMAT, &tmp );
+       // Resize text terminals if needed
+       if( giVT_RealWidth != mode.width || giVT_RealHeight != mode.height )
+       {
+                int    newBufSize = (giVT_RealWidth/giVT_CharWidth)
+                                       *(giVT_RealHeight/giVT_CharHeight)
+                                       *(giVT_Scrollback+1);
+               //tVT_Char      *tmp;
+               // Resize the text terminals
+               giVT_RealWidth = mode.width;
+               giVT_RealHeight = mode.height;
+               for( i = 0; i < NUM_VTS; i ++ )
+               {
+                       if( gVT_Terminals[i].Mode != TERM_MODE_TEXT )   continue;
+                       
+                       gVT_Terminals[i].Text = realloc(
+                               gVT_Terminals[i].Text,
+                               newBufSize*sizeof(tVT_Char)
+                               );
+               }
+       }
+}
+
+void VT_SetMode(int Mode)
+{
+       VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_SETBUFFORMAT, &Mode );
 }
 
 /**
@@ -523,9 +579,9 @@ void VT_SetTerminal(int ID)
        }
        
        if( gpVT_CurTerm->Mode == TERM_MODE_TEXT )
-               VT_SetResolution( 1, gpVT_CurTerm->Width*giVT_CharWidth, gpVT_CurTerm->Height*giVT_CharHeight );
+               VT_SetMode( VIDEO_BUFFMT_TEXT );
        else
-               VT_SetResolution( 0, gpVT_CurTerm->Width, gpVT_CurTerm->Height );
+               VT_SetMode( VIDEO_BUFFMT_FRAMEBUFFER );
        
        // Update the screen
        VT_int_UpdateScreen( &gVT_Terminals[ ID ], 1 );
@@ -612,10 +668,10 @@ void VT_KBCallBack(Uint32 Codepoint)
                                gpVT_CurTerm->ViewPos = 0;
                        return;
                case KEY_PGDOWN:
-                       if( gpVT_CurTerm->ViewPos < gpVT_CurTerm->Width*(gpVT_CurTerm->Height*(VT_SCROLLBACK-1)) )
+                       if( gpVT_CurTerm->ViewPos < gpVT_CurTerm->Width*gpVT_CurTerm->Height*(giVT_Scrollback-1) )
                                gpVT_CurTerm->ViewPos += gpVT_CurTerm->Width;
                        else
-                               gpVT_CurTerm->ViewPos = gpVT_CurTerm->Width*(gpVT_CurTerm->Height*(VT_SCROLLBACK-1));
+                               gpVT_CurTerm->ViewPos = gpVT_CurTerm->Width*gpVT_CurTerm->Height*(giVT_Scrollback-1);
                        return;
                }
        }
@@ -725,28 +781,36 @@ int VT_int_ParseEscape(tVTerm *Term, char *Buffer)
        char    c;
         int    argc = 0, j = 1;
         int    tmp;
-        int    args[4] = {0,0,0,0};
+        int    args[6] = {0,0,0,0};
        
-       switch(Buffer[0]) {
+       switch(Buffer[0])
+       {
        //Large Code
        case '[':
                // Get Arguments
-               c = Buffer[1];
-               do {
-                       while('0' <= c && c <= '9') {
-                               args[argc] *= 10;
-                               args[argc] += c-'0';
-                               c = Buffer[++j];
-                       }
-                       if( j != 1 )    argc ++;
-               } while(c == ';');
+               c = Buffer[j++];
+               if( '0' <= c && c <= '9' )
+               {
+                       do {
+                               while('0' <= c && c <= '9') {
+                                       args[argc] *= 10;
+                                       args[argc] += c-'0';
+                                       c = Buffer[j++];
+                               }
+                               argc ++;
+                       } while(c == ';');
+               }
                
+               /*
                // Get string (what does this do?)
                if(c == '"') {
-                       c = Buffer[++j];
+                       c = Buffer[j++];
                        while(c != '"')
-                               c = Buffer[++j];
+                               c = Buffer[j++];
                }
+               */
+               
+               //Log_Debug("VTerm", "argc = %i", argc);
                
                // Get Command
                if(     ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))
@@ -782,7 +846,7 @@ int VT_int_ParseEscape(tVTerm *Term, char *Buffer)
                                {
                                case 2:
                                        {
-                                        int    i = Term->Height * VT_SCROLLBACK;
+                                        int    i = Term->Height * (giVT_Scrollback + 1);
                                        while( i-- )    VT_int_ClearLine(Term, i);
                                        Term->WritePos = 0;
                                        Term->ViewPos = 0;
@@ -817,15 +881,18 @@ int VT_int_ParseEscape(tVTerm *Term, char *Buffer)
                                        }
                                }
                                break;
+                       default:
+                               Log_Warning("VTerm", "Unknown control sequence");
+                               break;
                        }
                }
                break;
                
-       default:
-               break;
+       default:        break;
        }
        
-       return j + 1;
+       //Log_Debug("VTerm", "j = %i, Buffer = '%s'", j, Buffer);
+       return j;
 }
 
 /**
@@ -841,7 +908,7 @@ void VT_int_PutString(tVTerm *Term, Uint8 *Buffer, Uint Count)
                if( Buffer[i] == 0x1B ) // Escape Sequence
                {
                        i ++;
-                       i += VT_int_ParseEscape(Term, (char*)&Buffer[i]);
+                       i += VT_int_ParseEscape(Term, (char*)&Buffer[i]) - 1;
                        continue;
                }
                
@@ -923,25 +990,25 @@ void VT_int_PutChar(tVTerm *Term, Uint32 Ch)
        }
        
        // Move Screen
-       if(Term->WritePos >= Term->Width*Term->Height*VT_SCROLLBACK)
+       if(Term->WritePos >= Term->Width*Term->Height*(giVT_Scrollback+1))
        {
                 int    base, i;
                Term->WritePos -= Term->Width;
                VT_int_UpdateScreen( Term, 0 );
                
                // Update view position
-               base = Term->Width*Term->Height*(VT_SCROLLBACK-1);
+               base = Term->Width*Term->Height*(giVT_Scrollback-1);
                if(Term->ViewPos < base)        Term->ViewPos += Term->Width;
                if(Term->ViewPos > base)        Term->ViewPos = base;
                
                // Scroll terminal cache
-               base = Term->Width*(Term->Height*VT_SCROLLBACK-1);
+               base = Term->Width*(Term->Height*(giVT_Scrollback+1)-1);
                
                // Scroll Back
                memcpy(
                        Term->Text,
                        &Term->Text[Term->Width],
-                       (Term->Width*Term->Height*VT_SCROLLBACK-Term->Width)*sizeof(tVT_Char)
+                       (Term->Width*Term->Height*(giVT_Scrollback+1)-Term->Width)*sizeof(tVT_Char)
                        );
                
                // Clear last row
@@ -1061,7 +1128,7 @@ void VT_int_ChangeMode(tVTerm *Term, int NewMode)
        case TERM_MODE_TEXT:
                Log_Log("VTerm", "Set VT %p to text mode", Term);
                free(Term->Buffer);
-               Term->Text = calloc( Term->Width*Term->Height*VT_SCROLLBACK, sizeof(tVT_Char) );
+               Term->Text = calloc( Term->Width*Term->Height*(giVT_Scrollback+1), sizeof(tVT_Char) );
                break;
        case TERM_MODE_FB:
                Log_Log("VTerm", "Set VT %p to framebuffer mode (%ix%i)", Term,
index 09c4f51..8e62578 100644 (file)
@@ -95,9 +95,6 @@ typedef struct sKernelSymbol {
  */
 
 // === FUNCTIONS ===
-// --- Core ---
-extern void    System_Init(char *ArgString);
-
 // --- IRQs ---
 extern int     IRQ_AddHandler(int Num, void (*Callback)(int));
 
@@ -315,6 +312,7 @@ extern int  strcmp(const char *__str1, const char *__str2);
 extern int     strncmp(const char *Str1, const char *Str2, size_t num);
 extern int     strucmp(const char *Str1, const char *Str2);
 extern char    *strdup(const char *Str);
+extern char    **str_split(const char *__str, char __ch);
 extern int     strpos(const char *Str, char Ch);
 extern int     strpos8(const char *str, Uint32 search);
 extern void    itoa(char *buf, Uint num, int base, int minLength, char pad);
index f3313f6..1c00c5e 100644 (file)
@@ -15,8 +15,6 @@
  * Writes to the driver's file while in component colour modes\r
  * must correspond to a change of the contents of the screen. The framebuffer\r
  * must start at offset 0 in the file.\r
- * In pallete colour modes the LFB is preceded by a 1024 byte pallete (allowing\r
- * room for 256 entries of 32-bits each)\r
  * Reading from the screen must either return zero, or read from the\r
  * framebuffer.\r
  * \r
@@ -190,6 +188,17 @@ enum eTplVideo_2DCommands
         */\r
        VIDEO_2DOP_BLIT,\r
 \r
+\r
+       /**\r
+        * \brief Copy a region from video memory to the framebuffer\r
+        */\r
+       VIDEO_2DOP_BLITBUF,\r
+\r
+       /**\r
+        * \brief Copy and scale a region from video memory to the framebuffer\r
+        */\r
+       VIDEO_2DOP_BLITSCALEBUF,\r
+\r
        NUM_VIDEO_2DOPS\r
 };\r
 \r
index ac8f616..ab64d67 100644 (file)
@@ -28,10 +28,11 @@ char        *strncpy(char *__str1, const char *__str2, size_t max);
  int   strcmp(const char *str1, const char *str2);
  int   strncmp(const char *str1, const char *str2, size_t num);
 char   *strdup(const char *Str);
- int   DivUp(int num, int dem);
+char   **str_split(const char *__str, char __ch);
  int   strpos8(const char *str, Uint32 Search);
  int   ReadUTF8(Uint8 *str, Uint32 *Val);
  int   WriteUTF8(Uint8 *str, Uint32 Val);
+ int   DivUp(int num, int dem);
 Sint64 timestamp(int sec, int mins, int hrs, int day, int month, int year);
 Uint   rand(void);
  int   CheckString(char *String);
@@ -54,8 +55,9 @@ EXPORT(strncpy);
 EXPORT(strcmp);
 EXPORT(strncmp);
 EXPORT(strdup);
-EXPORT(DivUp);
+EXPORT(str_split);
 EXPORT(strpos8);
+EXPORT(DivUp);
 EXPORT(ReadUTF8);
 EXPORT(WriteUTF8);
 EXPORT(timestamp);
@@ -230,8 +232,12 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
                        pad = ' ';
                
                // - Minimum length
-               minSize = 1;
-               if('1' <= c && c <= '9')
+               if(c == '*') {
+                       minSize = val;
+                       val = va_arg(args, Uint);
+                       c = *__format++;
+               }
+               else if('1' <= c && c <= '9')
                {
                        minSize = 0;
                        while('0' <= c && c <= '9')
@@ -241,6 +247,8 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
                                c = *__format++;
                        }
                }
+               else
+                       minSize = 1;
                
                // - Default, Long or LongLong?
                isLongLong = 0;
@@ -300,6 +308,7 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
                case 'C':       // Non-Null Terminated Character Array
                        p = (char*)(Uint)val;
                        if(!p)  goto printString;
+                       //while(minSize--)      PUTCH(*p++);
                        while(minSize--)        PUTCH(*p++);
                        break;
                
@@ -451,6 +460,52 @@ char *strdup(const char *Str)
        return ret;
 }
 
+/**
+ * \brief Split a string using the passed character
+ * \return NULL terminated array of strings on the heap
+ * \param __str        String to split
+ * \param __ch Character to split by
+ */
+char **str_split(const char *__str, char __ch)
+{
+        int    i, j;
+        int    len = 1;
+       char    **ret;
+       char    *start;
+       
+       for( i = 0; __str[i]; i++ )
+       {
+               if(__str[i] == __ch)
+                       len ++;
+       }
+       
+       ret = malloc( sizeof(char*)*(len+1) + (i + 1) );
+       if( !ret )      return NULL;
+       
+       j = 1;
+       start = (char *)&ret[len+1];
+       ret[0] = start;
+       for( i = 0; __str[i]; i++ )
+       {
+               if(__str[i] == __ch) {
+                       *start++ = '\0';
+                       Log_Debug("Lib", "str_split: ret[%i] = '%s'", j-1, ret[j-1]);
+                       ret[j++] = start;
+               }
+               else {
+                       *start++ = __str[i]; 
+               }
+       }
+       *start = '\0';
+       ret[j] = NULL;
+       Log_Debug("Lib", "str_split: ret[%i] = '%s'", j-1, ret[j-1]);
+       
+       for( j = 0; j < len; j++ )
+               Log_Debug("Lib", "str_split: ret[%i] = '%s'", j, ret[j]);
+       
+       return ret;
+}
+
 /**
  * \fn int DivUp(int num, int dem)
  * \brief Divide two numbers, rounding up
index 18f75fb..f4a23b4 100644 (file)
@@ -21,7 +21,11 @@ enum eLogLevels
        LOG_LEVEL_DEBUG,
        NUM_LOG_LEVELS
 };
-const char     *csaLevelCodes[] = {"k","p","f","e","w","n","l","d"};
+const char     *csaLevelColours[] = {
+               "\x1B[35m", "\x1B[34m", "\x1B[36m", "\x1B[31m",
+               "\x1B[33m", "\x1B[32m", "\x1B[0m", "\x1B[0m"
+               };
+const char     *csaLevelCodes[] =  {"k","p","f","e","w","n","l","d"};
 
 // === TYPES ===
 typedef struct sLogEntry
@@ -118,7 +122,8 @@ void Log_AddEvent(char *Ident, int Level, char *Format, va_list Args)
  */
 void Log_Int_PrintMessage(tLogEntry *Entry)
 {
-       LogF("%018lli%s [%+8s] %s\n",
+       LogF("%s%018lli%s [%+8s] %s\x1B[0m\n",
+               csaLevelColours[Entry->Level],
                Entry->Time,
                csaLevelCodes[Entry->Level],
                Entry->Ident,
index 68d5ba0..41fb514 100644 (file)
@@ -10,7 +10,9 @@
 #define        USE_UDI 0
 
 // === PROTOTYPES ===
- int   Modules_LoadBuiltins(void);
+ int   Module_int_Initialise(tModule *Module, char *ArgString);
+void   Modules_LoadBuiltins(void);
+void   Modules_SetBuiltinParams(char *Name, char *ArgString);
  int   Module_RegisterLoader(tModuleLoader *Loader);
  int   Module_LoadMem(void *Buffer, Uint Length, char *ArgString);
  int   Module_LoadFile(char *Path, char *ArgString);
@@ -34,6 +36,7 @@ tSpinlock     glModuleSpinlock;
 tModule        *gLoadedModules = NULL;
 tModuleLoader  *gModule_Loaders = NULL;
 tModule        *gLoadingModules = NULL;
+char   **gasBuiltinModuleArgs;
 
 // === CODE ===
 /**
@@ -45,11 +48,12 @@ tModule     *gLoadingModules = NULL;
  * \retval 0   Returned on success
  * \retval >0  Error code form the module's initialisation function
  */
-int Module_int_Initialise(tModule *Module)
+int Module_int_Initialise(tModule *Module, char *ArgString)
 {
         int    i, j;
         int    ret;
        char    **deps;
+       char    **args;
        tModule *mod;
        
        ENTER("pModule", Module);
@@ -100,7 +104,10 @@ int Module_int_Initialise(tModule *Module)
                }
                
                // Dependency is not loaded, so load it
-               ret = Module_int_Initialise( &gKernelModules[i] );
+               ret = Module_int_Initialise(
+                       &gKernelModules[i],
+                       gasBuiltinModuleArgs ? gasBuiltinModuleArgs[i] : NULL
+                       );
                if( ret )
                {
                        // The only "ok" error is NOTNEEDED
@@ -116,7 +123,15 @@ int Module_int_Initialise(tModule *Module)
                Module->Version >> 8, Module->Version & 0xFF
                );
        
-       ret = Module->Init(NULL);
+       if( ArgString )
+               args = str_split( ArgString, ',' );
+       else
+               args = NULL;
+       
+       ret = Module->Init(args);
+       
+       if(args)        free(args);
+       
        if( ret != MODULE_ERR_OK ) {
                switch(ret)
                {
@@ -153,7 +168,7 @@ int Module_int_Initialise(tModule *Module)
 /**
  * \brief Initialises builtin modules
  */
-int Modules_LoadBuiltins()
+void Modules_LoadBuiltins()
 {
         int    i;
        
@@ -163,10 +178,37 @@ int Modules_LoadBuiltins()
        
        for( i = 0; i < giNumBuiltinModules; i++ )
        {
-               Module_int_Initialise( &gKernelModules[i] );
+               Module_int_Initialise(
+                       &gKernelModules[i],
+                       (gasBuiltinModuleArgs ? gasBuiltinModuleArgs[i] : NULL)
+                       );
        }
        
-       return 0;
+       if( gasBuiltinModuleArgs != NULL )
+               free(gasBuiltinModuleArgs);
+}
+
+/**
+ * \brief Sets the parameters for a builtin module
+ */
+void Modules_SetBuiltinParams(char *Name, char *ArgString)
+{
+        int    i;
+       if( gasBuiltinModuleArgs == NULL ) {
+               giNumBuiltinModules = (Uint)&gKernelModulesEnd - (Uint)&gKernelModules;
+               giNumBuiltinModules /= sizeof(tModule);
+               gasBuiltinModuleArgs = calloc( giNumBuiltinModules, sizeof(char*) );
+       }
+       
+       for( i = 0; i < giNumBuiltinModules; i ++ )
+       {
+               if(strcmp( gKernelModules[i].Name, Name ) == 0) {
+                       gasBuiltinModuleArgs[i] = ArgString;
+                       return ;
+               }
+       }
+       
+       Log_Warning("Modules", "Unknown builtin kernel module '%s'", Name);
 }
 
 /**
@@ -258,7 +300,7 @@ int Module_LoadFile(char *Path, char *ArgString)
        }
        
        #if 1
-       if( Module_int_Initialise( info ) )
+       if( Module_int_Initialise( info, ArgString ) )
        {
                Binary_Unload(base);
                return 0;
index 546b2d8..7c5ff32 100644 (file)
@@ -32,31 +32,32 @@ typedef struct
 }      tConfigCommand;
 
 // === IMPORTS ===
+extern void    Arch_LoadBootModules();
 extern int     Modules_LoadBuiltins();
-//extern int   PCI_Install();
-extern void    DMA_Install();
+extern void    Modules_SetBuiltinParams(char *Name, char *ArgString);
 extern void    Debug_SetKTerminal(char *File);
-extern void    StartupPrint(char *Str);
 
 // === PROTOTYPES ===
-void   System_Init(char *ArgString);
+void   System_Init(char *Commandline);
 void   System_ParseCommandLine(char *ArgString);
+void   System_ExecuteCommandLine(void);
 void   System_ParseVFS(char *Arg);
+void   System_ParseModuleArgs(char *Arg);
 void   System_ParseSetting(char *Arg);
-void   System_ExecuteScript();
+void   System_ExecuteScript(void);
 tConfigFile    *System_Int_ParseFile(char *File);
 
 // === CONSTANTS ===
 const tConfigCommand   caConfigCommands[] = {
-       {"module", 1,2, 0, Module_LoadFile, {(Uint)"",0}},      // Load a module from a file
-       {"spawn", 1,1, 0, Proc_Spawn, {0}},             // Spawn a process
+       {"module",  1,2, 00, Module_LoadFile, {(Uint)"",0}},    // Load a module from a file
+       {"spawn",   1,1, 00, Proc_Spawn, {0}},          // Spawn a process
        // --- VFS ---
-       {"mount", 3,4, 0, VFS_Mount, {(Uint)"",0}},             // Mount a device
-       {"symlink", 2,2, 0, VFS_Symlink, {0}},  // Create a Symbolic Link
-       {"mkdir", 1,1, 0, VFS_MkDir, {0}},              // Create a Directory
-       {"open", 1,2, 0, VFS_Open, {VFS_OPENFLAG_READ,0}},      // Open a file
-       {"close", 1,1, 0x1, VFS_Close, {0}},    // Close an open file
-       {"ioctl", 3,3, 0x3, VFS_IOCtl, {0}},    // Call an IOCtl
+       {"mount",   3,4, 00, VFS_Mount, {(Uint)"",0}},          // Mount a device
+       {"symlink", 2,2, 00, VFS_Symlink, {0}}, // Create a Symbolic Link
+       {"mkdir",   1,1, 00, VFS_MkDir, {0}},           // Create a Directory
+       {"open",    1,2, 00, VFS_Open,  {VFS_OPENFLAG_READ,0}}, // Open a file
+       {"close",   1,1, 01, VFS_Close, {0}},   // Close an open file
+       {"ioctl",   3,3, 03, VFS_IOCtl, {0}},   // Call an IOCtl
        
        {"", 0,0, 0, NULL, {0}}
 };
@@ -64,13 +65,21 @@ const tConfigCommand        caConfigCommands[] = {
 
 // === GLOBALS ===
 char   *gsConfigScript = "/Acess/Conf/BootConf.cfg";
+char   *argv[32];
+ int   argc;
 
 // === CODE ===
-void System_Init(char *ArgString)
+void System_Init(char *CommandLine)
 {
+       // Parse Kernel's Command Line
+       System_ParseCommandLine(CommandLine);
        
-       // - Parse Kernel's Command Line
-       System_ParseCommandLine(ArgString);
+       // Initialise modules
+       Log_Log("Config", "Initialising builtin modules...");
+       Modules_LoadBuiltins();
+       Arch_LoadBootModules();
+       
+       System_ExecuteCommandLine();
        
        // - Execute the Config Script
        Log_Log("Config", "Executing config script...");
@@ -87,8 +96,6 @@ void System_Init(char *ArgString)
  */
 void System_ParseCommandLine(char *ArgString)
 {
-       char    *argv[32];
-        int    argc;
         int    i;
        char    *str;
        
@@ -103,13 +110,13 @@ void System_ParseCommandLine(char *ArgString)
                // Check for the end of the string
                if(*str == '\0') {      argc--; break;} 
                argv[argc] = str;
-               while(*str && *str != ' ')
-               {
-                       /*if(*str == '"') {
-                               while(*str && !(*str == '"' && str[-1] != '\\'))
-                                       str ++;
-                       }*/
-                       str++;
+               if(*str == '"') {
+                       while(*str && !(*str == '"' && str[-1] != '\\'))
+                               str ++;
+               }
+               else {
+                       while(*str && *str != ' ')
+                               str++;
                }
                if(*str == '\0')        break;  // Check for EOS
                *str = '\0';    // Cap off argument string
@@ -118,13 +125,44 @@ void System_ParseCommandLine(char *ArgString)
        if(argc < 32)
                argc ++;        // Count last argument
        
-       // --- Parse Arguments ---
+       // --- Parse Arguments (Pass 1) ---
        for( i = 1; i < argc; i++ )
        {
-               if( argv[i][0] == '/' )
-                       System_ParseVFS( argv[i] );
-               else
+               switch(argv[i][0])
+               {
+               // --- VFS ---
+               // Ignored on this pass
+               case '/':
+                       break;
+               
+               // --- Module Paramaters ---
+               // -VTerm:Width=640,Height=480,Scrollback=2
+               case '-':
+                       System_ParseModuleArgs( argv[i] );
+                       break;
+               // --- Config Options ---
+               // SCRIPT=/Acess/Conf/BootConf.cfg
+               default:
                        System_ParseSetting( argv[i] );
+                       break;
+               }
+       }
+}
+
+void System_ExecuteCommandLine(void)
+{
+        int    i;
+       for( i = 1; i < argc; i++ )
+       {
+               switch(argv[i][0])
+               {
+               // --- VFS ---
+               // Mount    /System=ext2:/Devices/ATA/A1
+               // Symlink  /Acess=/System/Acess2
+               case '/':
+                       System_ParseVFS( argv[i] );
+                       break;
+               }
        }
 }
 
@@ -180,6 +218,37 @@ void System_ParseVFS(char *Arg)
        }
 }
 
+/**
+ * \biref Parse a module argument string
+ */
+void System_ParseModuleArgs(char *Arg)
+{
+       char    *name, *args;
+        int    i;
+       
+       // Remove '-'   
+       name = Arg + 1;
+       
+       // Find the start of the args
+       i = strpos(name, ':');
+       if( i == -1 ) {
+               Log_Warning("Config", "Module spec with no arguments");
+               #if 1
+               return ;
+               #else
+               i = strlen(name);
+               args = name + i;
+               #endif
+       }
+       else {
+               name[i] = '\0';
+               args = name + i + 1;
+       }
+       
+       Log_Log("Config", "Setting boot parameters for '%s' to '%s'", name, args);
+       Modules_SetBuiltinParams(name, args);
+}
+
 /**
  * \fn void System_ParseSetting(char *Arg)
  */
@@ -220,8 +289,9 @@ void System_ParseSetting(char *Arg)
 
 /**
  * \fn void System_ExecuteScript()
+ * \brief Reads and parses the boot configuration script
  */
-void System_ExecuteScript()
+void System_ExecuteScript(void)
 {
         int    fp;
         int    fLen = 0;
@@ -242,10 +312,11 @@ void System_ExecuteScript()
                return;
        }
        
-       // Read into memory buffer
+       // Get length
        VFS_Seek(fp, 0, SEEK_END);
        fLen = VFS_Tell(fp);
        VFS_Seek(fp, 0, SEEK_SET);
+       // Read into memory buffer
        fData = malloc(fLen+1);
        VFS_Read(fp, fLen, fData);
        fData[fLen] = '\0';
@@ -419,6 +490,8 @@ void System_ExecuteScript()
                }
                free( file->Lines[i].Parts );
        }
+       
+       // Free data
        free( file );
        free( fData );
 }
index f726f27..0a9ab37 100644 (file)
@@ -266,10 +266,11 @@ int Threads_WaitTID(int TID, int *status)
                 int    initStatus = t->Status;
                 int    ret;
                
-               if(initStatus != THREAD_STAT_ZOMBIE)
+               if(initStatus != THREAD_STAT_ZOMBIE) {
                        while(t->Status == initStatus) {
                                Threads_Yield();
                        }
+               }
                
                ret = t->RetStatus;
                switch(t->Status)
index d65adb6..a1b9178 100644 (file)
@@ -103,6 +103,7 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff
         int    dataLength;
        if(Length < sizeof(tIPv4Header))        return;
        
+       #if 0
        //Log_Log("IPv4", "Version = %i", hdr->Version);
        //Log_Log("IPv4", "HeaderLength = %i", hdr->HeaderLength);
        //Log_Log("IPv4", "DiffServices = %i", hdr->DiffServices);
@@ -116,7 +117,8 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff
        Log_Log("IPv4", "Destination = %i.%i.%i.%i",
                hdr->Destination.B[0], hdr->Destination.B[1],
                hdr->Destination.B[2], hdr->Destination.B[3] );
-       
+       #endif  
+
        // Check that the version IS IPv4
        if(hdr->Version != 4) {
                Log_Log("IPv4", "hdr->Version(%i) != 4", hdr->Version);
index b709dfa..7ae927a 100644 (file)
@@ -38,14 +38,14 @@ void IPv6_int_GetPacket(tAdapter *Interface, tMacAddr From, int Length, void *Bu
                return;
        
        Log("[IPv6 ] hdr = {");
-       Log("[IPv6 ]  .Version = %i", (hdr->Head >> (20+8)) & 0xF );
-       Log("[IPv6 ]  .TrafficClass = %i", (hdr->Head >> (20)) & 0xFF );
-       Log("[IPv6 ]  .FlowLabel = %i", hdr->Head & 0xFFFFF );
+       Log("[IPv6 ]  .Version       = %i", (hdr->Head >> (20+8)) & 0xF );
+       Log("[IPv6 ]  .TrafficClass  = %i", (hdr->Head >> (20)) & 0xFF );
+       Log("[IPv6 ]  .FlowLabel     = %i", hdr->Head & 0xFFFFF );
        Log("[IPv6 ]  .PayloadLength = 0x%04x", ntohs(hdr->PayloadLength) );
-       Log("[IPv6 ]  .NextHeader = 0x%02x", hdr->NextHeader );
-       Log("[IPv6 ]  .HopLimit = 0x%02x", hdr->HopLimit );
-       Log("[IPv6 ]  .Source = %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", hdr->Source );
-       Log("[IPv6 ]  .Destination = %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", hdr->Destination );
+       Log("[IPv6 ]  .NextHeader    = 0x%02x", hdr->NextHeader );
+       Log("[IPv6 ]  .HopLimit      = 0x%02x", hdr->HopLimit );
+       Log("[IPv6 ]  .Source        = %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", hdr->Source );
+       Log("[IPv6 ]  .Destination   = %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", hdr->Destination );
        Log("[IPv6 ] }");
        
 }
index d18e52e..8aad269 100644 (file)
@@ -2,9 +2,11 @@
 #
 #
 
-CFLAGS  += -Wall -fno-builtin -fno-stack-protector
+CFLAGS  += -Wall -fno-builtin -fno-stack-protector -g
 LDFLAGS += 
 
+DEPFILES := $(OBJ:%.o=%.d)
+
 .PHONY : all clean install
 
 all: $(BIN)
@@ -17,9 +19,12 @@ install: $(BIN)
 
 $(BIN): $(OBJ)
        @echo --- $(LD) -o $@
-       @$(LD) $(LDFLAGS) -o $@ $(OBJ) -Map Map.txt
-       @objdump -d $(BIN) > $(BIN).dsm
+       @$(LD) -g $(LDFLAGS) -o $@ $(OBJ) -Map Map.txt
+       @objdump -d -S $(BIN) > $(BIN).dsm
 
 $(OBJ): %.o: %.c
        @echo --- GCC -o $@
-       @$(CC) $(CFLAGS) $(CPPFLAGS) -c $? -o $@
+       @$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
+       @$(CC) -M -MT $@ $(CPPFLAGS) $< -o $*.d
+
+-include $(DEPFILES)
index cce4a81..95ccd41 100644 (file)
@@ -7,6 +7,6 @@ CPPFLAGS += -I../include
 DIR := Apps/AxWin/1.0
 BIN := ../AxWinWM
 OBJ := main.o helpers.o commandline.o video.o
-OBJ += messages.o interface.o wm.o
+OBJ += messages.o interface.o wm.o decorator.o
 
 -include ../../Makefile.tpl
index 7ec792a..06ea61c 100644 (file)
@@ -24,7 +24,8 @@ extern int    giMouseFD;
 
 // === Functions ===
 extern void    memset32(void *ptr, uint32_t val, size_t count);
-extern void    Video_FillRect(short X, short Y, short W, short H, uint32_t Color);
 extern void    Video_Update(void);
-
+extern void    Video_FillRect(short X, short Y, short W, short H, uint32_t Color);
+extern void    Video_DrawRect(short X, short Y, short W, short H, uint32_t Color);
+extern void    Video_DrawText(short X, short Y, short W, short H, void *Font, int Point, uint32_t Color, char *Text);
 #endif
diff --git a/Usermode/Applications/axwin2_src/WM/decorator.c b/Usermode/Applications/axwin2_src/WM/decorator.c
new file mode 100644 (file)
index 0000000..3ab88e8
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Acess GUI (AxWin) Version 2
+ * By John Hodge (thePowersGang)
+ * 
+ * Widget Decorator
+ */
+#include "common.h"
+#include "wm.h"
+
+#define BOX_BGCOLOUR    0xC0C0C0
+#define BOX_BORDER      0xA0A0A0
+#define BUTTON_BGCOLOUR 0xD0D0D0
+#define BUTTON_BORDER   0xF0F0F0
+#define        TEXT_COLOUR     0x000000
+
+// === CODE ===
+void Decorator_RenderWidget(tElement *Element)
+{
+       _SysDebug("Decorator_RenderWidget: (Element={Type:%i,(%i,%i) %ix%i})",
+               Element->Type,
+               Element->CachedX, Element->CachedY,
+               Element->CachedW, Element->CachedH
+               );
+       
+       switch(Element->Type)
+       {
+       case ELETYPE_NONE:
+       case ELETYPE_BOX:       break;
+       
+       case ELETYPE_TABBAR:    // TODO: Moar
+       case ELETYPE_TOOLBAR:
+               Video_DrawRect(
+                       Element->CachedX, Element->CachedY,
+                       Element->CachedW, Element->CachedH,
+                       BOX_BORDER
+                       );
+               Video_FillRect(
+                       Element->CachedX, Element->CachedY,
+                       Element->CachedW-2, Element->CachedH-2,
+                       BOX_BGCOLOUR
+                       );
+               break;
+       
+       case ELETYPE_SPACER:
+               Video_FillRect(
+                       Element->CachedX+3, Element->CachedY+3,
+                       Element->CachedW-6, Element->CachedH-6,
+                       BOX_BORDER
+                       );
+               break;
+       
+       case ELETYPE_BUTTON:
+               Video_FillRect(
+                       Element->CachedX+1, Element->CachedY+1,
+                       Element->CachedW-2, Element->CachedH-2,
+                       BUTTON_BORDER
+                       );
+               Video_DrawRect(
+                       Element->CachedX, Element->CachedY,
+                       Element->CachedW-1, Element->CachedH-1,
+                       BUTTON_BORDER
+                       );
+               break;
+       
+       case ELETYPE_TEXT:
+               Video_DrawText(
+                       Element->CachedX+1, Element->CachedY+1,
+                       Element->CachedW-2, Element->CachedH-2,
+                       NULL,
+                       10,
+                       TEXT_COLOUR,
+                       Element->Text
+                       );
+               break;
+       }
+}
index 1eec6b4..3876b77 100644 (file)
@@ -15,40 +15,45 @@ tElement    *gpInterface_TabContent;
 // === CODE ===
 void Interface_Init(void)
 {
+       tElement        *area;
        tElement        *btn, *text;
        
        giInterface_Width = giScreenWidth/16;
        
-       WM_SetFlags(NULL, ELEFLAG_HORIZONTAL);
+       WM_SetFlags(NULL, 0);
        
        // Create Sidebar
        gpInterface_Sidebar = WM_CreateElement(NULL, ELETYPE_TOOLBAR, ELEFLAG_VERTICAL);
        WM_SetSize( gpInterface_Sidebar, giInterface_Width );
        // Create Main Area and regions within
        gpInterface_MainArea = WM_CreateElement(NULL, ELETYPE_BOX, ELEFLAG_VERTICAL);
-       gpInterface_HeaderBar = WM_CreateElement(gpInterface_MainArea, ELETYPE_BOX, ELEFLAG_HORIZONTAL);
+       gpInterface_HeaderBar = WM_CreateElement(gpInterface_MainArea, ELETYPE_BOX, 0);
        gpInterface_TabBar = WM_CreateElement(gpInterface_MainArea, ELETYPE_TABBAR, 0);
        gpInterface_TabContent = WM_CreateElement(gpInterface_MainArea, ELETYPE_BOX, 0);
        
+       // Main segment of the "taskbar"
+       area = WM_CreateElement(gpInterface_Sidebar, ELETYPE_BOX, ELEFLAG_VERTICAL);
        // Menu Button
-       btn = WM_CreateElement(gpInterface_Sidebar, ELETYPE_BUTTON, 0);
+       btn = WM_CreateElement(area, ELETYPE_BUTTON, ELEFLAG_NOEXPAND);
        WM_SetSize(btn, giInterface_Width);
        //text = WM_CreateElement(btn, ELETYPE_IMAGE, ELEFLAG_SCALE);
-       //WM_SetText(text, "asset://LogoSmall.png");
+       //WM_SetText(text, "asset://LogoSmall.sif");
        text = WM_CreateElement(btn, ELETYPE_TEXT, 0);
        WM_SetText(text, "Acess");
        
        // Plain <hr/> style spacer
-       WM_CreateElement(gpInterface_Sidebar, ELETYPE_SPACER, 0);
+       WM_CreateElement(area, ELETYPE_SPACER, 0);
        
-       // Create spacing gap (aligns the rest to the bottom/right)
-       WM_CreateElement(gpInterface_Sidebar, ELETYPE_GAP, 0);
+       // Windows Go Here
+       
+       // Bottom Segment
+       area = WM_CreateElement(gpInterface_Sidebar, ELETYPE_BOX, ELEFLAG_VERTICAL|ELEFLAG_ALIGN_END);
        
        // Plain <hr/> style spacer
-       WM_CreateElement(gpInterface_Sidebar, ELETYPE_SPACER, 0);
+       WM_CreateElement(area, ELETYPE_SPACER, 0);
        
        // Version String
-       text = WM_CreateElement(gpInterface_Sidebar, ELETYPE_TEXT, ELEFLAG_WRAP);
+       text = WM_CreateElement(area, ELETYPE_TEXT, ELEFLAG_WRAP);
        WM_SetText(text, "AxWin 1.0");
 }
 
index 1a68acb..1234b66 100644 (file)
@@ -8,6 +8,7 @@
 // === IMPORTS ===
 extern void    ParseCommandline(int argc, char *argv[]);
 extern void    Video_Setup(void);
+extern void    WM_Update(void);
 extern void    Messages_PollIPC(void);
 
 // === GLOBALS ===
@@ -31,11 +32,13 @@ int main(int argc, char *argv[])
        ParseCommandline(argc, argv);
        
        if( gsTerminalDevice == NULL ) {
-               gsTerminalDevice = "/Devices/VTerm/7";
+               gsTerminalDevice = "/Devices/VTerm/6";
        }
        
        Video_Setup();
-       Interface_Render();
+       Interface_Init();
+       
+       WM_Update();
        
        // Main Loop
        for(;;)
index 01bd07c..92137f0 100644 (file)
@@ -60,14 +60,16 @@ void Messages_Handle(tAxWin_Message *Msg, tMessages_Handle_Callback *Respond, in
 {
        switch(Msg->ID)
        {
+       #if 0
        case MSG_SREQ_PING:
-               Msg->ID = MSG_SRSP_PONG;
+               Msg->ID = MSG_SRSP_VERSION;
                Msg->Size = 2;
-               Msg->SRsp_Pong.Major = 0;
-               Msg->SRsp_Pong.Minor = 1;
-               Msg->SRsp_Pong.Build = -1;
+               Msg->Data[0] = 0;
+               Msg->Data[1] = 1;
+               *(uint16_t*)&Msg->Data[2] = -1;
                Messages_RespondIPC(ID, sizeof(Msg->ID), Msg);
                break;
+       #endif
        default:
                fprintf(stderr, "WARNING: Unknown message %i from %i (%p)\n", Msg->ID, ID, Respond);
                _SysDebug("WARNING: Unknown message %i from %i (%p)\n", Msg->ID, ID, Respond);
index fb08208..80e1302 100644 (file)
@@ -70,9 +70,31 @@ void Video_FillRect(short X, short Y, short W, short H, uint32_t Color)
 {
        uint32_t        *buf = gpScreenBuffer + Y*giScreenWidth + X;
        
+       _SysDebug("Video_FillRect: (X=%i, Y=%i, W=%i, H=%i, Color=%08x)",
+               X, Y, W, H, Color);
+       
+       if(W < 0 || X < 0 || X >= giScreenWidth)        return ;
+       if(X + W > giScreenWidth)       W = giScreenWidth - X;
+       
+       if(H < 0 || H < 0 || H >= giScreenHeight)       return ;
+       if(Y + H > giScreenHeight)      H = giScreenHeight - Y;
+       
        while( H -- )
        {
                memset32( buf, Color, W );
                buf += giScreenWidth;
        }
 }
+
+void Video_DrawRect(short X, short Y, short W, short H, uint32_t Color)
+{      
+       Video_FillRect(X, Y, W, 1, Color);
+       Video_FillRect(X, Y+H-1, W, 1, Color);
+       Video_FillRect(X, Y, 1, H, Color);
+       Video_FillRect(X+W-1, Y, 1, H, Color);
+}
+
+void Video_DrawText(short X, short Y, short W, short H, void *Font, int Point, uint32_t Color, char *Text)
+{
+       // TODO!
+}
index 7763d3b..b91c756 100644 (file)
@@ -9,26 +9,45 @@
 #include <strings.h>
 #include "wm.h"
 
-tElement       gWM_RootElement;
+// === IMPORTS ===
+extern void    Decorator_RenderWidget(tElement *Element);
 
 // === PROTOTYPES ===
 tElement       *WM_CreateElement(tElement *Parent, int Type, int Flags);
 void   WM_SetFlags(tElement *Element, int Flags);
 void   WM_SetSize(tElement *Element, int Size);
 void   WM_SetText(tElement *Element, char *Text);
+void   WM_UpdateDimensions(tElement *Element, int Pass);
+void   WM_UpdatePosition(tElement *Element);
+void   WM_RenderWidget(tElement *Element);
+void   WM_Update(void);
+
+// === GLOBALS ===
+tElement       gWM_RootElement;
+struct {
+       void    (*Init)(tElement *This);
+       void    (*UpdateFlags)(tElement *This);
+       void    (*UpdateSize)(tElement *This);
+       void    (*UpdateText)(tElement *This);
+}      gaWM_WidgetTypes[MAX_ELETYPES] = {
+       {NULL, NULL, NULL, NULL},       // NULL
+       {NULL, NULL, NULL, NULL}        // Box
+};
 
 // === CODE ===
+// --- Widget Creation and Control ---
 tElement *WM_CreateElement(tElement *Parent, int Type, int Flags)
 {
        tElement        *ret;
        
-       if(Type < 0 || Type >= NUM_ELETYPES)    return NULL;
+       if(Type < 0 || Type > NUM_ELETYPES)     return NULL;
        
        ret = calloc(sizeof(tElement), 1);
        if(!ret)        return NULL;
        
        // Prepare
        ret->Type = Type;
+       if(Parent == NULL)      Parent = &gWM_RootElement;
        ret->Parent = Parent;
        
        // Append to parent's list
@@ -36,6 +55,11 @@ tElement *WM_CreateElement(tElement *Parent, int Type, int Flags)
        Parent->LastChild = ret;
        if(!Parent->FirstChild) Parent->FirstChild = ret;
        
+       ret->PaddingL = 2;
+       ret->PaddingR = 2;
+       ret->PaddingT = 2;
+       ret->PaddingB = 2;
+       
        return ret;
 }
 
@@ -63,5 +87,402 @@ void WM_SetText(tElement *Element, char *Text)
        if(!Element)    return ;
        if(Element->Text)       free(Element->Text);
        Element->Text = strdup(Text);
+       
+       switch(Element->Type)
+       {
+       case ELETYPE_IMAGE:
+               if(Element->Data)       free(Element->Data);
+               Element->Data = LoadImage( Element->Text );
+               if(!Element->Data) {
+                       Element->Flags &= ~ELEFLAG_FIXEDSIZE;
+                       return ;
+               }
+               
+               Element->Flags |= ELEFLAG_FIXEDSIZE;
+               Element->CachedW = ((tImage*)Element->Data)->Width;
+               Element->CachedH = ((tImage*)Element->Data)->Height;
+               
+               if(Element->Parent && Element->Parent->Flags & ELEFLAG_VERTICAL)
+                       Element->Size = Element->CachedH;
+               else
+                       Element->Size = Element->CachedW;
+               break;
+       }
+       
        return ;
 }
+
+// --- Pre-Rendering ---
+#if 0
+void WM_UpdateDimensions(tElement *Element, int Pass)
+{
+       // Pass zero intialises
+       if( Pass == 0 )
+       {
+               // If not a fixed size element, initialise the sizes
+               if( !(Element->Flags & ELEFLAG_FIXEDSIZE) )
+               {
+                       Element->CachedH = 0;
+                       Element->CachedW = 0;
+                       if( Element->Size )
+                       {
+                               if( Element->Parent->Flags & ELEFLAG_VERTICAL )
+                                       Element->CachedH = Element->Size;
+                               else
+                                       Element->CachedW = Element->Size;
+                       }
+               }
+       }
+
+        int    fixedSize = 0, maxCross = 0;
+        int    nFixed = 0, nChildren = 0;
+       for( child = Element->FirstChild; child; child = child->NextSibling )
+       {
+               WM_UpdateDimensions( child, 0 );
+               
+               if( Element->Flags & ELEFLAG_VERTICAL )
+               {
+                       if( child->CachedH ) {
+                               fixedSize += child->CachedH;
+                               nFixed ++;
+                       }
+                       if( maxCross < child->CachedW )
+                               maxCross = child->CachedW;
+               }
+               else
+               {
+                       if( child->CachedW ) {
+                               fixedSize += child->CachedW;
+                               nFixed ++;
+                       }
+                       if( maxCross < child->CachedH )
+                               maxCross = child->CachedH;
+               }
+               nChildren ++;
+       }
+
+
+       // If we don't have our dimensions, get the child dimensions
+       if( Element->CachedW == 0 || Element->CachedH == 0 )
+       {       
+               if( Element->Flags & ELEFLAG_VERTICAL )
+               {
+                       if( Element->CachedW == 0 && maxCross )
+                               Element->CachedW = Element->PaddingL
+                                       + Element->PaddingR + maxCross;
+                       
+                       if( Element->CachedH == 0 && nFixed == nChildren )
+                               Element->CachedH = Element->PaddingT
+                                       + Element->PaddingB + fixedSize
+                                       + nChildren * Element->GapSize;
+               }
+               else
+               {
+                       if( maxCross )
+                               Element->CachedH = Element->PaddingT
+                                       + Element->PaddingB + maxCross;
+                       
+                       if( Element->CachedW == 0 && nFixed == nChildren )
+                               Element->CachedW = Element->PaddingL
+                                       + Element->PaddingR + fixedSize
+                                       + nChildren * Element->GapSize;
+               }
+       }
+       
+       // Now, if we have the "length" of the widget, we can size the children
+       if( (Element->Flags & ELEFLAG_VERTICAL && Element->CachedH > 0)
+        || (!(Element->Flags & ELEFLAG_VERTICAL) && Element->CachedW > 0) )
+       {
+                int    dynSize;
+               
+               // Calculate the size of dynamically sized elements
+               if( Element->Flags & ELEFLAG_VERTICAL )
+                       dynSize = Element->CachedH - Element->PaddingT
+                                - Element->PaddingB - fixedSize;
+               else
+                       dynSize = Element->CachedW - Element->PaddingL
+                                - Element->PaddingR - fixedSize;
+               dynSize /= nChildren - nFixed;
+               
+               // Itterate children again
+               for( child = Element->FirstChild; child; child = child->NextSibling )
+               {
+                        int    tmp;
+                       
+                       // Get the size of them
+                       if(child->Size)
+                               tmp = child->Size;
+                       else if(dynSize < Element->MinSize)
+                               tmp = child->MinSize;
+                       else
+                               tmp = dynSize;
+                       
+                       if( Element->Flags & ELEFLAG_VERTICAL )
+                               child->CachedH = tmp;
+                       else
+                               child->CachedW = tmp;
+                       
+                       WM_UpdateDimensions(child, 1);
+               }
+       }
+}
+
+#endif
+
+/**
+ * \brief Updates the dimensions of an element
+ * 
+ * The dimensions of an element are calculated from the parent's
+ * cross dimension (the side at right angles to the alignment) sans some
+ * padding.
+ */
+void WM_UpdateDimensions(tElement *Element, int Pass)
+{
+       tElement        *child;
+        int    fixedChildSize = 0;
+        int    dynamicSize;
+        int    nChildren = 0;
+        int    nFixed = 0;
+       
+       _SysDebug("WM_UpdateDimensions: (Element=%p{Flags:0x%x}, Pass=%i)",
+               Element, Element->Flags,
+               Pass);
+       
+       if( Pass == 0 )
+       {
+               if( Element->Flags & ELEFLAG_NORENDER ) return ;
+               
+               if( !(Element->Flags & ELEFLAG_ABSOLUTEPOS) ) {
+                       Element->CachedX = 0;
+                       Element->CachedY = 0;
+               }
+               if( !(Element->Flags & ELEFLAG_FIXEDSIZE) ) {
+                       Element->CachedW = 0;
+                       Element->CachedH = 0;
+               }
+       }
+       
+       if( !(Element->Flags & ELEFLAG_FIXEDSIZE) ) {
+               // If the element is sized, fix its dimension(s)
+               if(Element->Size)
+               {
+                       if(Element->Flags & ELEFLAG_NOEXPAND)
+                       {
+                               Element->CachedW = Element->Size;
+                               Element->CachedH = Element->Size;
+                       }
+                       else {
+                               if( Element->Parent->Flags & ELEFLAG_VERTICAL ) {
+                                       Element->CachedH = Element->Size;
+                                       Element->CachedW = Element->Parent->CachedW;
+                                       if(Element->CachedW)
+                                               Element->CachedW -= (Element->Parent->PaddingL + Element->Parent->PaddingR);
+                               }
+                               else {
+                                       Element->CachedW = Element->Size;
+                                       Element->CachedH = Element->Parent->CachedH;
+                                       if(Element->CachedH)
+                                               Element->CachedH -= (Element->Parent->PaddingT + Element->Parent->PaddingB);
+                               }
+                       }
+               }
+               else {
+                       // Ok, so now we need to calculate the size of all child elements
+                       // However, if ELEFLAG_NOEXPAND is not set, we can still set one
+                       // dimension
+                       if( !(Element->Flags & ELEFLAG_NOEXPAND) ) {
+                               if( Element->Parent->Flags & ELEFLAG_VERTICAL ) {
+                                       Element->CachedW = Element->Parent->CachedW;
+                                       if(Element->CachedW)
+                                               Element->CachedW -= (Element->Parent->PaddingL + Element->Parent->PaddingR);
+                               }
+                               else {
+                                       Element->CachedH = Element->Parent->CachedH;
+                                       if(Element->CachedH)
+                                               Element->CachedH -= (Element->Parent->PaddingT + Element->Parent->PaddingB);
+                               }
+                       }
+               }
+       }
+       
+       // Process Children (first pass)
+       for( child = Element->FirstChild; child; child = child->NextSibling )
+       {
+               if( child->Flags & ELEFLAG_NORENDER )   continue;
+               WM_UpdateDimensions(child, 0);
+               
+               // Children that don't inherit positions are ignored
+               if( child->Flags & ELEFLAG_ABSOLUTEPOS )        continue;
+               
+               fixedChildSize += child->Size;
+               if(child->Size > 0)
+                       nFixed ++;
+               nChildren ++;
+               
+               // If we are wrapping the children, get the largest cross size
+               if( !(Element->Flags & ELEFLAG_FIXEDSIZE)
+                && Element->Flags & ELEFLAG_NOEXPAND
+                && Element->Size == 0 )
+               {
+                       if( Element->Flags & ELEFLAG_VERTICAL ) {
+                               if( Element->CachedW < child->CachedW )
+                                       Element->CachedW = child->CachedW;
+                       }
+                       else {
+                               if( Element->CachedH < child->CachedH )
+                                       Element->CachedH = child->CachedH;
+                       }
+               }
+       }
+       
+       // Let's avoid a #DIV0 shall we?
+       if( nChildren > 0 )
+       {
+               // Calculate the size of dynamically sized children
+               if( Element->Flags & ELEFLAG_VERTICAL ) {
+                       if( Element->CachedH == 0 ) {
+                               if( nFixed == nChildren )
+                                       Element->CachedH = fixedChildSize;
+                               else
+                                       return ;
+                       }
+                       dynamicSize = (Element->CachedH - (Element->PaddingT + Element->PaddingB)  - fixedChildSize) / nChildren;
+               }
+               else {
+                       if( Element->CachedW == 0 ) {
+                               if( nFixed == nChildren )
+                                       Element->CachedW = fixedChildSize;
+                               else
+                                       return ;
+                       }
+                       dynamicSize = (Element->CachedW - (Element->PaddingL + Element->PaddingR) - fixedChildSize) / nChildren;
+               }
+               
+               // Process Children (second pass)
+               for( child = Element->FirstChild; child; child = child->NextSibling )
+               {
+                       if( child->Flags & ELEFLAG_NORENDER )   continue;
+                       // Children that don't inherit positions are ignored
+                       if( child->Flags & ELEFLAG_ABSOLUTEPOS )        continue;
+                       
+                       if(!child->Size) {
+                               if(child->Flags & ELEFLAG_VERTICAL)
+                                       child->CachedH = dynamicSize;
+                               else
+                                       child->CachedW = dynamicSize;
+                       }
+                       
+                       WM_UpdateDimensions(child, 1);
+                       
+                       // If we are wrapping the children, get the largest cross size
+                       if( Element->Flags & ELEFLAG_NOEXPAND ) {
+                               if( Element->Flags & ELEFLAG_VERTICAL ) {
+                                       if( Element->CachedW < child->CachedW )
+                                               Element->CachedW = child->CachedW;
+                               }
+                               else {
+                                       if( Element->CachedH < child->CachedH )
+                                               Element->CachedH = child->CachedH;
+                               }
+                       }
+               }
+       }
+       
+       // Add the padding
+       //Element->CachedW += Element->PaddingL + Element->PaddingR;
+       //Element->CachedH += Element->PaddingT + Element->PaddingB;
+       
+       _SysDebug("Pass %i, Element %p %ix%i",
+               Pass, Element, Element->CachedW, Element->CachedH
+               );
+       
+       // We should be done
+       // Next function will do the coordinates
+}
+
+
+/**
+ * \brief Updates the position of an element
+ * 
+ * The parent element sets the positions of its children
+ */
+void WM_UpdatePosition(tElement *Element)
+{
+       tElement        *child;
+        int    x, y;
+       
+       if( Element->Flags & ELEFLAG_NORENDER ) return ;
+       
+       _SysDebug("Element=%p{PaddingL:%i, PaddingT:%i}",
+               Element, Element->PaddingL, Element->PaddingT);
+       
+       // Initialise
+       x = Element->CachedX + Element->PaddingL;
+       y = Element->CachedY + Element->PaddingT;
+       
+       // Update each child
+       for(child = Element->FirstChild; child; child = child->NextSibling)
+       {
+               child->CachedX = x;
+               child->CachedY = y;
+               
+               // Set Alignment
+               if( Element->Flags & ELEFLAG_ALIGN_CENTER ) {
+                       if(Element->Flags & ELEFLAG_VERTICAL )
+                               child->CachedX += Element->CachedW/2 - child->CachedW/2;
+                       else
+                               child->CachedY += Element->CachedH/2 - child->CachedH/2;
+               }
+               else if( Element->Flags & ELEFLAG_ALIGN_END ) {
+                       if(Element->Flags & ELEFLAG_VERTICAL )
+                               child->CachedX += Element->CachedW - child->CachedW;
+                       else
+                               child->CachedY += Element->CachedH - child->CachedH;
+               }
+               
+               // Update child's children positions
+               WM_UpdatePosition(child);
+               
+               // Increment
+               if(Element->Flags & ELEFLAG_VERTICAL ) {
+                       y += child->CachedH + Element->GapSize;
+               }
+               else {
+                       x += child->CachedW + Element->GapSize;
+               }
+       }
+       
+       _SysDebug("Element %p (%i,%i)",
+                Element, Element->CachedX, Element->CachedY
+               );
+}
+
+// --- Render ---
+void WM_RenderWidget(tElement *Element)
+{
+       tElement        *child;
+       
+       if( Element->Flags & ELEFLAG_NORENDER ) return ;
+       if( Element->Flags & ELEFLAG_INVISIBLE )        return ;
+       
+       Decorator_RenderWidget(Element);
+       
+       for(child = Element->FirstChild; child; child = child->NextSibling)
+       {
+               WM_RenderWidget(child);
+       }
+}
+
+void WM_Update(void)
+{
+       gWM_RootElement.CachedX = 0;    gWM_RootElement.CachedY = 0;
+       gWM_RootElement.CachedW = giScreenWidth;
+       gWM_RootElement.CachedH = giScreenHeight;
+       gWM_RootElement.Flags |= ELEFLAG_NOEXPAND|ELEFLAG_ABSOLUTEPOS|ELEFLAG_FIXEDSIZE;
+       
+       WM_UpdateDimensions( &gWM_RootElement, 0 );
+       WM_UpdatePosition( &gWM_RootElement );
+       WM_RenderWidget( &gWM_RootElement );
+       
+       Video_Update();
+}
index 38dc1ac..82c022a 100644 (file)
@@ -11,11 +11,9 @@ typedef struct sElement
        struct sElement *LastChild;
        struct sElement *NextSibling;
        
-       
-       short   CachedX;
-       short   CachedY;
-       short   CachedW;
-       short   CachedH;
+       short   PaddingL, PaddingR;
+       short   PaddingT, PaddingB;
+       short   GapSize;
        
        short   Size;   // Size attribute
        
@@ -23,6 +21,10 @@ typedef struct sElement
        void    *Data;
        
        uint32_t        Flags;
+       
+       // -- Render Cache
+       short   CachedX, CachedY;
+       short   CachedW, CachedH;
 }      tElement;
 
 typedef struct sTab
@@ -51,10 +53,57 @@ typedef struct sApplication
 // === CONSTANTS ===
 enum eElementFlags
 {
-       ELEFLAG_VISIBLE     = 0x001,    ELEFLAG_INVISIBLE   = 0x000,
-       ELEFLAG_VERTICAL    = 0x002,    ELEFLAG_HORIZONTAL  = 0x000,
-       ELEFLAG_WRAP        = 0x004,    ELEFLAG_NOWRAP      = 0x000,
+       /**
+        * \brief Rendered
+        * 
+        * If set, the element will be ignored in calculating sizes and
+        * rendering.
+        */
+       ELEFLAG_NORENDER    = 0x001,
+       /**
+        * \brief Element visibility
+        * 
+        * If set, the element is not drawn.
+        */
+       ELEFLAG_INVISIBLE   = 0x002,
+       
+       /**
+        * \brief Position an element absulutely
+        */
+       ELEFLAG_ABSOLUTEPOS = 0x004,
+       
+       /**
+        * \brief Fixed size element
+        */
+       ELEFLAG_FIXEDSIZE   = 0x008,
+       
+       /**
+        * \brief Element "orientation"
+        */
+       ELEFLAG_VERTICAL    = 0x010,//  ELEFLAG_HORIZONTAL  = 0x000,
+       /**
+        * \brief Action for text that overflows
+        */
+       ELEFLAG_WRAP        = 0x020,//  ELEFLAG_NOWRAP      = 0x000,
+       /**
+        * \brief Cross size action
+        * 
+        * If this flag is set, the element will only be as large (across
+        * its parent) as is needed to encase the contents of the element.
+        * Otherwise, the element will expand to fill all avaliable space.
+        */
+       ELEFLAG_NOEXPAND    = 0x040,    //      ELEFLAG_EXPAND      = 0x000
+       
+       /**
+        * \brief Center alignment
+        */
+       ELEFLAG_ALIGN_CENTER= 0x080,
+       /**
+        * \brief Right/Bottom alignment
+        */
+       ELEFLAG_ALIGN_END = 0x100
 };
+
 /**
  */
 enum eElementTypes
@@ -67,11 +116,11 @@ enum eElementTypes
        
        ELETYPE_BUTTON, //!< Push Button
        ELETYPE_TEXT,   //!< Text
+       ELETYPE_IMAGE,  //!< Image
        
        ELETYPE_SPACER, //!< Visual Spacer
-       ELETYPE_GAP,    //!< Alignment Gap
        
-       NUM_ELETYPES
+       MAX_ELETYPES    = 0x100
 };
 
 // === FUNCTIONS ===
index 5fdac4c..4a6a779 100644 (file)
@@ -150,20 +150,28 @@ EXPORT int vfprintf(FILE *fp, const char *format, va_list args)
 {\r
        va_list tmpList = args;\r
         int    size;\r
-       char    *buf;\r
+       char    sbuf[1024];\r
+       char    *buf = sbuf;\r
         \r
        if(!fp || !format)      return -1;\r
        \r
-       size = vsprintf(NULL, (char*)format, tmpList);\r
+       size = vsnprintf(sbuf, 1024, (char*)format, tmpList);\r
        \r
-       buf = (char*)malloc(size+1);\r
-       buf[size] = '\0';\r
+       if( size >= 1024 )\r
+       {\r
+               buf = (char*)malloc(size+1);\r
+               if(!buf) {\r
+                       write(_stdout, 31, "vfprintf ERROR: malloc() failed");\r
+                       return 0;\r
+               }\r
+               buf[size] = '\0';\r
        \r
-       // Print\r
-       vsprintf(buf, (char*)format, args);\r
+               // Print\r
+               vsnprintf(buf, size+1, (char*)format, args);\r
+       }\r
        \r
        // Write to stream\r
-       write(fp->FD, size+1, buf);\r
+       write(fp->FD, size, buf);\r
        \r
        // Free buffer\r
        free(buf);\r
@@ -271,15 +279,20 @@ EXPORT int        puts(const char *str)
        return len;\r
 }\r
 \r
+EXPORT int vsprintf(char * __s, const char *__format, va_list __args)\r
+{\r
+       return vsnprintf(__s, 0x7FFFFFFF, __format, __args);\r
+}\r
+\r
 //sprintfv\r
 /**\r
- \fn EXPORT void vsprintf(char *buf, const char *format, va_list args)\r
+ \fn EXPORT void vsnprintf(char *buf, const char *format, va_list args)\r
  \brief Prints a formatted string to a buffer\r
  \param buf    Pointer - Destination Buffer\r
  \param format String - Format String\r
  \param args   VarArgs List - Arguments\r
 */\r
-EXPORT int vsprintf(char *buf, const char *format, va_list args)\r
+EXPORT int vsnprintf(char *buf, size_t __maxlen, const char *format, va_list args)\r
 {\r
        char    tmp[33];\r
         int    c, minSize;\r
@@ -295,7 +308,7 @@ EXPORT int vsprintf(char *buf, const char *format, va_list args)
        {\r
                // Non-control character\r
                if (c != '%') {\r
-                       if(buf) buf[pos] = c;\r
+                       if(buf && pos < __maxlen)       buf[pos] = c;\r
                        pos ++;\r
                        continue;\r
                }\r
@@ -303,7 +316,7 @@ EXPORT int vsprintf(char *buf, const char *format, va_list args)
                // Control Character\r
                c = *format++;\r
                if(c == '%') {  // Literal %\r
-                       if(buf) buf[pos] = '%';\r
+                       if(buf && pos < __maxlen)       buf[pos] = '%';\r
                        pos ++;\r
                        continue;\r
                }\r
@@ -358,7 +371,7 @@ EXPORT int vsprintf(char *buf, const char *format, va_list args)
                \r
                // Pointer\r
                case 'p':\r
-                       if(buf) {\r
+                       if(buf && pos+2 < __maxlen) {\r
                                buf[pos] = '*';\r
                                buf[pos+1] = '0';\r
                                buf[pos+2] = 'x';\r
@@ -394,7 +407,8 @@ EXPORT int vsprintf(char *buf, const char *format, va_list args)
                        if(!p)  p = "(null)";\r
                        if(buf) {\r
                                while(*p) {\r
-                                       buf[pos++] = *p++;\r
+                                       if(pos < __maxlen)      buf[pos] = *p;\r
+                                       pos ++; p ++;\r
                                }\r
                        }\r
                        else {\r
@@ -407,12 +421,12 @@ EXPORT int vsprintf(char *buf, const char *format, va_list args)
                // Unknown, just treat it as a character\r
                default:\r
                        arg = va_arg(args, uint32_t);\r
-                       if(buf) buf[pos] = arg;\r
+                       if(buf && pos < __maxlen)       buf[pos] = arg;\r
                        pos ++;\r
                        break;\r
                }\r
     }\r
-       if(buf) buf[pos] = '\0';\r
+       if(buf && pos < __maxlen)       buf[pos] = '\0';\r
        \r
        return pos;\r
 }\r
@@ -463,22 +477,29 @@ EXPORT int printf(const char *format, ...)
 {\r
        #if 1\r
         int    size;\r
-       char    *buf;\r
+       char    sbuf[1024];\r
+       char    *buf = sbuf;\r
        va_list args;\r
        \r
        // Get final size\r
        va_start(args, format);\r
-       size = vsprintf(NULL, (char*)format, args);\r
+       size = vsnprintf(sbuf, 1024, (char*)format, args);\r
        va_end(args);\r
        \r
-       // Allocate buffer\r
-       buf = (char*)malloc(size+1);\r
-       buf[size] = '\0';\r
+       if( size >= 1024 ) {\r
+               // Allocate buffer\r
+               buf = (char*)malloc(size+1);\r
+               if(buf) {\r
+                       write(_stdout, 29, "PRINTF ERROR: malloc() failed");\r
+                       return 0;\r
+               }\r
+               buf[size] = '\0';\r
        \r
-       // Fill Buffer\r
-       va_start(args, format);\r
-       vsprintf(buf, (char*)format, args);\r
-       va_end(args);\r
+               // Fill Buffer\r
+               va_start(args, format);\r
+               vsnprintf(buf, size+1, (char*)format, args);\r
+               va_end(args);\r
+       }\r
        \r
        // Send to stdout\r
        write(_stdout, size+1, buf);\r
index 8a14223..4d53ab5 100644 (file)
@@ -50,6 +50,7 @@ enum eAxWin_Messages
        MSG_SREQ_SETFONT,       MSG_SREQ_PUTTEXT,
        
        // Server Responses
+       MSG_SRSP_VERSION,
        MSG_SRSP_RETURN,        // {int RequestID, void[] Return Value} - Returns a value from a server request
        
        NUM_MSG
@@ -79,7 +80,7 @@ struct sAxWin_SReq_NewWindow
  * \brief Server Response - Pong
  * \see eAxWin_Messages.MSG_SRSP_PONG
  */
-struct sAxWin_SRsp_Pong
+struct sAxWin_SRsp_Version
 {
        uint8_t Major;
        uint8_t Minor;
index 985f058..1223fe8 100644 (file)
@@ -16,6 +16,7 @@ typedef struct sFILE  FILE;
 \r
 // --- Standard IO ---\r
 extern int     printf(const char *format, ...);\r
+extern int     vsnprintf(char *buf, size_t __maxlen, const char *format, va_list args);\r
 extern int     vsprintf(char *buf, const char *format, va_list args);\r
 extern int     sprintf(char *buf, const char *format, ...);\r
 \r
diff --git a/Usermode/include/string.h b/Usermode/include/string.h
deleted file mode 100644 (file)
index 1e72197..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * AcessOS LibC
- * string.h
- */
-#ifndef __STRING_H
-#define __STRING_H
-
-#include <stddef.h>
-
-// Strings
-extern int     strlen(const char *string);
-extern int     strcmp(const char *str1, const char *str2);
-extern int     strncmp(const char *str1, const char *str2, size_t len);
-extern char    *strcpy(char *dst, const char *src);
-extern char    *strncpy(char *dst, const char *src, size_t num);
-extern char    *strcat(char *dst, const char *src);
-extern char    *strdup(const char *src);
-extern char    *strchr(char *str, int character);
-extern char    *strrchr(char *str, int character);
-extern char    *strstr(char *str1, const char *str2);
-
-// Memory
-extern void *memset(void *dest, int val, size_t count);
-extern void *memcpy(void *dest, const void *src, size_t count);
-extern void *memmove(void *dest, const void *src, size_t count);
-extern int     memcmp(const void *mem1, const void *mem2, size_t count);
-extern void    *memchr(void *ptr, int value, size_t num);
-
-#endif
index 119bb6a..d9e7ada 100644 (file)
@@ -40,5 +40,3 @@ extern int    pollmsg(int *src, unsigned int *Data);
 extern int     getmsg(int *src, unsigned int *Data);\r
 \r
 #endif\r
-\r
-#endif\r

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