Merge branch 'master' of git://git.ucc.asn.au/tpg/acess2
authorJohn Hodge <[email protected]>
Wed, 28 Nov 2012 04:07:57 +0000 (12:07 +0800)
committerJohn Hodge <[email protected]>
Wed, 28 Nov 2012 04:07:57 +0000 (12:07 +0800)
129 files changed:
AcessNative/Makefile
AcessNative/acesskernel_src/Makefile
AcessNative/acesskernel_src/include/mouse_int.h [new file with mode: 0644]
AcessNative/acesskernel_src/main.c
AcessNative/acesskernel_src/mouse.c
AcessNative/acesskernel_src/server.c
AcessNative/acesskernel_src/syscalls.c
AcessNative/acesskernel_src/threads.c
AcessNative/acesskernel_src/ui.h
AcessNative/acesskernel_src/ui_sdl.c
AcessNative/acesskernel_src/vfs_handle.c
AcessNative/acesskernel_src/video.c
AcessNative/ld-acess_src/common.h
AcessNative/ld-acess_src/elf.c [changed from symlink to file mode: 0644]
AcessNative/ld-acess_src/elf32.h [changed from symlink to file mode: 0644]
AcessNative/ld-acess_src/elf64.h [changed from symlink to file mode: 0644]
AcessNative/ld-acess_src/exports.c
AcessNative/ld-acess_src/exports.h
AcessNative/ld-acess_src/request.c
AcessNative/ld-acess_src/syscalls.c
AcessNative/syscalls.h
BuildConf/host/Makefile.cfg
BuildConf/x86/Makefile.cfg
BuildConf/x86_64/Makefile.cfg
KernelLand/Kernel/arch/armv7/lib.c
KernelLand/Kernel/arch/armv7/mm_virt.c
KernelLand/Kernel/arch/armv7/proc.c
KernelLand/Kernel/arch/armv7/start.S
KernelLand/Kernel/arch/armv7/vpci_realview_pb.c [new file with mode: 0644]
KernelLand/Kernel/arch/x86/link.ld
KernelLand/Kernel/arch/x86/mboot.c
KernelLand/Kernel/arch/x86/start.asm
KernelLand/Kernel/arch/x86_64/desctab.asm
KernelLand/Kernel/arch/x86_64/errors.c
KernelLand/Kernel/arch/x86_64/include/mm_virt.h
KernelLand/Kernel/arch/x86_64/mm_virt.c
KernelLand/Kernel/arch/x86_64/proc.asm
KernelLand/Kernel/arch/x86_64/proc.c
KernelLand/Kernel/bin/elf.c
KernelLand/Kernel/binary.c
KernelLand/Kernel/drv/vterm_input.c
KernelLand/Kernel/include/api_drv_keyboard.h
KernelLand/Kernel/include/logdebug.h
KernelLand/Kernel/lib.c
KernelLand/Kernel/libc.c
KernelLand/Kernel/logging.c
KernelLand/Kernel/messages.c
KernelLand/Kernel/syscalls.c
KernelLand/Kernel/threads.c
KernelLand/Kernel/vfs/mmap.c
KernelLand/Kernel/vfs/nodecache.c
KernelLand/Modules/Display/BochsGA/bochsvbe.c
KernelLand/Modules/Filesystems/FAT/fat.c
KernelLand/Modules/Filesystems/InitRD/GenerateInitRD.php
KernelLand/Modules/Filesystems/InitRD/files.lst
KernelLand/Modules/USB/Core/usb.c
KernelLand/Modules/USB/Core/usb.h
KernelLand/Modules/USB/Core/usb_devinit.c
KernelLand/Modules/USB/Core/usb_lowlevel.c
KernelLand/Modules/USB/UHCI/uhci.c
Makefile
RunQemu
Usermode/Applications/axwin3_src/Interface/main.c
Usermode/Applications/axwin3_src/WM/Makefile
Usermode/Applications/axwin3_src/WM/include/wm.h
Usermode/Applications/axwin3_src/WM/include/wm_internals.h
Usermode/Applications/axwin3_src/WM/include/wm_renderer.h
Usermode/Applications/axwin3_src/WM/ipc.c
Usermode/Applications/axwin3_src/WM/main.c
Usermode/Applications/axwin3_src/WM/renderers/framebuffer.c [new file with mode: 0644]
Usermode/Applications/axwin3_src/WM/renderers/menu.c
Usermode/Applications/axwin3_src/WM/renderers/passthru.c [deleted file]
Usermode/Applications/axwin3_src/WM/renderers/richtext.c [new file with mode: 0644]
Usermode/Applications/axwin3_src/WM/renderers/widget.c
Usermode/Applications/axwin3_src/WM/renderers/widget/subwin.c [new file with mode: 0644]
Usermode/Applications/axwin3_src/WM/video.c
Usermode/Applications/axwin3_src/WM/wm.c
Usermode/Applications/axwin3_src/include/framebuffer_messages.h
Usermode/Applications/axwin3_src/include/ipcmessages.h
Usermode/Applications/axwin3_src/include/menu_messages.h
Usermode/Applications/axwin3_src/include/richtext_messages.h [new file with mode: 0644]
Usermode/Applications/axwin3_src/include/widget_messages.h
Usermode/Applications/axwin3_src/libaxwin3.so_src/Makefile
Usermode/Applications/axwin3_src/libaxwin3.so_src/include/internal.h
Usermode/Applications/axwin3_src/libaxwin3.so_src/include/ipc.h
Usermode/Applications/axwin3_src/libaxwin3.so_src/main.c
Usermode/Applications/axwin3_src/libaxwin3.so_src/msg.c
Usermode/Applications/axwin3_src/libaxwin3.so_src/r_menu.c
Usermode/Applications/axwin3_src/libaxwin3.so_src/r_richtext.c [new file with mode: 0644]
Usermode/Applications/axwin3_src/libaxwin3.so_src/r_widget.c
Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c
Usermode/Applications/gui_ate_src/Makefile [new file with mode: 0644]
Usermode/Applications/gui_ate_src/edit.c [new file with mode: 0644]
Usermode/Applications/gui_ate_src/include/file.h [new file with mode: 0644]
Usermode/Applications/gui_ate_src/include/syntax.h [new file with mode: 0644]
Usermode/Applications/gui_ate_src/main.c [new file with mode: 0644]
Usermode/Applications/gui_shell_src/Makefile [new file with mode: 0644]
Usermode/Applications/gui_shell_src/include/display.h [new file with mode: 0644]
Usermode/Applications/gui_shell_src/include/vt100.h [new file with mode: 0644]
Usermode/Applications/gui_shell_src/main.c [new file with mode: 0644]
Usermode/Applications/gui_shell_src/vt100.c [new file with mode: 0644]
Usermode/Applications/telnetd_src/main.c
Usermode/Libraries/Makefile.tpl
Usermode/Libraries/ld-acess.so_src/arch/armv7.S.h
Usermode/Libraries/ld-acess.so_src/arch/syscalls.s.h
Usermode/Libraries/ld-acess.so_src/common.h
Usermode/Libraries/ld-acess.so_src/elf.c
Usermode/Libraries/ld-acess.so_src/export.c
Usermode/Libraries/ld-acess.so_src/include_exp/acess/sys.h
Usermode/Libraries/ld-acess.so_src/include_exp/acess/syscall_types.h [new file with mode: 0644]
Usermode/Libraries/ld-acess.so_src/include_exp/sys/types.h
Usermode/Libraries/ld-acess.so_src/loadlib.c
Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/axwin.h
Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/richtext.h [new file with mode: 0644]
Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/widget.h
Usermode/Libraries/libc.so_src/Makefile
Usermode/Libraries/libc.so_src/fileIO.c
Usermode/Libraries/libc.so_src/heap.c
Usermode/Libraries/libc.so_src/include_exp/ctype.h
Usermode/Libraries/libc.so_src/include_exp/signal.h
Usermode/Libraries/libc.so_src/include_exp/stdio.h
Usermode/Libraries/libc.so_src/include_exp/stdlib.h
Usermode/Libraries/libc.so_src/lib.h
Usermode/Libraries/libc.so_src/scanf.c [new file with mode: 0644]
Usermode/Libraries/libc.so_src/signals.c
Usermode/Libraries/libc.so_src/stdio_int.h
Usermode/Libraries/libc.so_src/stdlib.c
Usermode/Libraries/libc.so_src/string.c
Usermode/Libraries/libc.so_src/stub.c

index c9cd481..7448f4f 100644 (file)
@@ -1,4 +1,6 @@
 
-all:
-       @$(MAKE) -C acesskernel_src
-       @$(MAKE) -C ld-acess_src
+.PHONY: all clean
+
+all clean:
+       @$(MAKE) -C acesskernel_src $@
+       @$(MAKE) -C ld-acess_src $@
index be21e45..b4b7c11 100644 (file)
@@ -44,7 +44,8 @@ ifeq ($(PLATFORM),win)
 endif\r
 ifeq ($(PLATFORM),lin)\r
        BIN := ../AcessKernel\r
-       CFLAGS +=\r
+       CFLAGS += \r
+       LDFLAGS += -lpthread\r
 endif\r
 \r
 .PHONY: all clean\r
diff --git a/AcessNative/acesskernel_src/include/mouse_int.h b/AcessNative/acesskernel_src/include/mouse_int.h
new file mode 100644 (file)
index 0000000..d18d566
--- /dev/null
@@ -0,0 +1,35 @@
+
+#ifndef _ACESSNATIVE__MOUSE_INT_H_
+#define _ACESSNATIVE__MOUSE_INT_H_
+
+#include <api_drv_joystick.h>
+
+typedef struct sPointer        tPointer;
+
+#define MAX_BUTTONS    5
+#define MAX_AXIES      2
+#define MAX_FILESIZE   (sizeof(tJoystick_FileHeader) + MAX_AXIES*sizeof(tJoystick_Axis) + MAX_BUTTONS)
+
+/**
+ */
+struct sPointer
+{
+       tPointer        *Next;
+
+       // Node
+       tVFS_Node       Node;
+
+       // Data
+       Uint8   FileData[MAX_FILESIZE];
+       tJoystick_FileHeader    *FileHeader;
+       tJoystick_Axis  *Axies;
+       Uint8   *Buttons;
+
+       // Limits for axis positions
+       Uint16  AxisLimits[MAX_AXIES];
+};
+
+extern void    Mouse_HandleEvent(Uint32 ButtonState, int *AxisDeltas, int *AxisValues);
+
+#endif
+
index e5d8bab..eb0883d 100644 (file)
@@ -26,6 +26,7 @@ extern int    NativeKeyboard_Install(char **Arguments);
 extern int     NativeFS_Install(char **Arguments);
 extern void    Debug_SetKTerminal(char *Path);
 extern int     VT_Install(char **Arguments);
+extern int     Mouse_Install(char **Arguments);
 extern int     VFS_Mount(const char *Device, const char *MountPoint, const char *Filesystem, const char *Options);
 extern int     VFS_MkDir(const char *Path);
 extern int     SyscallServer(void);
@@ -38,6 +39,19 @@ extern int   giBuildNumber;
 const char     *gsAcessDir = "../Usermode/Output/x86_64";
 
 // === CODE ===
+#ifndef __WIN32__
+#define P_NOWAIT       0
+int spawnv(int flags, const char *execuable, char * const argv[])
+{
+       int pid = fork();
+       if( pid != 0 )  return pid;
+
+       execv(execuable, argv);
+       perror("spawnv - execve");
+       for(;;);
+}
+#endif
+
 int main(int argc, char *argv[])
 {
        char    **rootapp = NULL;
@@ -81,6 +95,7 @@ int main(int argc, char *argv[])
                Log_Error("Init", "Unable to load NativeKeyboard");
        }
        NativeFS_Install(NULL);
+       Mouse_Install(NULL);
        // - Start VTerm
        {
                char    *args[] = {
index e69de29..0ff9e8a 100644 (file)
@@ -0,0 +1,170 @@
+/*
+ * Acess2 Kernel - Mouse Mulitplexing Driver
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ * - Mouse mulitplexing
+ */
+#define DEBUG  0
+#define VERSION        VER2(0,1)
+#include <acess.h>
+#include <modules.h>
+#include <fs_devfs.h>
+#include "include/mouse_int.h"
+
+// === PROTOTYPES ===
+ int   Mouse_Install(char **Arguments);
+ int   Mouse_Cleanup(void);
+// - "User" side
+ int   Mouse_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
+tVFS_Node      *Mouse_Root_FindDir(tVFS_Node *Node, const char *Name);
+ int   Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data);
+size_t Mouse_Dev_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Data);
+// - Device Side
+void   Mouse_HandleEvent(Uint32 ButtonState, int *AxisDeltas, int *AxisValues);
+
+// === GLOBALS ===
+tVFS_NodeType  gMouse_RootNodeType = {
+       .ReadDir = Mouse_Root_ReadDir,
+       .FindDir = Mouse_Root_FindDir
+};
+tVFS_NodeType  gMouse_DevNodeType = {
+       .IOCtl = Mouse_Dev_IOCtl,
+       .Read = Mouse_Dev_Read
+};
+tDevFS_Driver  gMouse_DevInfo = {
+       NULL, "Mouse",
+       { .Flags = VFS_FFLAG_DIRECTORY, .Type = &gMouse_RootNodeType, .Size = 1 }
+};
+tPointer       gMouse_Pointer;
+
+// === CODE ===
+/**
+ * \brief Initialise the keyboard driver
+ */
+int Mouse_Install(char **Arguments)
+{
+       /// - Register with DevFS
+       DevFS_AddDevice( &gMouse_DevInfo );
+
+       gMouse_Pointer.Node.Type = &gMouse_DevNodeType;
+       gMouse_Pointer.Node.ImplPtr = &gMouse_Pointer;
+       gMouse_Pointer.FileHeader = (void*)gMouse_Pointer.FileData;
+       gMouse_Pointer.Axies = (void*)( gMouse_Pointer.FileHeader + 1 );
+       gMouse_Pointer.Buttons = (void*)( gMouse_Pointer.Axies + MAX_AXIES );
+       gMouse_Pointer.FileHeader->NAxies = MAX_AXIES;
+       gMouse_Pointer.FileHeader->NButtons = MAX_BUTTONS;
+
+       return 0;
+}
+
+/**
+ * \brief Pre-unload cleanup function
+ */
+int Mouse_Cleanup(void)
+{
+       return 0;
+}
+
+// --- VFS Interface ---
+int Mouse_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
+{
+       if( Pos != 0 )
+               return -EINVAL;
+       strcpy(Dest, "system");
+       return 0;
+}
+
+tVFS_Node *Mouse_Root_FindDir(tVFS_Node *Node, const char *Name)
+{
+       if( strcmp(Name, "system") != 0 )       return NULL;
+       return &gMouse_Pointer.Node;
+}
+
+static const char *csaIOCTL_NAMES[] = {DRV_IOCTLNAMES, DRV_JOY_IOCTLNAMES, NULL};
+/**
+ * \brief IOCtl handler for the mouse
+ */
+int Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data)
+{
+       tJoystick_NumValue      *numval = Data;
+       tPointer        *ptr = Node->ImplPtr;
+       switch(ID)
+       {
+       BASE_IOCTLS(DRV_TYPE_MOUSE, "Mouse", VERSION, csaIOCTL_NAMES);
+
+       case JOY_IOCTL_GETSETAXISLIMIT:
+               if( !numval || !CheckMem(numval, sizeof(*numval)) )
+                       return -1;
+               LOG("GetSetAxisLimit %i = %i", numval->Num, numval->Value);
+               if(numval->Num < 0 || numval->Num >= ptr->FileHeader->NAxies)
+                       return 0;
+               if(numval->Value != -1)
+                       ptr->AxisLimits[numval->Num] = numval->Value;
+               return ptr->AxisLimits[numval->Num];
+
+       case JOY_IOCTL_GETSETAXISPOSITION:
+               if( !numval || !CheckMem(numval, sizeof(*numval)) )
+                       return -1;
+               if(numval->Num < 0 || numval->Num >= ptr->FileHeader->NAxies)
+                       return 0;
+               if(numval->Value != -1)
+                       ptr->Axies[numval->Num].CursorPos = numval->Value;
+               return ptr->Axies[numval->Num].CursorPos;
+       }
+       return -1;
+}
+
+/**
+ * \brief Read from a device
+ */
+size_t Mouse_Dev_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Data)
+{
+       tPointer *ptr = Node->ImplPtr;
+        int    n_buttons = ptr->FileHeader->NButtons;
+        int    n_axies = ptr->FileHeader->NAxies;
+
+       ENTER("pNode iLength pData", Node, Length, Data);
+
+       // TODO: Locking (Acquire)
+
+       Length = MIN(
+               Length, 
+               sizeof(tJoystick_FileHeader) + n_axies*sizeof(tJoystick_Axis) + n_buttons
+               );
+
+       // Mark as checked
+       VFS_MarkAvaliable( Node, 0 );
+
+       memcpy( Data, ptr->FileData, Length );
+
+       // TODO: Locking (Release)
+
+       LEAVE('i', Length);
+       return Length;
+}
+
+// --- Device Interface ---
+/*
+ * Handle a mouse event (movement or button press/release)
+ * - See Input/Mouse/include/mouse.h
+ */
+void Mouse_HandleEvent(Uint32 ButtonState, int *AxisDeltas, int *AxisValues)
+{
+       tPointer *ptr = &gMouse_Pointer;
+       
+       ENTER("pHandle xButtonState pAxisDeltas", Handle, ButtonState, AxisDeltas);
+
+       // Update cursor position
+       for( int i = 0; i < 2; i ++ )
+       {
+               ptr->Axies[i].CursorPos = AxisValues[i];
+               ptr->Axies[i].CurValue = AxisDeltas ? AxisDeltas[i] : 0;
+       }
+       for( int i = 0; i < 5; i ++ )
+               ptr->Buttons[i] = ButtonState & (1 << i) ? 255 : 0;
+
+       VFS_MarkAvaliable( &ptr->Node, 1 );
+       LEAVE('-');
+}
+
index 7919979..45806e2 100644 (file)
@@ -19,7 +19,7 @@ typedef int   socklen_t;
 # include <unistd.h>
 # include <sys/socket.h>
 # include <netinet/in.h>
-# include <arpa/inet.h>        // inet_ntop
+# include <netdb.h>    // getaddrinfo
 #endif
 #define DONT_INCLUDE_SYSCALL_NAMES
 #include "../syscalls.h"
@@ -136,7 +136,6 @@ int Server_WorkerThread(void *ClientPtr)
        Log_Debug("Server", "Worker %p", ClientPtr);    
 
        #if USE_TCP
-
        while( *((volatile typeof(Client->Socket)*)&Client->Socket) == 0 )
                ;
        Threads_SetThread( Client->ClientID );
@@ -153,7 +152,7 @@ int Server_WorkerThread(void *ClientPtr)
                        perror("select");
                        continue ;
                }
-               Log_Debug("Server", "%p: rv=%i", Client, rv);           
+//             Log_Debug("Server", "%p: rv=%i", Client, rv);           
 
                if( FD_ISSET(Client->Socket, &fds) )
                {
@@ -161,8 +160,11 @@ int Server_WorkerThread(void *ClientPtr)
                        char    lbuf[sizeof(tRequestHeader) + ciMaxParamCount*sizeof(tRequestValue)];
                        tRequestHeader  *hdr = (void*)lbuf;
                        size_t  len = recv(Client->Socket, (void*)hdr, sizeof(*hdr), 0);
-                       Log_Debug("Server", "%i bytes of header", len);
-                       if( len == 0 )  break;
+//                     Log_Debug("Server", "%i bytes of header", len);
+                       if( len == 0 ) {
+                               Log_Notice("Server", "Zero RX on %i (worker %p)", Client->Socket, Client);
+                               break;
+                       }
                        if( len == -1 ) {
                                perror("recv header");
 //                             Log_Warning("Server", "recv() error - %s", strerror(errno));
@@ -185,7 +187,7 @@ int Server_WorkerThread(void *ClientPtr)
                        if( hdr->NParams > 0 )
                        {
                                len = recv(Client->Socket, (void*)hdr->Params, hdr->NParams*sizeof(tRequestValue), 0);
-                               Log_Debug("Server", "%i bytes of params", len);
+//                             Log_Debug("Server", "%i bytes of params", len);
                                if( len != hdr->NParams*sizeof(tRequestValue) ) {
                                        // Oops.
                                        perror("recv params");
@@ -195,7 +197,7 @@ int Server_WorkerThread(void *ClientPtr)
                        }
                        else
                        {
-                               Log_Debug("Server", "No params?");
+//                             Log_Debug("Server", "No params?");
                        }
 
                        // Get buffer size
@@ -221,7 +223,7 @@ int Server_WorkerThread(void *ClientPtr)
                                while( rem )
                                {
                                        len = recv(Client->Socket, ptr, rem, 0);
-                                       Log_Debug("Server", "%i bytes of data", len);
+//                                     Log_Debug("Server", "%i bytes of data", len);
                                        if( len == -1 ) {
                                                // Oops?
                                                perror("recv data");
@@ -235,8 +237,8 @@ int Server_WorkerThread(void *ClientPtr)
                                        break;
                                }
                        }
-                       else
-                               Log_Debug("Server", "no data");
+//                     else
+//                             Log_Debug("Server", "no data");
 
                         int    retlen;
                        tRequestHeader  *retHeader;
index 446da3d..d14a1d9 100644 (file)
@@ -4,14 +4,18 @@
  *
  * Syscall Distribution
  */
-#define DEBUG  1
+#define DEBUG  0
 #include <acess.h>
 #include <threads.h>
 #include <events.h>
+#if DEBUG == 0
+# define DONT_INCLUDE_SYSCALL_NAMES
+#endif
 #include "../syscalls.h"
 
 // === IMPORTS ===
 extern int     Threads_Fork(void);     // AcessNative only function
+extern int     Threads_Spawn(int nFD, int FDs[], const void *info);
 
 // === TYPES ===
 typedef int    (*tSyscallHandler)(Uint *Errno, const char *Format, void *Args, int *Sizes);
@@ -190,6 +194,13 @@ SYSCALL1(Syscall_AN_Fork, "d", int *,
        return *a0;
 );
 
+SYSCALL3(Syscall_AN_Spawn, "ddd", int *, int *, void *,
+       if(Sizes[0] < sizeof(int))
+               return -1;
+       *a0 = Threads_Spawn(Sizes[1] / sizeof(int), a1, a2);
+       return *a0;
+);
+
 SYSCALL2(Syscall_SendMessage, "id", int, void *,
        return Proc_SendMessage(a0, Sizes[1], a1);
 );
@@ -244,6 +255,7 @@ const tSyscallHandler       caSyscalls[] = {
 
        Syscall_Sleep,
        Syscall_AN_Fork,
+       Syscall_AN_Spawn,
 
        Syscall_SendMessage,
        Syscall_GetMessage,
@@ -384,11 +396,12 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
        }
        
        // Allocate the return
-       ret = malloc(sizeof(tRequestHeader) + retValueCount * sizeof(tRequestValue)
-               + retDataLen);
+       size_t  msglen = sizeof(tRequestHeader) + retValueCount * sizeof(tRequestValue) + retDataLen;
+       ret = malloc(msglen);
        ret->ClientID = Request->ClientID;
        ret->CallID = Request->CallID;
        ret->NParams = retValueCount;
+       ret->MessageLength = msglen;
        inData = (char*)&ret->Params[ ret->NParams ];
        
        // Static Uint64 return value
@@ -398,7 +411,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength)
        *(Uint64*)inData = retVal;
        inData += sizeof(Uint64);
        
-       Log_Debug("Syscalls", "Return 0x%llx", retVal);
+       //Log_Debug("Syscalls", "Return 0x%llx", retVal);
        
        retValueCount = 1;
        for( i = 0; i < Request->NParams; i ++ )
index 9400d72..661d584 100644 (file)
@@ -10,6 +10,8 @@
 #include <acess.h>
 #include <mutex.h>
 #include "../../KernelLand/Kernel/include/semaphore.h"
+typedef signed long long int   time_t;
+#include "../../Usermode/Libraries/ld-acess.so_src/include_exp/acess/syscall_types.h"
 #include <rwlock.h>
 #include <events.h>
 #include <threads_int.h>
@@ -19,7 +21,8 @@
 #define THREAD_EVENT_WAKEUP    0x80000000
 
 // === IMPORTS ===
-void   VFS_CloneHandleList(int PID);
+extern void    VFS_CloneHandleList(int PID);
+extern void    VFS_CloneHandlesFromList(int PID, int nFD, int FDs[]);
 
 // === STRUCTURES ===
 // === PROTOTYPES ===
@@ -264,13 +267,34 @@ int Threads_Fork(void)
 {
        tThread *thread = Threads_CloneTCB(gpCurrentThread);
        thread->PID = thread->TID;
+
        // Duplicate the VFS handles (and nodes) from vfs_handle.c
-       
        VFS_CloneHandleList(thread->PID);
        
        return thread->PID;
 }
 
+int Threads_Spawn(int nFD, int FDs[], struct s_sys_spawninfo *info)
+{
+       tThread *thread = Threads_CloneTCB(gpCurrentThread);
+       thread->PID = thread->TID;
+       if( info )
+       {
+               // TODO: PGID?
+               //if( info->flags & SPAWNFLAG_NEWPGID )
+               //      thread->PGID = thread->PID;
+               if( info->gid && thread->UID == 0 )
+                       thread->GID = info->gid;
+               if( info->uid && thread->UID == 0 )     // last because ->UID is used above
+                       thread->UID = info->uid;
+       }
+       
+       VFS_CloneHandlesFromList(thread->PID, nFD, FDs);
+
+       Log_Debug("Threads", "_spawn: %i", thread->PID);
+       return thread->PID;
+}
+
 // --------------------------------------------------------------------
 // Mutexes 
 // --------------------------------------------------------------------
@@ -312,7 +336,7 @@ Uint32 Threads_WaitEvents(Uint32 Mask)
 {
        Uint32  rv;
 
-       Log_Debug("Threads", "Mask = %x, ->Events = %x", Mask, gpCurrentThread->Events);        
+       //Log_Debug("Threads", "Mask = %x, ->Events = %x", Mask, gpCurrentThread->Events);      
 
        gpCurrentThread->WaitMask = Mask;
        if( !(gpCurrentThread->Events & Mask) )
@@ -321,13 +345,13 @@ Uint32 Threads_WaitEvents(Uint32 Mask)
                        Log_Warning("Threads", "Wait on eventsem of %p, %p failed",
                                gpCurrentThread, gpCurrentThread->EventSem);
                }
-               Log_Debug("Threads", "Woken from nap (%i here)", SDL_SemValue(gpCurrentThread->EventSem));
+               //Log_Debug("Threads", "Woken from nap (%i here)", SDL_SemValue(gpCurrentThread->EventSem));
        }
        rv = gpCurrentThread->Events & Mask;
        gpCurrentThread->Events &= ~Mask;
        gpCurrentThread->WaitMask = -1;
 
-       Log_Debug("Threads", "- rv = %x", rv);
+       //Log_Debug("Threads", "- rv = %x", rv);
 
        return rv;
 }
@@ -335,8 +359,8 @@ Uint32 Threads_WaitEvents(Uint32 Mask)
 void Threads_PostEvent(tThread *Thread, Uint32 Events)
 {
        Thread->Events |= Events;
-       Log_Debug("Threads", "Trigger event %x (->Events = %p)", Events, Thread->Events);
-       
+//     Log_Debug("Threads", "Trigger event %x (->Events = %p) on %p", Events, Thread->Events, Thread);
+
        if( Events == 0 || Thread->WaitMask & Events ) {
                Threads_Glue_SemSignal( Thread->EventSem, 1 );
 //             Log_Debug("Threads", "Waking %p(%i %s)", Thread, Thread->TID, Thread->ThreadName);
index 80241da..3c43cc5 100644 (file)
@@ -20,5 +20,6 @@ extern void   UI_Redraw(void);
 
 typedef void (*tUI_KeybardCallback)(Uint32 Key);
 extern tUI_KeybardCallback     gUI_KeyboardCallback;
+extern void    Mouse_HandleEvent(Uint32 ButtonState, int *AxisDeltas, int *AxisValues);
 
 #endif
index ae1d811..7e97cbe 100644 (file)
@@ -57,7 +57,7 @@ int UI_Initialise(int MaxWidth, int MaxHeight)
        return 0;
 }
 
-Uint32 UI_GetAcessKeyFromSDL(SDLKey Sym, Uint16 Unicode)
+Uint32 UI_GetAcessKeyFromSDL(SDLKey Sym)
 {
        Uint8   *keystate = SDL_GetKeyState(NULL);
         int    shiftState = 0;
@@ -70,50 +70,61 @@ Uint32 UI_GetAcessKeyFromSDL(SDLKey Sym, Uint16 Unicode)
        if( gUI_Keymap[shiftState][Sym] )
                return gUI_Keymap[shiftState][Sym];
 
-       // Enter key on acess returns \n, but SDL returns \r
-       if( Sym == SDLK_RETURN )
-               Unicode = '\n';
-       
-       // How nice of you, a unicode value
-       if( Unicode )
-       {
-               ret = Unicode;
-       }
-       // Ok, we need to do work :(
-       else
+       switch(Sym)
        {
-               switch(Sym)
-               {
-               case SDLK_UP:   ret = KEY_UP;   break;
-               case SDLK_DOWN: ret = KEY_DOWN; break;
-               case SDLK_LEFT: ret = KEY_LEFT; break;
-               case SDLK_RIGHT:ret = KEY_RIGHT;break;
-               case SDLK_CAPSLOCK:     ret = KEY_CAPSLOCK;     break;
-               case SDLK_F1:   ret = KEY_F1;   break;
-               case SDLK_F2:   ret = KEY_F2;   break;
-               case SDLK_F3:   ret = KEY_F3;   break;
-               case SDLK_F4:   ret = KEY_F4;   break;
-               case SDLK_F5:   ret = KEY_F5;   break;
-               case SDLK_F6:   ret = KEY_F6;   break;
-               case SDLK_F7:   ret = KEY_F7;   break;
-               case SDLK_F8:   ret = KEY_F8;   break;
-               case SDLK_F9:   ret = KEY_F9;   break;
-               case SDLK_F10:  ret = KEY_F10;  break;
-               case SDLK_F11:  ret = KEY_F11;  break;
-               case SDLK_F12:  ret = KEY_F12;  break;
-               case SDLK_RETURN:       ret = '\n';     break;
-               case SDLK_LALT: ret = KEY_LALT; break;
-               case SDLK_RALT: ret = KEY_RALT; break;
-               default:
-                       printf("Unhandled key code %i\n", Sym);
-                       break;
-               }
+       case SDLK_a ... SDLK_z:
+               ret = Sym - SDLK_a + KEYSYM_a;
+               break;
+       case SDLK_0 ... SDLK_9:
+               ret = Sym - SDLK_0 + KEYSYM_0;
+               break;
+       case SDLK_CAPSLOCK:     ret = KEYSYM_CAPS;      break;
+       case SDLK_TAB:  ret = KEYSYM_TAB;       break;
+       case SDLK_UP:   ret = KEYSYM_UPARROW;   break;
+       case SDLK_DOWN: ret = KEYSYM_DOWNARROW; break;
+       case SDLK_LEFT: ret = KEYSYM_LEFTARROW; break;
+       case SDLK_RIGHT:ret = KEYSYM_RIGHTARROW;break;
+       case SDLK_F1:   ret = KEYSYM_F1;        break;
+       case SDLK_F2:   ret = KEYSYM_F2;        break;
+       case SDLK_F3:   ret = KEYSYM_F3;        break;
+       case SDLK_F4:   ret = KEYSYM_F4;        break;
+       case SDLK_F5:   ret = KEYSYM_F5;        break;
+       case SDLK_F6:   ret = KEYSYM_F6;        break;
+       case SDLK_F7:   ret = KEYSYM_F7;        break;
+       case SDLK_F8:   ret = KEYSYM_F8;        break;
+       case SDLK_F9:   ret = KEYSYM_F9;        break;
+       case SDLK_F10:  ret = KEYSYM_F10;       break;
+       case SDLK_F11:  ret = KEYSYM_F11;       break;
+       case SDLK_F12:  ret = KEYSYM_F12;       break;
+       case SDLK_RETURN:       ret = KEYSYM_RETURN;    break;
+       case SDLK_LALT:         ret = KEYSYM_LEFTALT;   break;
+       case SDLK_LCTRL:        ret = KEYSYM_LEFTCTRL;  break;
+       case SDLK_LSHIFT:       ret = KEYSYM_LEFTSHIFT; break;
+       case SDLK_LSUPER:       ret = KEYSYM_LEFTGUI;   break;
+       case SDLK_RALT:         ret = KEYSYM_RIGHTALT;  break;
+       case SDLK_RCTRL:        ret = KEYSYM_RIGHTCTRL; break;
+       case SDLK_RSHIFT:       ret = KEYSYM_RIGHTSHIFT;        break;
+       case SDLK_RSUPER:       ret = KEYSYM_RIGHTGUI;  break;
+       default:
+               printf("Unhandled key code %i\n", Sym);
+               break;
        }
        
        gUI_Keymap[shiftState][Sym] = ret;
        return ret;
 }
 
+Uint32 UI_GetButtonBits(Uint8 sdlstate)
+{
+       Uint32  rv = 0;
+       rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_LEFT)    ? (1 << 0) : 0;
+       rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_RIGHT)   ? (1 << 1) : 0;
+       rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_MIDDLE)  ? (1 << 2) : 0;
+       rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_X1)      ? (1 << 3) : 0;
+       rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_X2)      ? (1 << 4) : 0;
+       return rv;
+}
+
 void UI_MainLoop(void)
 {
        SDL_Event       event;
@@ -130,29 +141,41 @@ void UI_MainLoop(void)
                                return ;
                                
                        case SDL_KEYDOWN:
-                               acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym,
-                                       event.key.keysym.unicode);
-                               
+                               acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym);
+                               // Enter key on acess returns \n, but SDL returns \r
+                               if(event.key.keysym.sym == SDLK_RETURN)
+                                       event.key.keysym.unicode = '\n';                                
+
                                if( gUI_KeyboardCallback ) {
-                                       gUI_KeyboardCallback(KEY_ACTION_RAWSYM|event.key.keysym.sym);
-                                       gUI_KeyboardCallback(KEY_ACTION_PRESS|acess_sym);
+                                       gUI_KeyboardCallback(KEY_ACTION_RAWSYM|acess_sym);
+                                       gUI_KeyboardCallback(KEY_ACTION_PRESS|event.key.keysym.unicode);
                                }
                                break;
                        
                        case SDL_KEYUP:
-                               acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym,
-                                       event.key.keysym.unicode);
+                               acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym);
                                
                                if( gUI_KeyboardCallback ) {
-                                       gUI_KeyboardCallback(KEY_ACTION_RAWSYM|event.key.keysym.sym);
-                                       gUI_KeyboardCallback(KEY_ACTION_RELEASE|acess_sym);
+                                       gUI_KeyboardCallback(KEY_ACTION_RAWSYM|acess_sym);
+                                       gUI_KeyboardCallback(KEY_ACTION_RELEASE|0);
                                }
                                break;
 
                        case SDL_USEREVENT:
                                SDL_UpdateRect(gScreen, 0, 0, giUI_Width, giUI_Height);
                                SDL_Flip(gScreen);
-                               break;          
+                               break;
+                       
+                       case SDL_MOUSEMOTION: {
+                               int abs[] = {event.motion.x, event.motion.y};
+                               int delta[] = {event.motion.xrel, event.motion.yrel};
+                               Mouse_HandleEvent(UI_GetButtonBits(SDL_GetMouseState(NULL, NULL)), delta, abs);
+                               break; }
+                       case SDL_MOUSEBUTTONUP:
+                       case SDL_MOUSEBUTTONDOWN: {
+                               int abs[] = {event.button.x, event.button.y};
+                               Mouse_HandleEvent(UI_GetButtonBits(SDL_GetMouseState(NULL, NULL)), NULL, abs);
+                               break; }
        
                        default:
                                break;
index cfe0489..724e76f 100644 (file)
@@ -38,8 +38,8 @@ tUserHandles *VFS_int_GetUserHandles(int PID, int bCreate)
        tUserHandles    *ent, *prev = NULL;
        for( ent = gpUserHandles; ent; prev = ent, ent = ent->Next ) {
                if( ent->PID == PID ) {
-                       if( bCreate )
-                               Log_Warning("VFS", "Process %i already has a handle list", PID);
+                       //if( bCreate )
+                       //      Log_Warning("VFS", "Process %i already has a handle list", PID);
                        return ent;
                }
                if( ent->PID > PID )    break;
@@ -88,6 +88,40 @@ void VFS_CloneHandleList(int PID)
        }
 }
 
+void VFS_CloneHandlesFromList(int PID, int nFD, int FDs[])
+{
+       tUserHandles    *ent;
+       tUserHandles    *cur;
+        int    i, maxhandles;
+       
+       cur = VFS_int_GetUserHandles(Threads_GetPID(), 0);
+       if(!cur)        return ;        // Don't need to do anything if the current list is empty
+       
+       ent = VFS_int_GetUserHandles(PID, 1);
+       
+       maxhandles = *Threads_GetMaxFD();
+       if( nFD > maxhandles )
+               nFD = maxhandles;
+       for( i = 0; i < nFD; i ++ )
+       {
+               if( FDs[i] >= maxhandles ) {
+                       ent->Handles[i].Node = NULL;
+                       continue ;
+               }
+               memcpy(&ent->Handles[i], &cur->Handles[ FDs[i] ], sizeof(tVFS_Handle));
+       }
+       for( ; i < maxhandles; i ++ )
+               cur->Handles[i].Node = NULL;
+       
+       for( i = 0; i < maxhandles; i ++ )
+       {
+               if(!cur->Handles[i].Node)       continue;
+               
+               if(ent->Handles[i].Node->Type->Reference)
+                       ent->Handles[i].Node->Type->Reference(ent->Handles[i].Node);
+       }
+}
+
 /**
  * \fn tVFS_Handle *VFS_GetHandle(int FD)
  * \brief Gets a pointer to the handle information structure
index 5408b56..da18f48 100644 (file)
@@ -166,10 +166,12 @@ Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Bu
                
                LOG("buffer = %p", Buffer);
                
+               Offset /= 4;
                startX = Offset % giUI_Width;
                startY = Offset / giUI_Width;
-               
-               if( Length + startX < giUI_Width )
+               Length /= 4;
+
+               if( startX + Length < giUI_Width )
                {
                        // Single line
                        UI_BlitBitmap(
@@ -177,6 +179,15 @@ Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Bu
                                Length, 1,
                                Buffer);
                }
+               else if( startX == 0 )
+               {
+                       int     lines = Length / giUI_Width;
+                       int     rem = Length % giUI_Width;
+                       UI_BlitBitmap(0, startY, giUI_Width, lines, Buffer);
+                       if( rem ) {
+                               UI_BlitBitmap(0, startY + lines, rem, 1, (Uint32*)Buffer + lines*giUI_Width);
+                       }
+               }
                else
                {
                        // First scanline (partial or full)
index 0d1dee8..63db861 100644 (file)
@@ -14,12 +14,13 @@ extern void *Binary_Load(const char *Path, uintptr_t *EntryPoint);
 extern void    Binary_SetReadyToUse(void *Base);
 
 // HACKS - So this can share the usermode elf.c
-static inline void *GetSymbol(const char*sym, size_t*sz)
+static inline int GetSymbol(const char *sym, void **val, size_t *sz)
 {
        uintptr_t rv;
        if( !Binary_GetSymbol(sym, &rv, sz) )
-               return NULL;
-       return (void*)rv;
+               return 0;
+       *val = (void*)rv;
+       return 1;
 }
 static inline void *LoadLibrary(const char *Name, const char *SearchPath, char **envp)
 {
@@ -30,6 +31,11 @@ static inline void AddLoaded(const char *Path, void *Base)
        Binary_SetReadyToUse(Base);
 }
 
+static inline int SysSetMemFlags(uintptr_t Addr, unsigned int flags, unsigned int mask)
+{
+       return 0;
+}
+
 extern int     AllocateMemory(uintptr_t VirtAddr, size_t ByteCount);
 extern uintptr_t       FindFreeRange(size_t ByteCount, int MaxBits);
 
deleted file mode 120000 (symlink)
index 3c15fb9b4a17b41ff4533b068704d20f5d7f1f2b..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "common.h"
-#define _COMMON_H      // stops real ld-acess.so common.h being included
-#include "../../Usermode/Libraries/ld-acess.so_src/elf.c"
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..3e05f24a5d7b914d7d578cc85699a0abe2c39b4a
--- /dev/null
@@ -0,0 +1,4 @@
+#include "common.h"
+#define _COMMON_H
+// stops real ld-acess.so common.h being included
+#include "../../Usermode/Libraries/ld-acess.so_src/elf.c"
deleted file mode 120000 (symlink)
index dfecd7142298a3eb464973518ba26c4658f0b807..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../Usermode/Libraries/ld-acess.so_src/elf32.h"
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..dfecd7142298a3eb464973518ba26c4658f0b807
--- /dev/null
@@ -0,0 +1 @@
+#include "../../Usermode/Libraries/ld-acess.so_src/elf32.h"
deleted file mode 120000 (symlink)
index 6edb566a42e95eaddd3bc324be572db6481f58e9..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../Usermode/Libraries/ld-acess.so_src/elf64.h"
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..6edb566a42e95eaddd3bc324be572db6481f58e9
--- /dev/null
@@ -0,0 +1 @@
+#include "../../Usermode/Libraries/ld-acess.so_src/elf64.h"
index 47f741f..07662a5 100644 (file)
@@ -11,7 +11,7 @@
 #include <stdarg.h>
 #include <stddef.h>
 
-#define DEBUG(v...)    Debug(v)
+#define DEBUG(v...)    do{}while(0)//Debug(v)
 #define PAGE_SIZE      4096
 
 typedef struct sFILE   FILE;
@@ -37,6 +37,7 @@ extern int    AllocateMemory(uintptr_t VirtAddr, size_t ByteCount);
 
 // === GLOBALS ===
 int    acess__errno;
+char   *gsExecutablePath = "./ld-acess";
 
 // === CODE ===
 // --- VFS Calls
@@ -253,6 +254,40 @@ int acess_execve(char *path, char **argv, const char **envp)
        return native_execve("./ld-acess", new_argv, envp);
 }
 
+int acess__SysSpawn(const char *binary, const char **argv, const char **envp, int nfd, int fds[], struct s_sys_spawninfo *info)
+{
+        int    argc = 0;
+       while( argv[argc++] );
+
+       Debug("_SysSpawn('%s', %p (%i), %p, %i, %p, %p)",
+               binary, argv, argc, envp, nfd, fds, info);
+
+        int    kernel_tid;
+        int    newID;
+       newID = _Syscall(SYS_AN_SPAWN, "<d >d >d", sizeof(int), &kernel_tid,
+               nfd*sizeof(int), fds,
+               info ? sizeof(*info) : 0, info);
+
+       const char      *new_argv[5+argc+1];
+        int    new_argc = 0, i;
+       char    client_id_str[11];
+       sprintf(client_id_str, "%i", newID);
+       new_argv[new_argc++] = gsExecutablePath;       // TODO: Get path to ld-acess executable
+       new_argv[new_argc++] = "--key";
+       new_argv[new_argc++] = client_id_str;
+       new_argv[new_argc++] = "--binary";
+       new_argv[new_argc++] = binary;
+       for( i = 0; argv[i]; i ++)
+               new_argv[new_argc++] = argv[i];
+       new_argv[new_argc++] = NULL;
+       
+       // TODO: Debug output?
+       
+       native_spawn(gsExecutablePath, new_argv, envp);
+
+       return kernel_tid;
+}
+
 void acess_sleep(void)
 {
        DEBUG("%s()", __func__);
@@ -339,12 +374,15 @@ const tSym        caBuiltinSymbols[] = {
        
        DEFSYM(clone),
        DEFSYM(execve),
+       DEFSYM(_SysSpawn),
        DEFSYM(sleep),
        
        DEFSYM(waittid),
+       DEFSYM(gettid),
        DEFSYM(setuid),
        DEFSYM(setgid),
-       DEFSYM(gettid),
+       DEFSYM(getuid),
+       DEFSYM(getgid),
 
        DEFSYM(SysSendMessage),
        DEFSYM(SysGetMessage),
index 880e74c..dc319ac 100644 (file)
@@ -21,6 +21,7 @@ extern int    native_seek(int FD, int64_t Offset, int Dir);
 extern uint64_t        native_tell(int FD);
 
 extern int     native_execve(const char *filename, const char *const argv[], const char *const envp[]);
+extern int     native_spawn(const char *filename, const char *const argv[], const char *const envp[]);
 
 // Syscalls used by the linker
 extern int     acess_open(const char *Path, int Flags);
index 7a9b3b3..5bcf8cd 100644 (file)
@@ -190,6 +190,7 @@ int SendRequest(tRequestHeader *Request, int RequestSize, int ResponseSize)
                printf("\n");
        }
        #endif
+       #if DEBUG
        {
                 int    i;
                char    *data = (char*)&Request->Params[Request->NParams];
@@ -219,6 +220,7 @@ int SendRequest(tRequestHeader *Request, int RequestSize, int ResponseSize)
                }
                DEBUG_S("\n");
        }
+       #endif
        
        // Send it off
        SendData(Request, RequestSize);
@@ -226,7 +228,23 @@ int SendRequest(tRequestHeader *Request, int RequestSize, int ResponseSize)
        if( Request->CallID == SYS_EXIT )       return 0;
 
        // Wait for a response (no timeout)
-       return ReadData(Request, ResponseSize, 0);
+       ReadData(Request, sizeof(*Request), 0);
+       // TODO: Sanity
+       size_t  recvbytes = sizeof(*Request), expbytes = Request->MessageLength;
+       char    *ptr = (void*)Request->Params;
+       while( recvbytes < expbytes )
+       {
+               size_t  len = ReadData(ptr, expbytes - recvbytes, 1000);
+               if( len == -1 ) {
+                       return -1;
+               }
+               recvbytes += len;
+               ptr += len;
+       }
+       if( recvbytes > expbytes ) {
+               // TODO: Warning
+       }
+       return recvbytes;
 }
 
 void SendData(void *Data, int Length)
@@ -275,7 +293,7 @@ int ReadData(void *Dest, int MaxLength, int Timeout)
        
        if( !ret ) {
                printf("[ERROR %i] Timeout reading from socket\n", giSyscall_ClientID);
-               return 0;       // Timeout
+               return -2;      // Timeout
        }
        
        #if USE_TCP
@@ -289,6 +307,11 @@ int ReadData(void *Dest, int MaxLength, int Timeout)
                perror("ReadData");
                exit(-1);
        }
+       if( ret == 0 ) {
+               fprintf(stderr, "[ERROR %i] Connection closed.\n", giSyscall_ClientID);
+               close(gSocket);
+               exit(0);
+       }
        
        DEBUG_S("%i bytes read from socket\n", ret);
        
index 6680186..26f6c44 100644 (file)
@@ -9,9 +9,14 @@
 #include <string.h>
 #include <stddef.h>
 #include <unistd.h>
+#include <spawn.h>     // posix_spawn
 #include "request.h"
 
+#if SYSCALL_TRACE
 #define DEBUG(str, x...)       Debug(str, x)
+#else
+#define DEBUG(...)     do{}while(0)
+#endif
 
 #define        MAX_FPS 16
 
@@ -206,6 +211,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
        req->ClientID = 0;      //< Filled later
        req->CallID = SyscallID;
        req->NParams = paramCount;
+       req->MessageLength = dataLength;
        dataPtr = &req->Params[paramCount];
        
        // Fill `output` and `input`
@@ -253,6 +259,11 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
        }
        
        // Write changes to buffers
+       if( req->NParams - 1 != retCount ) {
+               fprintf(stderr, "syscalls.c: Return count inbalance (%i - 1 != exp %i) [Call %i]\n",
+                       req->NParams, retCount, SyscallID);
+               exit(127);
+       }
        retCount = 0;
        for( i = 1; i < req->NParams; i ++ )
        {
@@ -321,7 +332,16 @@ uint64_t native_tell(int FD)
 int native_execve(const char *filename, const char *const argv[], const char *const envp[])
 {
        int ret;
-       ret = execve(filename, argv, envp);
+       ret = execve(filename, (void*)argv, (void*)envp);
        perror("native_execve");
        return ret;
 }
+
+int native_spawn(const char *filename, const char *const argv[], const char *const envp[])
+{
+       int rv;
+       
+       rv = posix_spawn(NULL, filename, NULL, NULL, (void*)argv, (void*)envp);
+       
+       return rv;
+}
index e6dbd28..21a9cb5 100644 (file)
@@ -29,6 +29,7 @@ typedef struct sRequestValue {
 typedef struct sRequestHeader {
        uint16_t        ClientID;
        uint16_t        CallID; //!< \see eSyscalls
+       uint32_t        MessageLength;
        uint16_t        NParams;
        
        tRequestValue   Params[];
@@ -66,6 +67,7 @@ enum eSyscalls {
        // IPC
        SYS_SLEEP,
        SYS_AN_FORK,
+       SYS_AN_SPAWN,
        SYS_SENDMSG,
        SYS_GETMSG,
        SYS_SELECT,
index 057e96e..d3241b1 100644 (file)
@@ -6,6 +6,10 @@
 SAVED_CC_ := $(CC)
 SAVED_LD_ := $(LD)
 
+ifeq ($(HOST_ARCH),)
+$(error Please set HOST_ARCH to the architecture to compile, e.g. x86)
+endif
+
 include $(ACESSDIR)/BuildConf/$(HOST_ARCH)/Makefile.cfg
 
 OBJDUMP := objdump -S
index 76c3d3c..65777d1 100644 (file)
@@ -2,10 +2,11 @@
 # Acess2 Build Configuration
 #
 
-#CC = i586-elf-gcc
-#LD = i586-elf-ld
-CC = gcc
-LD = ld
+CC = i586-elf-gcc
+#CC = clang -m32
+LD = i586-elf-ld
+#CC = gcc
+#LD = ld
 AS = nasm
 #OBJDUMP = i586-elf-objdump
 OBJDUMP = objdump
index 6aa3afc..cc252bc 100644 (file)
@@ -1,13 +1,13 @@
 
-PREFIX := x86_64-pc-elf
-#PREFIX := x86_64-none-elf
+#PREFIX := x86_64-pc-elf
+PREFIX := x86_64-none-elf
 
 CC := $(PREFIX)-gcc
 LD := $(PREFIX)-ld
 DISASM = $(PREFIX)-objdump -d -M x86-64 -S
 
-KERNEL_CFLAGS := -mcmodel=kernel -nostdlib -mno-red-zone -Wall
-DYNMOD_CFLAGS := -mcmodel=small -fPIC -mno-red-zone
+KERNEL_CFLAGS := -mcmodel=kernel -nostdlib -mno-red-zone -Wall -mno-sse
+DYNMOD_CFLAGS := -mcmodel=small -fPIC -mno-red-zone -mno-sse
 
 ARCHDIR = x86_64
 
index 65c457c..f33f339 100644 (file)
@@ -103,7 +103,7 @@ void *memset(void *_dest, int _value, size_t _length)
        val32 |= val32 << 16;
        
        // Force alignment
-       while( (tVAddr)dst8 & 3 ) *dst8 ++ = _value;
+       while( (tVAddr)dst8 & 3 ) *dst8 ++ = _value, _length --;
        dst = (void *)dst8;
 
        // DWORD copies
index 85f9b27..146caea 100644 (file)
@@ -10,6 +10,7 @@
 #include <hal_proc.h>
 
 #define TRACE_MAPS     0
+#define TRACE_COW      1
 
 #define AP_KRW_ONLY    1       // Kernel page
 #define AP_KRO_ONLY    5       // Kernel RO page
 #define AP_RO_USER     2       // User RO Page
 #define PADDR_MASK_LVL1        0xFFFFFC00
 
+const char * const caAPValueNames[] = {
+       "AP_NOACCESS", "AP_KRW_ONLY",
+       "AP_RO_USER", "AP_RW_BOTH",
+       "AP_???_4", "AP_KRO_ONLY",
+       "AP_???_6", "AP_RO_BOTH"
+};
+
 // === IMPORTS ===
 extern Uint32  kernel_table0[];
 
@@ -53,7 +61,7 @@ tPAddr        MM_Clone(void);
 tVAddr MM_NewKStack(int bGlobal);
 void   MM_int_DumpTableEnt(tVAddr Start, size_t Len, tMM_PageInfo *Info);
 //void MM_DumpTables(tVAddr Start, tVAddr End);
-void   MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch);
+void   MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch, Uint32 UserLR);
 
 // === GLOBALS ===
 tPAddr giMM_ZeroPage;
@@ -902,7 +910,7 @@ tVAddr MM_NewUserStack(void)
        tVAddr  addr, ofs;
 
        addr = USER_STACK_TOP - USER_STACK_SIZE;
-       if( MM_GetPhysAddr(addr + PAGE_SIZE) ) {
+       if( MM_GetPhysAddr( (void*)(addr + PAGE_SIZE) ) ) {
                Log_Error("MMVirt", "Unable to create initial user stack, addr %p taken",
                        addr + PAGE_SIZE
                        );
@@ -938,18 +946,20 @@ void MM_int_DumpTableEnt(tVAddr Start, size_t Len, tMM_PageInfo *Info)
 {
        if( giMM_ZeroPage && Info->PhysAddr == giMM_ZeroPage )
        {
-               Debug("%p => %8s - 0x%7x %i %x %s",
+               Debug("%p => %8s - 0x%7x D%i %x %s %s",
                        Start, "ZERO", Len,
                        Info->Domain, Info->AP,
-                       Info->bGlobal ? "G" : "nG"
+                       Info->bExecutable ? " X" : "nX",
+                       Info->bGlobal ? " G" : "nG"
                        );
        }
        else
        {
-               Debug("%p => %8x - 0x%7x %i %x %s",
+               Debug("%p => %8x - 0x%7x D%i %x %s %s",
                        Start, Info->PhysAddr-Len, Len,
                        Info->Domain, Info->AP,
-                       Info->bGlobal ? "G" : "nG"
+                       Info->bExecutable ? " X" : "nX",
+                       Info->bGlobal ? " G" : "nG"
                        );
        }
 }
@@ -996,7 +1006,7 @@ void MM_DumpTables(tVAddr Start, tVAddr End)
 }
 
 // NOTE: Runs in abort context, not much difference, just a smaller stack
-void MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch)
+void MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch, Uint32 UserLR)
 {
         int    rv;
        tMM_PageInfo    pi;
@@ -1070,6 +1080,33 @@ void MM_PageFault(Uint32 PC, Uint32 Addr, Uint32 DFSR, int bPrefetch)
        Log_Error("MMVirt", "Code at %p accessed %p (DFSR = 0x%x)%s", PC, Addr, DFSR,
                (bPrefetch ? " - Prefetch" : "")
                );
+       Log_Error("MMVirt", "- User LR = 0x%x", UserLR);
+       const char * const dfsr_errors[] = {
+               /* 00000 */ "-", "Alignment Fault",
+               /* 00010 */ "Debug event", "Access Flag (Section)",
+               /* 00100 */ "Instr Cache Maint", "Translation (Section)",
+               /* 00110 */ "Access Flag (Page)", "Translation (Page)",
+               /* 01000 */ "Sync. External abort", "Domain (Section)",
+               /* 01010 */ "-", "Domain (Page)",
+               /* 01100 */ "Table Walk sync ext (lvl 1)", "Permission (Section)",
+               /* 01110 */ "Table Walk sync ext (lvl 2)", "Permission (Page)",
+               // 0b10000
+               /* 10000 */ "-", "-",
+               /* 10010 */ "-", "-",
+               /* 10100 */ "IMPL (Lockdown)", "-",
+               /* 10110 */ "Async. Extern. Abort", "-",
+               /* 11000 */ "Mem. access async pairity error", "Mem. access async pairity error",
+               /* 11010 */ "IMPL (Coprocessor abort)", "-",
+               /* 11100 */ "Table Walk Sync parity (lvl 1)", "-",
+               /* 11110 */ "Table Walk Sync parity (lvl 2)", "-"
+               };
+        int    errcode = (DFSR & 0xF) | (((DFSR >> 10) & 1) << 4);
+       Log_Error("MMVirt", "- Errcode 0b%05b", errcode);
+       Log_Error("MMVirt", "- Dom %i %s %s",
+               (DFSR >> 4) & 0xF, (DFSR & 0x800 ? "Write": "Read"),
+               dfsr_errors[errcode]
+               );
+       Log_Error("MMVirt", "- AP=%i(%s) %s", pi.AP, caAPValueNames[pi.AP], pi.bExecutable ? " Executable":"");
        if( Addr < 0x80000000 )
                MM_DumpTables(0, 0x80000000);
        else
index 9d5643e..fa1e02c 100644 (file)
@@ -136,7 +136,7 @@ tThread *Proc_SpawnWorker( void (*Fnc)(void*), void *Ptr )
        Uint32  sp;
 
        new = Threads_CloneThreadZero();
-       if(!new)        return -1;
+       if(!new)        return NULL;
        if(new->ThreadName)     free(new->ThreadName);
        new->ThreadName = NULL;
 
index 113c8a4..71534f5 100644 (file)
@@ -194,12 +194,21 @@ DataAbort:
 @      cpsid ifa, #19
        PUSH_GPRS
 
+       @ Get the user's LR value (and push to stack)
+       cps #31 @ Go to system mode
+       mov r1, lr
+       cps #19 @ Go to supervisor
+       mov r0, lr
+       cps #23 @ back to exception
+       push {r0,r1}
+       
        mov r3, #0      @ not a prefetch abort
        mrc p15, 0, r2, c5, c0, 0       @ Read DFSR (Data Fault Status Register) to R2
        mrc p15, 0, r1, c6, c0, 0       @ Read DFAR (Data Fault Address Register) into R1
        mov r0, lr      @ PC
        ldr r4, =MM_PageFault
        blx r4
+       add sp, #8      @ Undo push of the user/system LR
 
        POP_GPRS
        rfeia sp!       @ Pop state (actually RFEFD)
@@ -211,17 +220,24 @@ PrefetchAbort:
 @      cpsid ifa, #19
        PUSH_GPRS
 
-       ldr r0, =csAbort_Tag
-       ldr r1, =csPrefetchAbort_Fmt
-#      mov r2, lr
-       mrc p15, 0, r2, c6, c0, 2       @ Read IFAR (Instruction Fault Address Register) into R3
-       mrc p15, 0, r3, c5, c0, 1       @ Read IFSR (Instruction Fault Status Register) into R3
-       ldr r5, =Log_Error
-       blx r5
 
-.loop:
-       wfi
-       b .loop
+       @ Get the user's LR value (and push to stack)
+       cps #31 @ Go to system mode
+       mov r0, lr
+       cps #23 @ back to supervisor
+       push {r0}
+       
+       mrc p15, 0, r2, c5, c0, 1       @ Read IFSR (Instruction Fault Status Register) into R3
+       mrc p15, 0, r1, c6, c0, 2       @ Read IFAR (Instruction Fault Address Register) into R3
+       mov r0, r1
+       mov r3, #1      @ IS a prefetch abort
+       ldr r4, =MM_PageFault
+       blx r4
+       add sp, #4      @ Undo push of the user LR
+
+       POP_GPRS
+       rfeia sp!       @ Pop state (actually RFEFD)
+
 .globl Undef_Handler
 Undef_Handler:
        wfi
@@ -238,7 +254,7 @@ csIRQ_Fmt:
 csDataAbort_Fmt:
        .asciz "Data Abort - %p accessed %p, DFSR=%x Unk:%x Unk:%x"
 csPrefetchAbort_Fmt:
-       .asciz "Prefetch Abort at %p, IFSR=%x"
+       .asciz "Prefetch Abort at %p, IFSR=%x, UserLR:0x%x"
 csSyscallPrintRetAddr:
        .asciz "Syscall ret to %p"
 
diff --git a/KernelLand/Kernel/arch/armv7/vpci_realview_pb.c b/KernelLand/Kernel/arch/armv7/vpci_realview_pb.c
new file mode 100644 (file)
index 0000000..8c8afdb
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Acess2 Kernel ARMv7 Port
+ * - By John Hodge (thePowersGang)
+ *
+ * vpci_realview_pb.c
+ * - Realview PB VPCI Definitions
+ */
+#include <virtual_pci.h>
+
+// === PROTOTYPES ===
+
+// === GLOBALS ===
+tVPCI_Device   gaVPCI_Devices[] = {
+};
+int giVPCI_DeviceCount = sizeof(gaVPCI_Devices)/sizeof(gaVPCI_Devices[0]);
+
index a09b29a..533b05d 100644 (file)
@@ -3,8 +3,7 @@
  * Linker Script
  */
 
-lowStart = start - 0xC0000000;
-ENTRY(lowStart)
+ENTRY(start)
 OUTPUT_FORMAT(elf32-i386)
 
 SECTIONS {
@@ -12,6 +11,7 @@ SECTIONS {
        __load_addr = .;
        .multiboot : AT(ADDR(.multiboot)) {
                *(.multiboot)
+               *(.inittext)
        }
        
        . += 0xC0000000;
index 897c9bb..7403f38 100644 (file)
@@ -30,6 +30,7 @@ int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt *
                        if( !MM_GetPhysAddr(ent) )
                                Log_KernelPanic("MBoot", "MBoot Map entry %i addres bad (%p)",
                                        nPMemMapEnts, ent);
+                       LOG("%llx+%llx", ent->Base, ent->Length);
        
                        nent->Start = ent->Base;
                        nent->Length = ent->Length;
@@ -68,15 +69,18 @@ int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt *
        }
 
        // Ensure it's valid
+       LOG("Validating");
        nPMemMapEnts = PMemMap_ValidateMap(Map, nPMemMapEnts, MapSize);
        // TODO: Error handling
 
        // Replace kernel with PMEMTYPE_USED
+       LOG("Marking kernel");
        nPMemMapEnts = PMemMap_MarkRangeUsed(
                Map, nPMemMapEnts, MapSize,
                KStart, KEnd - KStart
                );
 
+       LOG("Dumping");
        PMemMap_DumpBlocks(Map, nPMemMapEnts);
 
        // Check if boot modules were passed
index 1d4a35d..26f8042 100644 (file)
@@ -55,7 +55,7 @@ mboot:
 ;      dd      8
 ;mboot2_end:
        
-[section .text]
+[section .inittext]
 [extern kmain]
 [extern Desctab_Install]
 [global start]
@@ -143,7 +143,7 @@ APStartup:
        or al, 1
        mov cr0, eax
        ; Jump into PMode
-       jmp 08h:DWORD .ProtectedMode-KERNEL_BASE
+       jmp 08h:DWORD .ProtectedMode
 [bits 32]
 .ProtectedMode:
        ; Load segment registers
@@ -218,6 +218,10 @@ APStartup:
        jmp .hlt
 %endif
 
+;
+;
+;
+[section .text]
 [global GetEIP]
 GetEIP:
        mov eax, [esp]
index 22b41be..e833173 100644 (file)
@@ -276,17 +276,23 @@ DEFIRQ    i
 %assign i i+1
 %endrep
 
+[extern Proc_int_SetIRQIP]
+
 [global IrqCommon]
 IrqCommon:
        PUSH_GPR
        push gs
        push fs
-
+       
+       mov rdi, [rsp+(16+2+2)*8]       ; 2SReg + GPRs + Int/Errcode = RIP
+       call Proc_int_SetIRQIP
+       push rax
+       
 ;      mov rdi, csIRQ_Fired
 ;      mov rsi, [rsp+(16+2)*8]
 ;      call Log
        
-       mov ebx, [rsp+(16+2)*8] ; Get interrupt number (16 GPRS + 2 SRs)
+       mov ebx, [rsp+(1+2+16)*8]       ; Get interrupt number (16 GPRS + 2 SRs)
        shl ebx, 2      ; *4
        mov rax, gaIRQ_Handlers
        lea rbx, [rax+rbx*8]
@@ -300,7 +306,7 @@ IrqCommon:
        test rax, rax   ; Check if it exists
        jz .skip.%[i]
        ; Set RDI to IRQ number
-       mov rdi, [rsp+(16+2+1)*8]       ; Get IRQ number
+       mov rdi, [rsp+(16+2+1+1)*8]     ; Get IRQ number
        mov rsi, [rbx-gaIRQ_Handlers+gaIRQ_DataPtrs]
        call rax        ; Call
 .skip.%[i]:
@@ -311,12 +317,15 @@ IrqCommon:
        
        ; ACK
        mov al, 0x20
-       mov rdi, [rsp+(16+2)*8] ; Get IRQ number
+       mov rdi, [rsp+(16+2+1)*8]       ; Get IRQ number
        cmp rdi, 8
        jb .skipAckSecondary
        out 0xA0, al
 .skipAckSecondary:
        out 0x20, al
+
+       pop rdi
+       call Proc_int_SetIRQIP
        
        pop fs
        pop gs
@@ -398,7 +407,10 @@ SyscallStub:
        mov [rsp+0x28], r10     ; Arg4
        mov [rsp+0x30], r8      ; Arg5
        mov [rsp+0x38], r9      ; Arg6
-       
+
+       mov rdi, rcx    
+       call Proc_int_SetIRQIP
+
        mov rdi, rsp
        sub rsp, 8
        call SyscallHandler
index e7812c3..fda3113 100644 (file)
@@ -13,6 +13,7 @@
 extern int     MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs);
 extern void    Error_Backtrace(Uint IP, Uint BP);
 extern void    Proc_EnableSSE(void);
+extern void    Threads_Dump(void);
 extern void    Proc_RestoreSSE(Uint32 Data);
 
 // === PROTOTYPES ===
@@ -98,6 +99,9 @@ void Error_Handler(tRegs *Regs)
                        *(Uint8*)(Regs->RIP+2), *(Uint8*)(Regs->RIP+3)
                        );
                break;
+       case 2: // NMI
+               Threads_Dump();
+               break;
        }
        
        __asm__ __volatile__ ("cli");
index 6cf25f0..120afb3 100644 (file)
@@ -84,7 +84,7 @@
 // === FUNCTIONS ===
 void   MM_FinishVirtualInit(void);
 tVAddr MM_NewKStack(void);
-tVAddr MM_Clone(void);
+tVAddr MM_Clone(int bCopyUser);
 tVAddr MM_NewWorkerStack(void *StackData, size_t StackSize);
 
 #endif
index 0953cbf..de7ae52 100644 (file)
@@ -722,43 +722,73 @@ int MM_IsValidBuffer(tVAddr Addr, size_t Size)
 
        Size += Addr & (PAGE_SIZE-1);
        Addr &= ~(PAGE_SIZE-1);
-       Addr &= ((1UL << 48)-1);        // Clap to address space
+       // NC addr
+       if( ((Addr >> 47) & 1) != ((Addr>>48) == 0xFFFF))
+               return 0;
+       Addr &= ((1UL << 48)-1);        // Clamp to address space
 
        pml4 = Addr >> 39;
        pdp = Addr >> 30;
        dir = Addr >> 21;
        tab = Addr >> 12;
 
-       if( !(PAGEMAPLVL4(pml4) & 1) )  return 0;
-       if( !(PAGEDIRPTR(pdp) & 1) )    return 0;
-       if( !(PAGEDIR(dir) & 1) )       return 0;
-       if( !(PAGETABLE(tab) & 1) )     return 0;
+       if( !(PAGEMAPLVL4(pml4) & 1) ) {
+               Log_Debug("MMVirt", "PML4E %i NP", pml4);
+               return 0;
+       }
+       if( !(PAGEDIRPTR(pdp) & 1) ) {
+               Log_Debug("MMVirt", "PDPE %i NP", pdp);
+               return 0;
+       }
+       if( !(PAGEDIR(dir) & 1) ) {
+               Log_Debug("MMVirt", "PDE %i NP", dir);
+               return 0;
+       }
+       if( !(PAGETABLE(tab) & 1) ) {
+               Log_Debug("MMVirt", "PTE %i NP", tab);
+               return 0;
+       }
        
        bIsUser = !!(PAGETABLE(tab) & PF_USER);
 
        while( Size >= PAGE_SIZE )
        {
+               tab ++;
+               Size -= PAGE_SIZE;
+               
                if( (tab & 511) == 0 )
                {
                        dir ++;
-                       if( ((dir >> 9) & 511) == 0 )
+                       if( (dir & 511) == 0 )
                        {
                                pdp ++;
-                               if( ((pdp >> 18) & 511) == 0 )
+                               if( (pdp & 511) == 0 )
                                {
                                        pml4 ++;
-                                       if( !(PAGEMAPLVL4(pml4) & 1) )  return 0;
+                                       if( !(PAGEMAPLVL4(pml4) & 1) ) {
+                                               Log_Debug("MMVirt", "IsValidBuffer - PML4E %x NP, Size=%x", pml4, Size);
+                                               return 0;
+                                       }
                                }
-                               if( !(PAGEDIRPTR(pdp) & 1) )    return 0;
+                               if( !(PAGEDIRPTR(pdp) & 1) ) {
+                                       Log_Debug("MMVirt", "IsValidBuffer - PDPE %x NP", pdp);
+                                       return 0;
+                               }
+                       }
+                       if( !(PAGEDIR(dir) & 1) ) {
+                               Log_Debug("MMVirt", "IsValidBuffer - PDE %x NP", dir);
+                               return 0;
                        }
-                       if( !(PAGEDIR(dir) & 1) )       return 0;
                }
                
-               if( !(PAGETABLE(tab) & 1) )   return 0;
-               if( bIsUser && !(PAGETABLE(tab) & PF_USER) )    return 0;
-
-               tab ++;
-               Size -= PAGE_SIZE;
+               if( !(PAGETABLE(tab) & 1) ) {
+                       Log_Debug("MMVirt", "IsValidBuffer - PTE %x NP", tab);
+                       return 0;
+               }
+               if( bIsUser && !(PAGETABLE(tab) & PF_USER) ) {
+                       Log_Debug("MMVirt", "IsValidBuffer - PTE %x Not user", tab);
+                       return 0;
+               }
        }
        return 1;
 }
@@ -849,6 +879,7 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr)
        
        // Allocated successfully, now map
        ret = MM_MapHWPages(phys, Pages);
+       *PhysAddr = phys;
        // MapHWPages references the pages, so deref them back down to 1
        for(;Pages--;phys+=0x1000)
                MM_DerefPhys(phys);
@@ -857,7 +888,6 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr)
                return 0;
        }
        
-       *PhysAddr = phys;
        return ret;
 }
 
@@ -894,7 +924,7 @@ void MM_FreeTemp(void *Ptr)
 
 
 // --- Address Space Clone --
-tPAddr MM_Clone(void)
+tPAddr MM_Clone(int bNoUserCopy)
 {
        tPAddr  ret;
         int    i;
@@ -910,7 +940,7 @@ tPAddr MM_Clone(void)
        INVLPG_ALL();
        
        // #3 Set Copy-On-Write to all user pages
-       if( Threads_GetPID() != 0 )
+       if( Threads_GetPID() != 0 && !bNoUserCopy )
        {
                for( i = 0; i < 256; i ++)
                {
index f540b3b..f3b3a28 100644 (file)
@@ -21,7 +21,7 @@ NewTaskHeader:
        mov rdi, [rsp+0x10]
        mov rax, [rsp+0x8]
        add rsp, 0x10   ; Reclaim stack space (thread/fcn)
-       xchg bx, bx
+       ;xchg bx, bx
        call rax
        
        ; Quit thread with RAX as the return code
@@ -39,6 +39,8 @@ Proc_CloneInt:
        PUSH_GPR
        ; Save RSP
        mov [rdi], rsp
+       ; Call MM_Clone (with bNoUserCopy flag)
+       mov rdi, rdx
        call MM_Clone
        ; Save CR3
        mov rsi, [rsp+0x30]     ; Saved version of RSI
index 2a38d62..b35b507 100644 (file)
@@ -37,7 +37,7 @@ extern void   APStartup(void);        // 16-bit AP startup code
 
 extern Uint    GetRIP(void);   // start.asm
 extern Uint    SaveState(Uint *RSP, Uint *Regs);
-extern Uint    Proc_CloneInt(Uint *RSP, Uint *CR3);
+extern Uint    Proc_CloneInt(Uint *RSP, Uint *CR3, int bCopyUserVM);
 extern void    NewTaskHeader(void);    // Actually takes cdecl args
 extern void    Proc_InitialiseSSE(void);
 extern void    Proc_SaveSSE(Uint DestPtr);
@@ -75,6 +75,7 @@ void  Proc_StartProcess(Uint16 SS, Uint Stack, Uint Flags, Uint16 CS, Uint IP) NO
 //void Proc_DumpThreadCPUState(tThread *Thread);
 //void Proc_Reschedule(void);
 void   Proc_Scheduler(int CPU, Uint RSP, Uint RIP);
+Uint   Proc_int_SetIRQIP(Uint RIP);
 
 // === GLOBALS ===
 //!\brief Used by desctab.asm in SyscallStub
@@ -506,7 +507,7 @@ tTID Proc_Clone(Uint Flags)
        if(!newThread)  return -1;
        
        // Save core machine state
-       rip = Proc_CloneInt(&newThread->SavedState.RSP, &newThread->Process->MemState.CR3);
+       rip = Proc_CloneInt(&newThread->SavedState.RSP, &newThread->Process->MemState.CR3, !!(Flags & CLONE_NOUSER));
        if(rip == 0)    return 0;       // Child
        newThread->KernelStack = cur->KernelStack;
        newThread->SavedState.RIP = rip;
@@ -722,7 +723,14 @@ void Proc_CallFaultHandler(tThread *Thread)
 
 void Proc_DumpThreadCPUState(tThread *Thread)
 {
-       Log("  At %04x:%016llx", Thread->SavedState.UserCS, Thread->SavedState.UserRIP);
+       if( Thread->CurCPU == GetCPUNum() ) {
+               // TODO: Backtrace to IRQ
+               Log("  IRQ %016llx", Thread->SavedState.UserRIP);
+       }
+       else {
+               Log("  At %016llx, SP=%016llx", Thread->SavedState.RIP, Thread->SavedState.RSP);
+               Log("  User %04x:%016llx", Thread->SavedState.UserCS, Thread->SavedState.UserRIP);
+       }
 }
 
 void Proc_Reschedule(void)
@@ -755,7 +763,7 @@ void Proc_Reschedule(void)
 
        // Update CPU state
        gaCPUs[cpu].Current = nextthread;
-       gTSSs[cpu].RSP0 = nextthread->KernelStack-4;
+       gTSSs[cpu].RSP0 = nextthread->KernelStack-sizeof(void*);
        __asm__ __volatile__ ("mov %0, %%db0" : : "r" (nextthread));
 
        if( curthread )
@@ -822,5 +830,14 @@ void Proc_Scheduler(int CPU, Uint RSP, Uint RIP)
 #endif
 }
 
+Uint Proc_int_SetIRQIP(Uint RIP)
+{
+        int    cpu = GetCPUNum();
+       tThread *thread = gaCPUs[cpu].Current;
+       Uint    rv = thread->SavedState.UserRIP;
+       thread->SavedState.UserRIP = RIP;
+       return rv;
+}
+
 // === EXPORTS ===
 EXPORT(Proc_SpawnWorker);
index 76724bc..4456a2c 100644 (file)
@@ -1,21 +1,37 @@
 /*\r
- * Acess v0.1\r
- * ELF Executable Loader Code\r
+ * Acess2 Kernel\r
+ * - By John Hodge (thePowersGang)\r
+ *\r
+ * elf.c\r
+ * - ELF Executable Loader Code\r
  */\r
 #define DEBUG  0\r
 #include <acess.h>\r
 #include <binary.h>\r
 \r
+// ---- Import linking code from userland\r
 #define _COMMON_H\r
 #define SysDebug(v...) LOG(v)\r
 #if BITS <= 32\r
 # define DISABLE_ELF64\r
 #endif\r
-void   *GetSymbol(const char *Name, size_t *Size);\r
-void   *GetSymbol(const char *Name, size_t *Size) { Uint val; Binary_GetSymbol(Name, &val); if(Size)*Size=0; return (void*)val; };\r
+static int     GetSymbol(const char *Name, void **Value, size_t *Size);\r
+static int     GetSymbol(const char *Name, void **Value, size_t *Size) {\r
+       Uint val;\r
+       if(!Binary_GetSymbol(Name, &val)) {\r
+               Log_Notice("ELF", "Lookup of '%s' failed", Name);\r
+               return 0;\r
+       }\r
+       if(Size)\r
+               *Size=0;\r
+       *Value = (void*)val;\r
+       return 1;\r
+}\r
 #define AddLoaded(a,b) do{}while(0)\r
 #define LoadLibrary(a,b,c)     (Log_Debug("ELF", "Module requested lib '%s'",a),0)\r
+#define SysSetMemFlags(ad,f,m) do{}while(0)\r
 #include "../../../Usermode/Libraries/ld-acess.so_src/elf.c"\r
+// ---- / ----\r
 \r
 #define DEBUG_WARN     1\r
 \r
index 92baa73..208ab95 100644 (file)
@@ -194,9 +194,10 @@ int Proc_SysSpawn(const char *Binary, const char **ArgV, const char **EnvP, int
                Proc_Execve(Binary, ArgV, EnvP, size);
                for(;;);
        }
-       if( ret < 0 )
+       if( ret == -1 )
        {
                VFS_FreeSavedHandles(nFD, handles);
+               free(cachebuf);
        }
        
        return ret;
index 31b050f..b44564e 100644 (file)
@@ -133,9 +133,6 @@ void VT_KBCallBack(Uint32 Codepoint)
        
                Codepoint &= KEY_CODEPOINT_MASK;
 
-               // Ignore Modifer Keys
-               if(Codepoint > KEY_MODIFIERS)   return;
-               
                // Get UTF-8/ANSI Encoding
                if( Codepoint == 0 )
                {
index f027e0e..964be49 100644 (file)
@@ -87,56 +87,6 @@ typedef void (*tKeybardCallback)(Uint32 Key);
  * \}\r
  */\r
 \r
-/**\r
- * \brief Symbolic key codes\r
- * \r
- * These key codes represent non-pritable characters and are placed above\r
- * the Unicode character space.\r
- * If the using driver recieves a key code with the 31st bit set, it means\r
- * that that key has been released.\r
- */\r
-enum eTplKeyboard_KeyCodes {\r
-       KEY_ESC = 0x1B, //!< Escape Character\r
-       \r
-       KEY_NP_MASK = 0x20000000,       //! Mask for non-printable characters\r
-       \r
-       /**\r
-        * \name Special Keys\r
-        * \brief These keys are usually used on their own\r
-        * \{\r
-        */\r
-       KEY_CAPSLOCK,\r
-       KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT,\r
-       KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, \r
-       KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12,\r
-       KEY_NUMLOCK, KEY_SCROLLLOCK,\r
-       KEY_HOME, KEY_END, KEY_INS, KEY_DEL,\r
-       KEY_PAUSE, KEY_BREAK,\r
-       KEY_PGUP, KEY_PGDOWN,\r
-       KEY_KPENTER, KEY_KPSLASH, KEY_KPMINUS, KEY_KPPLUS, KEY_KPSTAR,\r
-       KEY_KPHOME, KEY_KPUP, KEY_KPPGUP, KEY_KPLEFT, KEY_KP5, KEY_KPRIGHT,\r
-       KEY_KPEND, KEY_KPDOWN, KEY_KPPGDN, KEY_KPINS, KEY_KPDEL,\r
-       KEY_LWIN, KEY_RWIN,\r
-       KEY_MENU,\r
-       /**\r
-        * \}\r
-        */\r
-       \r
-       // Modifiers\r
-       /**\r
-        * \name Modifiers\r
-        * \brief These keye usually alter the character stream sent to the user\r
-        * \{\r
-        */\r
-       KEY_MODIFIERS = 0x30000000,\r
-       KEY_LCTRL, KEY_RCTRL,\r
-       KEY_LALT, KEY_RALT,\r
-       KEY_LSHIFT, KEY_RSHIFT,\r
-       /**\r
-        * \}\r
-        */\r
-};\r
-\r
 #include "keysyms.h"\r
 \r
 #endif\r
index 13d3b82..80cb1c9 100644 (file)
@@ -56,7 +56,7 @@ extern void   Debug_HexDump(const char *Header, const void *Data, size_t Length);
 # define LEAVE_RET(_t,_v...)   return (_v)
 # define LEAVE_RET0()  return
 #endif
-#if SANITY
+#if !DISABLE_ASSERTS
 # define ASSERT(expr) do{if(!(expr))Panic("%s:%i - %s: Assertion '"#expr"' failed",__FILE__,__LINE__,(char*)__func__);}while(0)
 #else
 # define ASSERT(expr)
index 36b877c..5f302d4 100644 (file)
@@ -287,23 +287,23 @@ Sint64 timestamp(int sec, int min, int hrs, int day, int month, int year)
        return stamp * 1000;
 }
 
+static Sint64 DivMod64(Sint64 N, Sint64 D, Sint64 *R);
+       
+static Sint64 DivMod64(Sint64 N, Sint64 D, Sint64 *R)
+{
+       int sign = (N < 0) != (D < 0);
+       if(N < 0)       N = -N;
+       if(D < 0)       D = -D;
+       if(sign)
+               return -DivMod64U(N, D, (Uint64*)R);
+       else
+               return DivMod64U(N, D, (Uint64*)R);
+}
+
 void format_date(tTime TS, int *year, int *month, int *day, int *hrs, int *mins, int *sec, int *ms)
 {
         int    is_leap = 0, i;
 
-       auto Sint64 DivMod64(Sint64 N, Sint64 D, Sint64 *R);
-       
-       Sint64 DivMod64(Sint64 N, Sint64 D, Sint64 *R)
-       {
-               int sign = (N < 0) != (D < 0);
-               if(N < 0)       N = -N;
-               if(D < 0)       D = -D;
-               if(sign)
-                       return -DivMod64U(N, D, (Uint64*)R);
-               else
-                       return DivMod64U(N, D, (Uint64*)R);
-       }
-
        // Get time
        // TODO: Leap-seconds?
        {
index ef94426..8674650 100644 (file)
@@ -184,7 +184,14 @@ void itoa(char *buf, Uint64 num, int base, int minLength, char pad)
 /**
  * \brief Append a character the the vsnprintf output
  */
-#define PUTCH(c)       _putch(c)
+#define PUTCH(ch)      do { \
+               if(pos < __maxlen) { \
+                       if(__s) __s[pos] = ch; \
+               } else { \
+                       (void)ch;\
+               } \
+               pos ++; \
+       } while(0)
 #define GETVAL()       do {\
        if(isLongLong)  val = va_arg(args, Uint64);\
        else    val = va_arg(args, unsigned int);\
@@ -203,17 +210,6 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
        size_t  pos = 0;
        // Flags
         int    bPadLeft = 0;
-       
-       auto void _putch(char ch);
-
-       void _putch(char ch)
-       {
-               if(pos < __maxlen)
-               {
-                       if(__s) __s[pos] = ch;
-               }
-               pos ++;
-       }
 
        while((c = *__format++) != 0)
        {
@@ -230,8 +226,14 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
                if(c == 'p') {
                        Uint    ptr = va_arg(args, Uint);
                        PUTCH('*');     PUTCH('0');     PUTCH('x');
-                       for( len = BITS/4; len --; )
-                               PUTCH( cUCDIGITS[ (ptr>>(len*4))&15 ] );
+                       for( len = BITS/4; len -- && ((ptr>>(len*4))&15) == 0; )
+                               ;
+                       len ++;
+                       if( len == 0 )
+                               PUTCH( '0' );
+                       else
+                               while( len -- )
+                                       PUTCH( cUCDIGITS[ (ptr>>(len*4))&15 ] );
                        continue ;
                }
                
@@ -742,7 +744,8 @@ void *memmove(void *__dest, const void *__src, size_t len)
        
 }
 
-// NOTE: Strictly not libc, but lib.c is used by userland code too
+// NOTE: Strictly not libc, but lib.c is used by userland code too and hence these two
+// can't be in it.
 /**
  * \name Memory Validation
  * \{
index 9617b83..aab25a1 100644 (file)
@@ -91,12 +91,10 @@ void Log_AddEvent(const char *Ident, int Level, const char *Format, va_list Args
        va_list args_tmp;
        
        if( Level >= NUM_LOG_LEVELS )   return;
-       
+
        va_copy(args_tmp, Args);
        len = vsnprintf(NULL, 256, Format, args_tmp);
        
-       //Log("len = %i", len);
-       
        #if USE_RING_BUFFER || !CACHE_MESSAGES
        {
        char    buf[sizeof(tLogEntry)+len+1];
@@ -161,9 +159,11 @@ void Log_Int_PrintMessage(tLogEntry *Entry)
        if( CPU_HAS_LOCK(&glLogOutput) )
                return ;        // TODO: Error?
        SHORTLOCK( &glLogOutput );
-       LogF("%s%014lli%s [%-8s] %i - %s",
+       LogF("%s%014lli",
                csaLevelColours[Entry->Level],
-               Entry->Time,
+               Entry->Time
+               );
+       LogF("%s [%-8s] %i - %s",
                csaLevelCodes[Entry->Level],
                Entry->Ident,
                Threads_GetTID(),
index c991978..8237423 100644 (file)
@@ -137,10 +137,13 @@ int Proc_GetMessage(Uint *Source, Uint BufSize, void *Buffer)
        // Remove from list
        tmp = cur->Messages;
        cur->Messages = cur->Messages->Next;
+       // - Removed last message? Clear the end-of-list pointer
        if(cur->Messages == NULL)       cur->LastMessage = NULL;
+       //  > Otherwise, re-mark the IPCMSG event flag
+       else    cur->EventState |= THREAD_EVENT_IPCMSG;
        
        SHORTREL( &cur->IsLocked );
-       
+
        free(tmp);      // Free outside of lock
 
        LEAVE('i', ret);
index bfd68bf..82389bb 100644 (file)
 #include <events.h>
 
 #define CHECK_NUM_NULLOK(v,size)       \
-       if((v)&&!Syscall_Valid((size),(v))){ret=-1;err=-EINVAL;break;}
+       if((v)&&!Syscall_Valid((size),(v))){LOG("CHECK_NUM_NULLOK: %p(%x) FAIL",v,size);ret=-1;err=-EINVAL;break;}
 #define CHECK_STR_NULLOK(v)    \
-       if((v)&&!Syscall_ValidString((v))){ret=-1;err=-EINVAL;break;}
+       if((v)&&!Syscall_ValidString((v))){LOG("CHECK_STR_NULLOK: %p FAIL",v);ret=-1;err=-EINVAL;break;}
 #define CHECK_NUM_NONULL(v,size)       \
-       if(!(v)||!Syscall_Valid((size),(v))){ret=-1;err=-EINVAL;break;}
+       if(!(v)||!Syscall_Valid((size),(v))){LOG("CHECK_NUM_NONULL: %p(%x) FAIL",v,size);ret=-1;err=-EINVAL;break;}
 #define CHECK_STR_NONULL(v)    \
-       if(!(v)||!Syscall_ValidString((v))){ret=-1;err=-EINVAL;break;}
+       if(!(v)||!Syscall_ValidString((v))){LOG("CHECK_STR_NONULL: %p FAIL",v);ret=-1;err=-EINVAL;break;}
 #define CHECK_STR_ARRAY(arr)   do {\
         int    i;\
        char    **tmp = (char**)arr; \
@@ -38,6 +38,7 @@ extern Uint   Binary_Load(const char *file, Uint *entryPoint);
 void   SyscallHandler(tSyscallRegs *Regs);
  int   Syscall_ValidString(const char *Addr);
  int   Syscall_Valid(int Size, const void *Addr);
+ int   Syscall_MM_SetFlags(const void *Addr, Uint Flags, Uint Mask);
 
 // === CODE ===
 // TODO: Do sanity checking on arguments, ATM the user can really fuck with the kernel
@@ -114,6 +115,11 @@ void SyscallHandler(tSyscallRegs *Regs)
        // -- Unmap an address
        case SYS_UNMAP:         MM_Deallocate(Regs->Arg1);      break;
        
+       // -- Change the protection on an address
+       case SYS_SETFLAGS:
+               ret = Syscall_MM_SetFlags((void*)Regs->Arg1, Regs->Arg2, Regs->Arg3);
+               break;
+
        // -- Get Thread/Process IDs
        case SYS_GETTID:        ret = Threads_GetTID(); break;
        case SYS_GETPID:        ret = Threads_GetPID(); break;
@@ -160,7 +166,7 @@ void SyscallHandler(tSyscallRegs *Regs)
                CHECK_STR_NONULL((const char*)Regs->Arg1);
                CHECK_STR_ARRAY((const char**)Regs->Arg2);
                CHECK_STR_ARRAY((const char**)Regs->Arg3);
-               CHECK_NUM_NONULL((void*)Regs->Arg5, Regs->Arg4*sizeof(int));
+               CHECK_NUM_NULLOK((void*)Regs->Arg5, Regs->Arg4*sizeof(int));
                ret = Proc_SysSpawn(
                        (const char*)Regs->Arg1, (const char**)Regs->Arg2, (const char**)Regs->Arg3,
                        Regs->Arg4, (int*)Regs->Arg5
@@ -394,7 +400,31 @@ int Syscall_ValidString(const char *Addr)
  */
 int Syscall_Valid(int Size, const void *Addr)
 {
-       if(!MM_IsUser( (tVAddr)Addr ))  return 0;
+       if(!MM_IsUser( (tVAddr)Addr )) {
+               Log_Debug("Syscalls", "Syscall_Valid - %p not user", Addr);
+               return 0;
+       }
        
        return CheckMem( Addr, Size );
 }
+
+int Syscall_MM_SetFlags(const void *Addr, Uint Flags, Uint Mask)
+{
+       tPAddr  paddr = MM_GetPhysAddr(Addr);
+       Flags &= MM_PFLAG_RO|MM_PFLAG_EXEC;
+       Mask &= MM_PFLAG_RO|MM_PFLAG_EXEC;
+
+       //Log_Debug("Syscalls", "SYS_SETFLAGS: %p %x %x", Addr, Flags, Mask);   
+
+       // Enable write?
+       if( (Mask & MM_PFLAG_RO) && !(Flags & MM_PFLAG_RO) ) {
+               void    *node;
+               // HACK - Assume that RO mmap'd files are immutable
+               if( MM_GetPageNode(paddr, &node) == 0 && node ) {
+                       Flags |= MM_PFLAG_COW;
+                       Mask |= MM_PFLAG_COW;
+               }
+       }
+       MM_SetFlags((tVAddr)Addr, Flags, Mask);
+       return 0;
+}
index 17cccca..a21db4a 100644 (file)
@@ -1079,7 +1079,7 @@ void Threads_int_DumpThread(tThread *thread)
        default:        break;
        }
        Log("  Priority %i, Quantum %i", thread->Priority, thread->Quantum);
-       Log("  KStack 0x%x", thread->KernelStack);
+       Log("  KStack %p", thread->KernelStack);
        if( thread->bInstrTrace )
                Log("  Tracing Enabled");
        Proc_DumpThreadCPUState(thread);
index c5015e6..8930177 100644 (file)
@@ -57,6 +57,7 @@ void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD,
                                        PAGE_SIZE - (mapping_base & (PAGE_SIZE-1))
                                        );
                                memset( (void*)(mapping_base + ofs), 0, PAGE_SIZE - (mapping_base & (PAGE_SIZE-1)));
+                               LOG("dune");
                        }
                        else {
                                LOG("New empty page");
index 0d23894..b2cc57f 100644 (file)
@@ -85,7 +85,7 @@ tVFS_Node *Inode_GetCache(int Handle, Uint64 Inode)
 tVFS_Node *Inode_CacheNode(int Handle, tVFS_Node *Node)
 {
        tInodeCache     *cache;
-       tCachedInode    *newEnt, *ent, *prev;
+       tCachedInode    *newEnt, *ent, *prev = NULL;
        
        cache = Inode_int_GetFSCache(Handle);
        if(!cache)      return NULL;
@@ -95,7 +95,6 @@ tVFS_Node *Inode_CacheNode(int Handle, tVFS_Node *Node)
        
        // Search Cache
        ent = cache->FirstNode;
-       prev = (tCachedInode*) &cache->FirstNode;
        for( ; ent; prev = ent, ent = ent->Next )
        {
                if(ent->Node.Inode < Node->Inode)       continue;
@@ -110,7 +109,10 @@ tVFS_Node *Inode_CacheNode(int Handle, tVFS_Node *Node)
        newEnt = malloc(sizeof(tCachedInode));
        newEnt->Next = ent;
        memcpy(&newEnt->Node, Node, sizeof(tVFS_Node));
-       prev->Next = newEnt;
+       if( prev )
+               prev->Next = newEnt;
+       else
+               cache->FirstNode = newEnt;
        newEnt->Node.ReferenceCount = 1;
 
        LOG("Cached %llx as %p", Node->Inode, &newEnt->Node);
index 70f0c91..84473df 100644 (file)
@@ -47,8 +47,6 @@ enum {
        VBE_DISPI_INDEX_Y_OFFSET\r
 };\r
 \r
-extern void MM_DumpTables(tVAddr Start, tVAddr End);\r
-\r
 // === PROTOTYPES ===\r
 // Driver\r
  int   BGA_Install(char **Arguments);\r
index c930497..be0a51c 100644 (file)
@@ -98,7 +98,11 @@ int FAT_Detect(int FD)
 \r
        if(bs.bps == 0 || bs.spc == 0)\r
                return 0;\r
-       \r
+\r
+       Log_Debug("FAT", "_Detect: Media type = %02x", bs.mediaDesc);\r
+       if( bs.mediaDesc < 0xF0 )\r
+               return 0;\r
+\r
        return 1;\r
 }\r
 /**\r
index 4a6635b..5119442 100644 (file)
@@ -1,4 +1,6 @@
 <?php
+date_default_timezone_set("UTC");
+
 $lGenDate = date("Y-m-d H:i");
 $gOutput = <<<EOF
 /*
index fe2fc4d..77426da 100644 (file)
@@ -19,7 +19,6 @@ Dir "Libs" {
        File "ld-acess.so" "__BIN__/Libs/ld-acess.so"
        File "libld-acess.so" "__BIN__/Libs/libld-acess.so"
        File "libc.so" "__BIN__/Libs/libc.so"
-       File "libgcc.so" "__BIN__/Libs/libgcc.so"
        File "libreadline.so" "__BIN__/Libs/libreadline.so"
        File "libnet.so" "__BIN__/Libs/libnet.so"
        File "liburi.so" "__BIN__/Libs/liburi.so"
index 3234a77..c4e1680 100644 (file)
@@ -31,7 +31,7 @@ tUSBHub *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts)
 {
        tUSBHost        *host;
        
-       host = malloc(sizeof(tUSBHost) + nPorts*sizeof(tUSBHubPort));
+       host = malloc(sizeof(tUSBHost) + nPorts*sizeof(tUSBHubPort) + sizeof(tUSBDevice) + sizeof(tUSBInterface));
        if(!host) {
                // Oh, bugger.
                return NULL;
@@ -40,19 +40,21 @@ tUSBHub *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts)
        host->Ptr = ControllerPtr;
        memset(host->AddressBitmap, 0, sizeof(host->AddressBitmap));
 
-       host->RootHubDev.ParentHub = NULL;
-       host->RootHubDev.Host = host;
-       host->RootHubDev.Address = 0;
+       host->RootHubDev = (void*)(host->RootHub.Ports + nPorts);
+       host->RootHubDev->ParentHub = NULL;
+       host->RootHubDev->Host = host;
+       host->RootHubDev->Address = 0;
        ASSERT(HostDef->InitControl);
-       host->RootHubDev.EndpointHandles[0] = HostDef->InitControl(ControllerPtr, 0, 64);
+       host->RootHubDev->EndpointHandles[0] = HostDef->InitControl(ControllerPtr, 0, 64);
+       host->RootHubDev->nInterfaces = 0;
 
-//     host->RootHubIf.Next = NULL;
-       host->RootHubIf.Dev = &host->RootHubDev;
-       host->RootHubIf.Driver = NULL;
-       host->RootHubIf.Data = NULL;
-       host->RootHubIf.nEndpoints = 0;
+       host->RootHubIf = (void*)(host->RootHubDev + 1);
+       host->RootHubIf->Dev = host->RootHubDev;
+       host->RootHubIf->Driver = NULL;
+       host->RootHubIf->Data = NULL;
+       host->RootHubIf->nEndpoints = 0;
 
-       host->RootHub.Interface = &host->RootHubIf;
+       host->RootHub.Interface = host->RootHubIf;
        host->RootHub.nPorts = nPorts;
        memset(host->RootHub.Ports, 0, sizeof(tUSBHubPort)*nPorts);
 
index c5c8cad..2de6985 100644 (file)
@@ -101,8 +101,8 @@ struct sUSBHost
        
        Uint8   AddressBitmap[128/8];
        
-       tUSBDevice      RootHubDev;
-       tUSBInterface   RootHubIf;
+       tUSBDevice      *RootHubDev;
+       tUSBInterface   *RootHubIf;
        tUSBHub RootHub;
 };
 
index 0da8c85..c9655cb 100644 (file)
@@ -362,6 +362,7 @@ void USB_SetDeviceDataPtr(tUSBInterface *Dev, void *Ptr) { Dev->Data = Ptr; }
 int USB_int_AllocateAddress(tUSBHost *Host)
 {
         int    i;
+       ASSERT(Host);
        for( i = 1; i < 128; i ++ )
        {
                if(Host->AddressBitmap[i/8] & (1 << (i%8)))
index 57948ce..27bad3e 100644 (file)
@@ -84,7 +84,7 @@ void USB_int_WakeThread(void *Thread, void *Data, size_t Length)
 
 int USB_int_SendSetupSetAddress(tUSBHost *Host, int Address)
 {
-       USB_int_Request(&Host->RootHubDev, 0, 0x00, 5, Address & 0x7F, 0, 0, NULL);
+       USB_int_Request(Host->RootHubDev, 0, 0x00, 5, Address & 0x7F, 0, 0, NULL);
        return 0;
 }
 
index 0fe80dc..98a4b09 100644 (file)
@@ -93,7 +93,14 @@ int UHCI_Initialise(char **Arguments)
         int    ret;
        
        ENTER("");
-       
+
+       if( Arguments && *Arguments && strcmp(*Arguments, "0") == 0 )
+       {
+               LOG("Disabled by argument");
+               LEAVE('i', MODULE_ERR_NOTNEEDED);
+               return MODULE_ERR_NOTNEEDED;
+       }
+
        // Initialise with no maximum value
        Semaphore_Init( &gUHCI_InterruptSempahore, 0, 0, "UHCI", "Interrupt Queue");
 
@@ -107,14 +114,15 @@ int UHCI_Initialise(char **Arguments)
                tPAddr  tmp;    
                gaUHCI_TDPool = (void *) MM_AllocDMA(1, 32, &tmp);
                memset(gaUHCI_TDPool, 0, PAGE_SIZE);
+               LOG("gaUHCI_TDPool = %p (%P)", gaUHCI_TDPool, tmp);
        }
 
        // Enumerate PCI Bus, getting a maximum of `MAX_CONTROLLERS` devices
+       // Class:SubClass:Protocol = 0xC (Serial) : 0x3 (USB) : 0x00 (UHCI)
        while( (id = PCI_GetDeviceByClass(0x0C0300, 0xFFFFFF, id)) >= 0 && i < MAX_CONTROLLERS )
        {
                tUHCI_Controller        *cinfo = &gUHCI_Controllers[i];
                Uint32  base_addr;
-               // NOTE: Check "protocol" from PCI?
                
                cinfo->PciId = id;
                base_addr = PCI_GetBAR(id, 4);
@@ -184,6 +192,7 @@ int UHCI_int_InitHost(tUHCI_Controller *Host)
                LEAVE('i', -1);
                return -1;
        }
+       LOG("->FrameList = %p (%P)", Host->FrameList, Host->PhysFrameList);
 
        Host->TDQHPage = (void *) MM_AllocDMA(1, 32, &Host->PhysTDQHPage);
        if( !Host->TDQHPage ) {
@@ -192,6 +201,7 @@ int UHCI_int_InitHost(tUHCI_Controller *Host)
                LEAVE('i', -1);
                return -1;
        }
+       LOG("->TDQHPage = %p (%P)", Host->TDQHPage, Host->PhysTDQHPage);
 
        // Fill frame list
        // - The numbers 0...31, but bit reversed (16 (0b1000) = 1 (0b00001)
@@ -199,6 +209,7 @@ int UHCI_int_InitHost(tUHCI_Controller *Host)
                0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30,
                1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31
                };
+       // Fill all slots (but every 4th will be changed below
        for( int i = 0; i < 1024; i ++ ) {
                Uint32  addr = MM_GetPhysAddr( &Host->TDQHPage->ControlQH );
                Host->FrameList[i] = addr | 2;
@@ -214,7 +225,7 @@ int UHCI_int_InitHost(tUHCI_Controller *Host)
                Host->FrameList[768 + i*4] = addr | 2;
        }
 
-       // Build up interrupt binary tree       
+       // Build up interrupt binary tree
        {
                tUHCI_QH        *dest = Host->TDQHPage->InterruptQHs;
                Uint32  destphys = Host->PhysTDQHPage;
@@ -222,7 +233,9 @@ int UHCI_int_InitHost(tUHCI_Controller *Host)
                // Set up next pointer to index to i/2 in the next step
                for( int _count = 64; _count > 1; _count /= 2 )
                {
+                       LOG("count=%i, dest=%p, destphys=%P", _count, dest, destphys);
                        for( int i = 0; i < _count; i ++ ) {
+                               LOG(" %i-%i: %P==%P", _count, i, MM_GetPhysAddr(dest+i), destphys+i*sizeof(tUHCI_QH));
                                dest[i].Next = destphys + (_count + i/2) * sizeof(tUHCI_QH) + 2;
                                dest[i].Child = 1;
                        }
@@ -257,6 +270,7 @@ int UHCI_int_InitHost(tUHCI_Controller *Host)
        PCI_ConfigWrite( Host->PciId, 0xC0, 2, 0x2000 );
 
        // Enable processing
+       LOG("Processing enabling");
        _OutWord( Host, USBCMD, 0x0001 );
 
        LEAVE('i', 0);
@@ -301,16 +315,18 @@ void UHCI_int_AppendTD(tUHCI_Controller *Cont, tUHCI_QH *QH, tUHCI_TD *TD)
        TD->Control |= (TD->Token >> 21) & 0x7FF;
 
        // Stop controller
+       tPAddr  tdaddr = MM_GetPhysAddr( TD );
+       ASSERT(tdaddr);
        _OutWord( Cont, USBCMD, 0x0000 );
        
        // Add
        TD->Link = 1;
        if( QH->Child & 1 ) {
-               QH->Child = MM_GetPhysAddr( TD );
+               QH->Child = tdaddr;
        }
        else {
                // Depth first
-               QH->_LastItem->Link = MM_GetPhysAddr( TD ) | 4;
+               QH->_LastItem->Link = tdaddr | 4;
        }
        QH->_LastItem = TD;
 
@@ -574,7 +590,7 @@ void *UHCI_SendControl(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData,
        void *InData, size_t InLength
        )
 {
-       ENTER("pPtr pEndpt ibOutbound", Ptr, Endpt, bOutbound);
+       ENTER("pPtr pEndpt bOutbound", Ptr, Endpt, bOutbound);
        
        tUHCI_Controller        *Cont = Ptr;
        tUHCI_QH        *qh = &Cont->TDQHPage->ControlQH;
@@ -644,7 +660,14 @@ void *UHCI_SendControl(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData,
        
        // Update toggle value
        epi->Tgl = tgl;
-       
+
+       // --- HACK!!!
+//     for( int i = 0; i < 1024; i ++ )
+//     {
+//             LOG("- FrameList[%i] = %x", i, Cont->FrameList[i]);
+//     }
+       // --- /HACK    
+
        LEAVE('p', td); 
        return td;
 }
@@ -658,7 +681,7 @@ void *UHCI_SendBulk(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData, int bOu
         int    dest, tgl;
        size_t  mps;
 
-       ENTER("pPtr pEndpt pCb pCbData bOutbound pData iLength", Ptr, Dest, Cb, CbData, bOutbound, Data, Length);
+       ENTER("pPtr pEndpt pCb pCbData bOutbound pData iLength", Ptr, Endpt, Cb, CbData, bOutbound, Data, Length);
 
        if( Endpt == NULL ) {
                Log_Error("UHCI", "_SendBulk passed a NULL endpoint handle");
@@ -800,7 +823,8 @@ void UHCI_int_CleanQH(tUHCI_Controller *Cont, tUHCI_QH *QH)
                        continue ;
                }
 
-               LOG("Removed %p from QH %p", td, QH);           
+               LOG("Removed %p from QH %p", td, QH);
+               ASSERT(td->Link);
 
                if( !prev )
                        QH->Child = td->Link;
@@ -968,26 +992,38 @@ void UHCI_InterruptHandler(int IRQ, void *Ptr)
        // USB Error Interrupt
        if( status & 2 )
        {
-               
+               Log_Notice("UHCI", "USB Error");
        }
 
        // Resume Detect
        // - Fired if in suspend state and a USB device sends the RESUME signal
        if( status & 4 )
        {
-               
+               Log_Notice("UHCI", "Resume Detect");
        }
 
        // Host System Error
        if( status & 8 )
        {
-               
+               Log_Notice("UHCI", "Host System Error");
        }
 
        // Host Controller Process Error
        if( status & 0x10 )
        {
                Log_Error("UHCI", "Host controller process error on controller %p", Ptr);
+               // Spam Tree
+               //for( int i = 0; i < 1024; i += 4 ) {
+               //      LOG("%4i: %x", i, Host->FrameList[i]);
+               //}
+               
+               tPAddr  phys = Host->TDQHPage->ControlQH.Child;
+               while( !(phys & 1) && MM_GetRefCount(phys & ~15))
+               {
+                       tUHCI_TD *td = UHCI_int_GetTDFromPhys(Host, phys);
+                       LOG("%08P: %08x %08x %08x", phys, td->Control, td->Token, td->BufferPointer);
+                       phys = td->Link;
+               }
        }
 
        _OutWord(Host, USBSTS, status);
index e16a7b2..0d265c4 100644 (file)
--- a/Makefile
+++ b/Makefile
 
 SUBMAKE = $(MAKE) --no-print-directory
 
-USRLIBS := crt0.o acess.ld ld-acess.so libgcc.so libc.so
+USRLIBS := crt0.o acess.ld ld-acess.so libc.so
 USRLIBS += libreadline.so libnet.so liburi.so libpsocket.so
 USRLIBS += libimage_sif.so
 
 USRAPPS := init login CLIShell cat ls mount
 USRAPPS += bomb lspci
 USRAPPS += ip dhcpclient ping telnet irc wget telnetd
-USRAPPS += axwin3
+USRAPPS += axwin3 gui_ate
 
 ALL_DYNMODS = $(addprefix all-,$(DYNMODS))
 ALL_MODULES := $(addprefix all-,$(MODULES))
@@ -37,6 +37,8 @@ AI_USRLIBS := $(addprefix allinstall-,$(USRLIBS))
 AI_USRAPPS := $(addprefix allinstall-,$(USRAPPS))
 
 .PHONY: all clean install \
+       kmode all-kmode clean-kmode \
+       all-user clean-user \
        $(ALL_MODULES) all-Kernel $(ALL_USRLIBS) $(ALL_USRAPPS) \
        $(AI_MODULES) allinstall-Kernel $(AI_USRLIBS) $(AI_USRAPPS) \
        $(CLEAN_MODULES) clean-Kernel $(CLEAN_USRLIBS) $(CLEAN_USRAPPS) \
@@ -44,6 +46,7 @@ AI_USRAPPS := $(addprefix allinstall-,$(USRAPPS))
 
 kmode: $(AI_MODULES) $(AI_DYNMODS) allinstall-Kernel
 all-kmode:     $(ALL_MODULES) $(ALL_DYNMODS) all-Kernel
+clean-kmode:   $(CLEAN_MODULES) $(CLEAN_DYNMODS) clean-Kernel
 
 all-user: $(ALL_USRLIBS) $(ALL_USRAPPS)
 clean-user: $(CLEAN_USRLIBS) $(CLEAN_USRAPPS)
diff --git a/RunQemu b/RunQemu
index d2e9ec3..87cae41 100755 (executable)
--- a/RunQemu
+++ b/RunQemu
@@ -26,7 +26,7 @@ while [ $# -ne 0 ]; do
                        _kfile="KernelLand/Acess2.$1-$2.bin"
                fi
                BOOTOPT="-kernel $_kfile"
-               BOOTOPT=$BOOTOPT" -initrd KernelLand/Modules/Filesystems/FS_InitRD.kmd.$1 -append $3"
+               BOOTOPT=$BOOTOPT" -initrd KernelLand/Modules/Filesystems/FS_InitRD.kmd.$1 -append \"$3\""
                shift
                shift
                ;;
@@ -69,7 +69,7 @@ QEMU_PARAMS=$QEMU_PARAMS" -net "$_NETTYPE
 
 if [ "x$_NOUSB" != "xyes" ] ; then
        QEMU_PARAMS=$QEMU_PARAMS" -usb"
-       QEMU_PARAMS=$QEMU_PARAMS" -device usb-ehci"
+#      QEMU_PARAMS=$QEMU_PARAMS" -device usb-ehci"
        QEMU_PARAMS=$QEMU_PARAMS" -drive id=test_usb_image,file=USB_Test_Image.img,if=none"
        QEMU_PARAMS=$QEMU_PARAMS" -device usb-storage,drive=test_usb_image"
        QEMU_PARAMS=$QEMU_PARAMS" -usbdevice mouse"
@@ -89,4 +89,4 @@ if [ "x$_NOTEE" = "xyes" ] ; then
        exit
 fi
 
-$QEMU $BOOTOPT $QEMU_PARAMS -serial stdio | tee QemuLog.txt
+eval $QEMU $BOOTOPT $QEMU_PARAMS -serial stdio | tee QemuLog.txt
index fee178a..e8b5834 100644 (file)
@@ -20,6 +20,8 @@ void  create_sidebar(void);
 void   create_mainmenu(void);
 void   create_run_dialog(void);
 void   mainmenu_run_dialog(void *unused);
+void   mainmenu_app_terminal(void *unused);
+void   mainmenu_app_textedit(void *unused);
 
 // === GLOBALS ===
 tHWND  gSidebar;
@@ -29,6 +31,7 @@ tHWND gRunDialog;
 tAxWin3_Widget *gRunInput;
  int   giScreenWidth;
  int   giScreenHeight;
+char   **gEnvion;
 
 // === CODE ===
 int systembutton_fire(tAxWin3_Widget *Widget)
@@ -38,8 +41,9 @@ int systembutton_fire(tAxWin3_Widget *Widget)
        return 0;
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *argv[], char **envp)
 {
+       gEnvion = envp;
        // Connect to AxWin3 Server
        AxWin3_Connect(NULL);
 
@@ -51,8 +55,8 @@ int main(int argc, char *argv[])
        create_run_dialog();
        
        AxWin3_RegisterAction(gSidebar, "Interface>Run", (tAxWin3_HotkeyCallback)mainmenu_run_dialog);
-//     AxWin3_RegisterAction(gSidebar, "Interface>Terminal", mainmenu_app_terminal);
-//     AxWin3_RegisterAction(gSidebar, "Interface>TextEdit", mainmenu_app_textedit);
+       AxWin3_RegisterAction(gSidebar, "Interface>Terminal", (tAxWin3_HotkeyCallback)mainmenu_app_terminal);
+       AxWin3_RegisterAction(gSidebar, "Interface>TextEdit", (tAxWin3_HotkeyCallback)mainmenu_app_textedit);
 
        // Idle loop
        AxWin3_MainLoop();
@@ -107,7 +111,9 @@ void create_sidebar(void)
 
 void mainmenu_app_textedit(void *unused)
 {
-       _SysDebug("TODO: Launch text editor");
+       const char      *args[] = {"ate",NULL};
+//     _SysDebug("TODO: Launch text editor");
+       _SysSpawn("/Acess/Apps/AxWin/3.0/ate", args, (const char **)gEnvion, 0, NULL, NULL);
 }
 
 void mainmenu_app_terminal(void *unused)
index fae6cbe..1d67450 100644 (file)
@@ -10,9 +10,10 @@ BIN := AxWinWM
 OBJ := main.o input.o video.o ipc.o image.o utf-8.o
 OBJ += wm.o wm_input.o wm_render.o wm_render_text.o wm_hotkeys.o
 OBJ += decorator.o
-OBJ += renderers/passthru.o
+OBJ += renderers/framebuffer.o
 OBJ += renderers/background.o
 OBJ += renderers/menu.o
+OBJ += renderers/richtext.o
 # TODO: Move to a lower makefile
 OBJ += renderers/widget.o
 OBJ += renderers/widget/button.o
@@ -20,6 +21,7 @@ OBJ += renderers/widget/image.o
 OBJ += renderers/widget/disptext.o
 OBJ += renderers/widget/textinput.o
 OBJ += renderers/widget/spacer.o
+OBJ += renderers/widget/subwin.o
 
 LDFLAGS += -limage_sif -luri -lnet
 
index 7807c90..e060e24 100644 (file)
@@ -24,6 +24,8 @@
 #define WINFLAG_NODECORATE     0x00000002
 //! Window takes up all of screen
 #define WINFLAG_MAXIMIZED      0x00000004
+//! Window is contained within the parent
+#define WINFLAG_RELATIVE       0x00000008
 //! Window contents are valid
 #define WINFLAG_CLEAN          0x00000040
 //! All child windows are un-changed
@@ -45,12 +47,14 @@ typedef struct sIPC_Client  tIPC_Client;
 // === FUNCTIONS ===
 // --- Management
 extern tWindow *WM_CreateWindow(tWindow *Parent, tIPC_Client *Client, uint32_t ID, int Flags, const char *Renderer);
+extern tWindow *WM_GetWindowByID(tWindow *Requester, uint32_t ID);
 extern void    WM_Invalidate(tWindow *Window);
 extern void    WM_SetWindowTitle(tWindow *Window, const char *Title);
 extern void    WM_FocusWindow(tWindow *Destination);
 extern void    WM_RaiseWindow(tWindow *Window);
 extern void    WM_ShowWindow(tWindow *Window, int bShow);
 extern void    WM_DecorateWindow(tWindow *Window, int bDecorate);
+extern void    WM_SetRelative(tWindow *Window, int bRelativeToParent);
 extern int     WM_ResizeWindow(tWindow *Window, int W, int H);
 extern int     WM_MoveWindow(tWindow *Window, int X, int Y);
 extern int     WM_SendMessage(tWindow *Source, tWindow *Dest, int MessageID, int Length, const void *Data);
index 9ab29f8..45769e8 100644 (file)
@@ -41,8 +41,9 @@ struct sWindow
 
        // Position and dimensions
         int    X, Y;
-        int    RealW, RealH;
         int    W, H;
+        int    RealX, RealY;
+        int    RealW, RealH;
 
        void    *RenderBuffer;  //!< Cached copy of the rendered window
 };
index 5882549..89aceb9 100644 (file)
@@ -52,9 +52,17 @@ struct sWMRenderer
         * \return Boolean failure (0: Handled, 1: Unhandled)
         */
         int    (*HandleMessage)(tWindow *Window, int MessageID, int Length, const void *Data);
+       
+        int    nIPCHandlers;
+       
+       /**
+        * \brief IPC Message handler
+        */
+        int    (*IPCHandlers[])(tWindow *Window, size_t Length, const void *Data);
 };
 
 extern void    WM_RegisterRenderer(tWMRenderer *Renderer);
 extern tWindow *WM_CreateWindowStruct(size_t ExtraBytes);
+extern int     WM_SendIPCReply(tWindow *Window, int Message, size_t Length, const void *Data);
 
 #endif
index 1d4ac33..2917bc9 100644 (file)
@@ -13,7 +13,8 @@
 #include <stdio.h>
 #include <wm.h>
 #include <wm_internals.h>
-#include <wm_hotkeys.h>
+#include <wm_hotkeys.h>        // Hotkey registration
+#include <wm_renderer.h>       // Renderer IPC messages
 
 #define AXWIN_PORT     4101
 
@@ -244,7 +245,6 @@ tWindow *IPC_int_GetWindow(tIPC_Client *Client, uint32_t WindowID)
                return NULL;
 
        if( WindowID >= Client->nWindows ) {
-//             _SysDebug("Window %i out of range for %p (%i)", WindowID, Client, Client->nWindows);
                return NULL;
        }
 
@@ -540,8 +540,8 @@ void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxW
        tIPC_Client     *client;
         int    rv = 0;
        
-       _SysDebug("IPC_Handle: (IPCType=%p, Ident=%p, MsgLen=%i, Msg=%p)",
-               IPCType, Ident, MsgLen, Msg);
+//     _SysDebug("IPC_Handle: (IPCType=%p, Ident=%p, MsgLen=%i, Msg=%p)",
+//             IPCType, Ident, MsgLen, Msg);
        
        if( MsgLen < sizeof(tAxWin_IPCMessage) )
                return ;
@@ -549,25 +549,53 @@ void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxW
                return ;
        
        client = IPC_int_GetClient(IPCType, Ident);
-
-       if( Msg->ID >= giIPC_NumMessageHandlers ) {
-               fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType);
-               _SysDebug("WARNING: Unknown message %i (%p)", Msg->ID, IPCType);
-               return ;
+       if( !client ) {
+               // Oops?
        }
        
-       if( !gIPC_MessageHandlers[ Msg->ID ] ) {
-               fprintf(stderr, "WARNING: Message %i does not have a handler\n", Msg->ID);
-               _SysDebug("WARNING: Message %i does not have a handler", Msg->ID);
-               return ;
+       if( Msg->Flags & IPCMSG_FLAG_RENDERER )
+       {
+               tWindow *win = IPC_int_GetWindow(client, Msg->Window);
+               if( !win ) {
+                       _SysDebug("WARNING: NULL window in message %i", Msg->ID);
+                       return ;
+               }
+               tWMRenderer     *renderer = win->Renderer;
+               if( Msg->ID >= renderer->nIPCHandlers ) {
+                       _SysDebug("WARNING: Message %i out of range in %s", Msg->ID, renderer->Name);
+                       return ;
+               }
+               if( !renderer->IPCHandlers[Msg->ID] ) {
+                       _SysDebug("WARNING: Message %i has no handler in %s", Msg->ID, renderer->Name);
+                       return ;
+               }
+               _SysDebug("IPC_Handle: Call %s-%i", renderer->Name, Msg->ID);
+               rv = renderer->IPCHandlers[Msg->ID](win, Msg->Size, Msg->Data);
+               if( rv )
+                       _SysDebug("IPC_Handle: rv != 0 (%i)", rv);
+       }
+       else
+       {
+               if( Msg->ID >= giIPC_NumMessageHandlers ) {
+                       fprintf(stderr, "WARNING: Unknown message %i (%p)\n", Msg->ID, IPCType);
+                       _SysDebug("WARNING: Unknown message %i (%p)", Msg->ID, IPCType);
+                       return ;
+               }
+               
+               if( !gIPC_MessageHandlers[ Msg->ID ] ) {
+                       fprintf(stderr, "WARNING: Message %i does not have a handler\n", Msg->ID);
+                       _SysDebug("WARNING: Message %i does not have a handler", Msg->ID);
+                       return ;
+               }
+       
+               _SysDebug("IPC_Handle: Call WM-%i", Msg->ID);
+               rv = gIPC_MessageHandlers[Msg->ID](client, Msg);
+               if( rv )
+                       _SysDebug("IPC_Handle: rv != 0 (%i)", rv);
        }
-
-       _SysDebug("IPC_Handle: Msg->ID = %i", Msg->ID);
-       rv = gIPC_MessageHandlers[Msg->ID](client, Msg);
-       _SysDebug("IPC_Handle: rv = %i", rv);
 }
 
-// --- Server->Client replies
+// Dispatch a message to the client
 void IPC_SendWMMessage(tIPC_Client *Client, uint32_t Src, uint32_t Dst, int MsgID, int Len, void *Data)
 {
        tAxWin_IPCMessage       *hdr;
@@ -590,3 +618,20 @@ void IPC_SendWMMessage(tIPC_Client *Client, uint32_t Src, uint32_t Dst, int MsgI
        Client->IPCType->SendMessage(Client->Ident, sizeof(buf), buf);
 }
 
+// --- Server->Client replies
+void IPC_SendReply(tIPC_Client *Client, uint32_t WinID, int MsgID, size_t Len, const void *Data)
+{
+       tAxWin_IPCMessage       *hdr;
+       char    buf[sizeof(*hdr)+Len];
+       
+       hdr = (void*)buf;
+       
+       hdr->ID = MsgID;
+       hdr->Flags = IPCMSG_FLAG_RENDERER;
+       hdr->Size = Len;
+       hdr->Window = WinID;
+       
+       memcpy(hdr->Data, Data, Len);
+       Client->IPCType->SendMessage(Client->Ident, sizeof(buf), buf);
+}
+
index 0996f90..7d2d391 100644 (file)
@@ -18,6 +18,7 @@ extern int    Renderer_Menu_Init(void);
 extern int     Renderer_Widget_Init(void);
 extern int     Renderer_Background_Init(void);
 extern int     Renderer_Framebuffer_Init(void);
+extern int     Renderer_RichText_Init(void);
 extern void    WM_Update(void);
 extern void    WM_Hotkey_Register(int nKeys, uint32_t *Keys, const char *ActionName);
 
@@ -45,8 +46,6 @@ const char    *gsInstallRoot = __INSTALL_ROOT;
  */
 int main(int argc, char *argv[])
 {
-        int    server_tid = gettid();
-       
        ParseCommandline(argc, argv);
        
        if( gsTerminalDevice == NULL ) {
@@ -64,6 +63,7 @@ int main(int argc, char *argv[])
        Renderer_Widget_Init();
        Renderer_Background_Init();
        Renderer_Framebuffer_Init();
+       Renderer_RichText_Init();
        WM_Initialise();
 
        // TODO: Config
@@ -72,16 +72,20 @@ int main(int argc, char *argv[])
        WM_Hotkey_Register(2, keys, "Interface>Run");
        
        // Spawn interface root
-       if( clone(CLONE_VM, 0) == 0 )
        {
+               int     server_tid = gettid();
+               _SysDebug("server_tid = %i", server_tid);
                static char csInterfaceApp[] = __INSTALL_ROOT"/AxWinUI";
                char    server_info[] = "AXWIN3_SERVER=00000";
-               char    *envp[] = {server_info, NULL};
-               char    *argv[] = {csInterfaceApp, NULL};
+               const char      *envp[] = {server_info, NULL};
+               const char      *argv[] = {csInterfaceApp, NULL};
                _SysDebug("server_tid = %i, &server_tid = %p", server_tid, &server_tid);
                sprintf(server_info, "AXWIN3_SERVER=%i", server_tid);
-               execve(csInterfaceApp, argv, envp);
-               exit(1);
+               // TODO: Does the client need FDs?
+                int    rv = _SysSpawn(csInterfaceApp, argv, envp, 0, NULL, NULL);
+               if( rv ) {
+                       _SysDebug("_SysSpawn chucked a sad, rv=%i, errno=%i", rv, _errno);
+               }
        }
 
        // Main Loop
diff --git a/Usermode/Applications/axwin3_src/WM/renderers/framebuffer.c b/Usermode/Applications/axwin3_src/WM/renderers/framebuffer.c
new file mode 100644 (file)
index 0000000..fc838cb
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Acess2 Window Manager v3
+ * - By John Hodge (thePowersGang)
+ *
+ * renderer_passthru.c
+ * - Passthrough window render (framebuffer essentially)
+ */
+#include <common.h>
+#include <wm_renderer.h>
+#include <string.h>
+#include <framebuffer_messages.h>
+#include <wm_messages.h>
+
+// === TYPES ===
+typedef struct
+{
+       short   W, H;
+       void    *Data;
+       char    _data[];
+} tFBBuffer;
+typedef struct
+{
+       tFBBuffer       BackBuffer;
+        int    MaxBufferCount;
+       tFBBuffer       *Buffers[];
+} tFBWin;
+
+// === PROTOTYPES ===
+tWindow        *Renderer_Framebuffer_Create(int Flags);
+void   Renderer_Framebuffer_Redraw(tWindow *Window);
+ int   _Handle_Commit(tWindow *Target, size_t Len, const void *Data);
+ int   _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data);
+ int   Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data);
+
+// === GLOBALS ===
+tWMRenderer    gRenderer_Framebuffer = {
+       .Name = "FrameBuffer",
+       .CreateWindow = Renderer_Framebuffer_Create,
+       .Redraw = Renderer_Framebuffer_Redraw,
+       .HandleMessage = Renderer_Framebuffer_HandleMessage,
+       .nIPCHandlers = N_IPC_FB,
+       .IPCHandlers = {
+               [IPC_FB_COMMIT] = _Handle_Commit,
+               [IPC_FB_NEWBUF] = _Handle_CreateBuf,
+       }
+};
+
+// === CODE ===
+int Renderer_Framebuffer_Init(void)
+{
+       WM_RegisterRenderer(&gRenderer_Framebuffer);
+       return 0;
+}
+
+tWindow        *Renderer_Framebuffer_Create(int Flags)
+{
+       tWindow *ret;
+       tFBWin  *info;
+       const int       max_buffers = 10;       // TODO: Have this be configurable
+       
+       ret = WM_CreateWindowStruct( sizeof(*info) + max_buffers*sizeof(tFBBuffer*) );
+       info = ret->RendererInfo;
+       
+       info->BackBuffer.W = 0;
+       info->BackBuffer.H = 0;
+       info->BackBuffer.Data = NULL;
+       info->MaxBufferCount = max_buffers;
+       memset( info->Buffers, 0, sizeof(tFBBuffer*) * max_buffers );
+       
+       return ret;
+}
+
+void Renderer_Framebuffer_Redraw(tWindow *Window)
+{
+       
+}
+
+// --- ---
+tFBBuffer *_GetBuffer(tWindow *Win, uint16_t ID)
+{
+       tFBWin  *info = Win->RendererInfo;
+       if( ID == 0xFFFF )
+               return &info->BackBuffer;
+       else if( ID >= info->MaxBufferCount )
+               return NULL;
+       else
+               return info->Buffers[ ID ];
+}
+
+void _Blit(
+       tFBBuffer *Dest, uint16_t DX, uint16_t DY,
+       const tFBBuffer *Src, uint16_t SX, uint16_t SY,
+       uint16_t W, uint16_t H
+       )
+{
+       uint32_t        *dest_data = Dest->Data;
+       const uint32_t  *src_data = Src->Data;
+       // First, some sanity
+       if( DX > Dest->W )      return ;
+       if( DY > Dest->H )      return ;
+       if( SX > Src->W )       return ;
+       if( SY > Src->H )       return ;
+       
+       if( DX + W > Dest->W )  W = Dest->W - DX;
+       if( SX + W > Src->W )   W = Src->W - SX;
+       if( DY + H > Dest->H )  H = Dest->H - DY;
+       if( SY + H > Src->H )   H = Src->H - SY;
+       
+       dest_data += (DY * Dest->W) + DX;
+       src_data  += (SY * Src->W ) + SX;
+       for( int i = 0; i < H; i ++ )
+       {
+               memcpy( dest_data, src_data, W * 4 );
+               dest_data += Dest->W;
+               src_data += Src->W;
+       }
+}
+
+void _Fill(tFBBuffer *Buf, uint16_t X, uint16_t Y, uint16_t W, uint16_t H, uint32_t Colour)
+{
+       uint32_t        *data = Buf->Data;
+       
+       if( X > Buf->W )        return ;
+       if( Y > Buf->H )        return ;
+       if( X + W > Buf->W )    W = Buf->W - X;
+       if( Y + H > Buf->H )    H = Buf->H - Y;
+       
+       data += (Y * Buf->W) + X;
+       for( int i = 0; i < H; i ++ )
+       {
+               for( int j = 0; j < W; j ++ )
+                       *data++ = Colour;
+               data += Buf->W - W;
+       }
+}
+
+// --- ---
+int _Handle_Commit(tWindow *Target, size_t Len, const void *Data)
+{
+       // Do a window invalidate
+       return 0;
+}
+
+int _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data)
+{
+       const tFBIPC_NewBuf     *msg = Data;
+       tFBBuffer       *buf;
+       tFBWin  *info = Target->RendererInfo;
+       
+       if( Len < sizeof(*msg) )        return -1;
+       
+       if( msg->Buffer == -1 || msg->Buffer >= info->MaxBufferCount ) {
+               // Can't reallocate -1
+               return 1;
+       }
+       
+       if( info->Buffers[msg->Buffer] ) {
+               free(info->Buffers[msg->Buffer]);
+               info->Buffers[msg->Buffer] = NULL;
+       }
+       
+       buf = malloc(sizeof(tFBBuffer) + msg->W * msg->H * 4);
+       buf->W = msg->W;
+       buf->H = msg->H;
+       buf->Data = buf->_data;
+       
+       info->Buffers[msg->Buffer] = buf;
+       
+       return 0;
+}
+
+int _Handle_Upload(tWindow *Target, size_t Len, const void *Data)
+{
+       const tFBIPC_Transfer   *msg = Data;
+       tFBBuffer       *dest, src;
+       
+       if( Len < sizeof(*msg) )        return -1;
+       if( Len < sizeof(*msg) + msg->W * msg->H * 4 )  return -1;
+       
+       dest = _GetBuffer(Target, msg->Buffer);
+
+       src.W = msg->W; 
+       src.H = msg->H; 
+       src.Data = (void*)msg->ImageData;
+
+       _Blit( dest, msg->X, msg->Y,  &src, 0, 0,  msg->W, msg->H );
+       return 0;
+}
+
+int _Handle_Download(tWindow *Target, size_t Len, const void *Data)
+{
+       const tFBIPC_Transfer   *msg = Data;
+       tFBBuffer       dest, *src;
+       
+       if( Len < sizeof(*msg) )        return -1;
+       
+       src = _GetBuffer(Target, msg->Buffer);
+
+       tFBIPC_Transfer *ret;
+        int    retlen = sizeof(*ret) + msg->W*msg->H*4;
+       ret = malloc( retlen );
+
+       dest.W = ret->W = msg->W;
+       dest.H = ret->H = msg->H;
+       dest.Data = ret->ImageData;
+       
+       _Blit( &dest, 0, 0,  src, msg->X, msg->Y,  msg->W, msg->H );
+
+       WM_SendIPCReply(Target, IPC_FB_DOWNLOAD, retlen, ret);
+
+       free(ret);
+
+       return 0;
+}
+
+int _Handle_LocalBlit(tWindow *Target, size_t Len, const void *Data)
+{
+       const tFBIPC_Blit       *msg = Data;
+       tFBBuffer       *dest, *src;
+       
+       if( Len < sizeof(*msg) )        return -1;
+       
+       src = _GetBuffer(Target, msg->Source);
+       dest = _GetBuffer(Target, msg->Dest);
+
+       _Blit( dest, msg->DstX, msg->DstY,  src, msg->SrcX, msg->SrcY,  msg->W, msg->H );
+       return 0;
+}
+
+int _Handle_FillRect(tWindow *Target, size_t Len, const void *Data)
+{
+       const tFBIPC_Fill       *msg = Data;
+       tFBBuffer       *dest;
+       
+       if( Len < sizeof(*msg) )        return -1;
+       
+       dest = _GetBuffer(Target, msg->Buffer);
+       
+       _Fill( dest, msg->X, msg->Y, msg->W, msg->H, msg->Colour );
+       return 0;
+}
+
+int Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
+{
+       switch(Msg)
+       {
+       case WNDMSG_RESIZE:
+               // Resize the framebuffer
+               return 1;       // Pass on
+       
+       // Messages that get passed on
+       case WNDMSG_MOUSEBTN:
+               return 1;
+       }
+       return 1;
+}
+
+
index a183de0..9d2ecea 100644 (file)
@@ -47,6 +47,8 @@ typedef struct sMenuWindowInfo
 void   Renderer_Menu_Init(void);
 tWindow        *Renderer_Menu_Create(int Argument);
 void   Renderer_Menu_Redraw(tWindow *Window);
+ int   Renderer_Menu_HandleIPC_AddItem(tWindow *Window, size_t Length, const void *Data);
+ int   Renderer_Menu_HandleIPC_SetFlags(tWindow *Window, size_t Length, const void *Data);
  int   Renderer_Menu_HandleMessage(tWindow *Window, int Msg, int Length, const void *Data);
 
 // === CONSTANTS ===
@@ -70,7 +72,12 @@ tWMRenderer  gRenderer_Menu = {
        .Name = "Menu",
        .CreateWindow = Renderer_Menu_Create,
        .Redraw = Renderer_Menu_Redraw,
-       .HandleMessage = Renderer_Menu_HandleMessage
+       .HandleMessage = Renderer_Menu_HandleMessage,
+       .nIPCHandlers = 2,
+       .IPCHandlers = {
+               Renderer_Menu_HandleIPC_AddItem,
+//             Renderer_Menu_HandleIPC_SetFlags
+       }
 };
 tFont  *gMenu_Font = NULL;     // System monospace
 
@@ -196,8 +203,9 @@ void Renderer_Menu_Redraw(tWindow *Window)
        }
 }
 
-int Renderer_Menu_int_AddItem(tWindow *Window, int Length, const tMenuMsg_AddItem *Msg)
+int Renderer_Menu_HandleIPC_AddItem(tWindow *Window, size_t Length, const void *Data)
 {
+       const tMenuIPC_AddItem  *Msg = Data;
        tMenuWindowInfo *info = Window->RendererInfo;
        tMenuItem       *item;
        
@@ -418,11 +426,6 @@ int Renderer_Menu_HandleMessage(tWindow *Window, int Msg, int Length, const void
 
                return 0; }
 
-       // Manipulation messages
-       case MSG_MENU_ADDITEM:
-//             _SysDebug("MSG_MENU_ADDITEM");
-               return Renderer_Menu_int_AddItem(Window, Length, Data);
-       
        // Only message to pass to client
        case MSG_MENU_SELECT:
                return 1;
diff --git a/Usermode/Applications/axwin3_src/WM/renderers/passthru.c b/Usermode/Applications/axwin3_src/WM/renderers/passthru.c
deleted file mode 100644 (file)
index c8d61cf..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Acess2 Window Manager v3
- * - By John Hodge (thePowersGang)
- *
- * renderer_passthru.c
- * - Passthrough window render (framebuffer essentially)
- */
-#include <common.h>
-#include <wm_renderer.h>
-#include <string.h>
-#include <framebuffer_messages.h>
-#include <wm_messages.h>
-
-// === TYPES ===
-typedef struct
-{
-       short   W, H;
-       void    *Data;
-       char    _data[];
-} tFBBuffer;
-typedef struct
-{
-       tFBBuffer       BackBuffer;
-        int    MaxBufferCount;
-       tFBBuffer       *Buffers[];
-} tFBWin;
-
-// === PROTOTYPES ===
-tWindow        *Renderer_Framebuffer_Create(int Flags);
-void   Renderer_Framebuffer_Redraw(tWindow *Window);
- int   Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data);
-
-// === GLOBALS ===
-tWMRenderer    gRenderer_Framebuffer = {
-       .Name = "FrameBuffer",
-       .CreateWindow = Renderer_Framebuffer_Create,
-       .Redraw = Renderer_Framebuffer_Redraw,
-       .HandleMessage = Renderer_Framebuffer_HandleMessage
-};
-
-// === CODE ===
-int Renderer_Framebuffer_Init(void)
-{
-       WM_RegisterRenderer(&gRenderer_Framebuffer);
-       return 0;
-}
-
-tWindow        *Renderer_Framebuffer_Create(int Flags)
-{
-       tWindow *ret;
-       tFBWin  *info;
-       const int       max_buffers = 10;       // TODO: Have this be configurable
-       
-       ret = WM_CreateWindowStruct( sizeof(*info) + max_buffers*sizeof(tFBBuffer*) );
-       info = ret->RendererInfo;
-       
-       info->BackBuffer.W = 0;
-       info->BackBuffer.H = 0;
-       info->BackBuffer.Data = NULL;
-       info->MaxBufferCount = max_buffers;
-       memset( info->Buffers, 0, sizeof(tFBBuffer*) * max_buffers );
-       
-       return ret;
-}
-
-void Renderer_Framebuffer_Redraw(tWindow *Window)
-{
-       
-}
-
-// --- ---
-tFBBuffer *_GetBuffer(tWindow *Win, uint16_t ID)
-{
-       tFBWin  *info = Win->RendererInfo;
-       if( ID == 0xFFFF )
-               return &info->BackBuffer;
-       else if( ID >= info->MaxBufferCount )
-               return NULL;
-       else
-               return info->Buffers[ ID ];
-}
-
-void _Blit(
-       tFBBuffer *Dest, uint16_t DX, uint16_t DY,
-       const tFBBuffer *Src, uint16_t SX, uint16_t SY,
-       uint16_t W, uint16_t H
-       )
-{
-       uint32_t        *dest_data = Dest->Data;
-       const uint32_t  *src_data = Src->Data;
-       // First, some sanity
-       if( DX > Dest->W )      return ;
-       if( DY > Dest->H )      return ;
-       if( SX > Src->W )       return ;
-       if( SY > Src->H )       return ;
-       
-       if( DX + W > Dest->W )  W = Dest->W - DX;
-       if( SX + W > Src->W )   W = Src->W - SX;
-       if( DY + H > Dest->H )  H = Dest->H - DY;
-       if( SY + H > Src->H )   H = Src->H - SY;
-       
-       dest_data += (DY * Dest->W) + DX;
-       src_data  += (SY * Src->W ) + SX;
-       for( int i = 0; i < H; i ++ )
-       {
-               memcpy( dest_data, src_data, W * 4 );
-               dest_data += Dest->W;
-               src_data += Src->W;
-       }
-}
-
-void _Fill(tFBBuffer *Buf, uint16_t X, uint16_t Y, uint16_t W, uint16_t H, uint32_t Colour)
-{
-       uint32_t        *data = Buf->Data;
-       
-       if( X > Buf->W )        return ;
-       if( Y > Buf->H )        return ;
-       if( X + W > Buf->W )    W = Buf->W - X;
-       if( Y + H > Buf->H )    H = Buf->H - Y;
-       
-       data += (Y * Buf->W) + X;
-       for( int i = 0; i < H; i ++ )
-       {
-               for( int j = 0; j < W; j ++ )
-                       *data++ = Colour;
-               data += Buf->W - W;
-       }
-}
-
-// --- ---
-void _Handle_Commit(tWindow *Target, size_t Len, const void *Data)
-{
-       // Do a window invalidate
-}
-
-void _Handle_CreateBuf(tWindow *Target, size_t Len, const void *Data)
-{
-       const tFBMsg_NewBuf     *msg = Data;
-       tFBBuffer       *buf;
-       tFBWin  *info = Target->RendererInfo;
-       
-       if( Len < sizeof(*msg) )        return ;
-       
-       if( msg->Buffer == -1 || msg->Buffer >= info->MaxBufferCount ) {
-               // Can't reallocate -1
-               return ;
-       }
-       
-       if( info->Buffers[msg->Buffer] ) {
-               free(info->Buffers[msg->Buffer]);
-               info->Buffers[msg->Buffer] = NULL;
-       }
-       
-       buf = malloc(sizeof(tFBBuffer) + msg->W * msg->H * 4);
-       buf->W = msg->W;
-       buf->H = msg->H;
-       buf->Data = buf->_data;
-       
-       info->Buffers[msg->Buffer] = buf;
-}
-
-void _Handle_Upload(tWindow *Target, size_t Len, const void *Data)
-{
-       const tFBMsg_Transfer   *msg = Data;
-       tFBBuffer       *dest, src;
-       
-       if( Len < sizeof(*msg) )        return ;
-       if( Len < sizeof(*msg) + msg->W * msg->H * 4 )  return ;
-       
-       dest = _GetBuffer(Target, msg->Buffer);
-
-       src.W = msg->W; 
-       src.H = msg->H; 
-       src.Data = (void*)msg->ImageData;
-
-       _Blit( dest, msg->X, msg->Y,  &src, 0, 0,  msg->W, msg->H );
-}
-
-void _Handle_Download(tWindow *Target, size_t Len, const void *Data)
-{
-       #if 0
-       const tFBMsg_Transfer   *msg = Data;
-       tFBBuffer       dest, *src;
-       
-       if( Len < sizeof(*msg) )        return ;
-       if( Len < sizeof(*msg) + msg->W * msg->H * 4 )  return ;
-       
-       src = _GetBuffer(Target, msg->Buffer);
-
-       dest.W = msg->W;        
-       dest.H = msg->H;        
-       dest.Data = msg->ImageData;
-       
-       _Blit( &dest, 0, 0,  src, msg->X, msg->Y,  msg->W, msg->H );
-       #endif
-}
-
-void _Handle_LocalBlit(tWindow *Target, size_t Len, const void *Data)
-{
-       const tFBMsg_Blit       *msg = Data;
-       tFBBuffer       *dest, *src;
-       
-       if( Len < sizeof(*msg) )        return ;
-       
-       src = _GetBuffer(Target, msg->Source);
-       dest = _GetBuffer(Target, msg->Dest);
-
-       _Blit( dest, msg->DstX, msg->DstY,  src, msg->SrcX, msg->SrcY,  msg->W, msg->H );
-}
-
-void _Handle_FillRect(tWindow *Target, size_t Len, const void *Data)
-{
-       const tFBMsg_Fill       *msg = Data;
-       tFBBuffer       *dest;
-       
-       if( Len < sizeof(*msg) )        return ;
-       
-       dest = _GetBuffer(Target, msg->Buffer);
-       
-       _Fill( dest, msg->X, msg->Y, msg->W, msg->H, msg->Colour );
-}
-
-int Renderer_Framebuffer_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
-{
-       switch(Msg)
-       {
-       case WNDMSG_RESIZE:
-               // Resize the framebuffer
-               return 1;       // Pass on
-       
-       // Messages that get passed on
-       case WNDMSG_MOUSEBTN:
-               return 1;
-       
-       // --- Local messages ---
-       // - Drawing completed, do an update
-       case MSG_FB_COMMIT:
-               _Handle_Commit(Target, Len, Data);
-               return 0;
-       // - New Buffer (create a new server-side buffer)
-       case MSG_FB_NEWBUF:
-               _Handle_CreateBuf(Target, Len, Data);
-               return 0;
-       // - Upload (Transfer data from client to server)
-       case MSG_FB_UPLOAD:
-               _Handle_Upload(Target, Len, Data);
-               return 0;
-       // - Download (Transfer image data from server to client)
-       case MSG_FB_DOWNLOAD:
-               _Handle_Download(Target, Len, Data);
-               return 0;
-       // - Local Blit (Transfer from server to server)
-       case MSG_FB_BLIT:
-               _Handle_LocalBlit(Target, Len, Data);
-               return 0;
-       // - Fill a rectangle
-       case MSG_FB_FILL:
-               _Handle_FillRect(Target, Len, Data);
-               return 0;
-       }
-       return 1;
-}
-
-
diff --git a/Usermode/Applications/axwin3_src/WM/renderers/richtext.c b/Usermode/Applications/axwin3_src/WM/renderers/richtext.c
new file mode 100644 (file)
index 0000000..28be1ae
--- /dev/null
@@ -0,0 +1,317 @@
+/*
+ * Acess2 Window Manager v3
+ * - By John Hodge (thePowersGang)
+ *
+ * render/richtext.c
+ * - Formatted Line Editor
+ */
+#include <common.h>
+#include <wm_renderer.h>
+#include <wm_messages.h>
+#include <richtext_messages.h>
+#include <stdio.h>     // sscanf
+#include <string.h>    // memcpy
+
+#define LINES_PER_BLOCK        30
+
+// === TYPES ===
+typedef struct sRichText_Line
+{
+       struct sRichText_Line   *Next;
+       struct sRichText_Line   *Prev;
+        int    Num;
+       // TODO: Pre-rendered cache?
+       short   ByteLength;
+       short   Space;
+       char    Data[];
+} tRichText_Line;
+typedef struct sRichText_Window
+{
+        int    DispLines, DispCols;
+        int    FirstVisRow, FirstVisCol;
+        int    nLines, nCols;
+        int    CursorRow, CursorCol;
+       tRichText_Line  *FirstLine;
+       tRichText_Line  *FirstVisLine;
+       tColour DefaultFG;
+       tColour DefaultBG;
+       tFont   *Font;
+       
+       short   LineHeight;
+} tRichText_Window;
+
+// === PROTOTYPES ===
+ int   Renderer_RichText_Init(void);
+tWindow        *Renderer_RichText_Create(int Flags);
+void   Renderer_RichText_Redraw(tWindow *Window);
+ int   Renderer_RichText_HandleIPC_SetAttr(tWindow *Window, size_t Len, const void *Data);
+ int   Renderer_RichText_HandleIPC_WriteLine(tWindow *Window, size_t Len, const void *Data);
+ int   Renderer_RichText_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data);
+
+// === GLOBALS ===
+tWMRenderer    gRenderer_RichText = {
+       .Name = "RichText",
+       .CreateWindow   = Renderer_RichText_Create,
+       .Redraw         = Renderer_RichText_Redraw,
+       .HandleMessage  = Renderer_RichText_HandleMessage,
+       .nIPCHandlers = N_IPC_RICHTEXT,
+       .IPCHandlers = {
+               [IPC_RICHTEXT_SETATTR] = Renderer_RichText_HandleIPC_SetAttr,
+               [IPC_RICHTEXT_WRITELINE] = Renderer_RichText_HandleIPC_WriteLine
+       }
+};
+
+// === CODE ===
+int Renderer_RichText_Init(void)
+{
+       WM_RegisterRenderer(&gRenderer_RichText);       
+       return 0;
+}
+
+tWindow *Renderer_RichText_Create(int Flags)
+{
+       tRichText_Window        *info;
+       tWindow *ret = WM_CreateWindowStruct( sizeof(*info) );
+       if(!ret)        return NULL;
+       info = ret->RendererInfo;
+       
+       // Initialise font (get an idea of dimensions)
+       int h;
+       WM_Render_GetTextDims(NULL, "yY!", 3, NULL, &h);
+       info->LineHeight = h;
+       
+       return ret;
+}
+
+static inline int Renderer_RichText_RenderText_Act(tWindow *Window, tRichText_Window *info, int X, int Row, const char *Text, int Bytes, tColour FG, tColour BG, int Flags)
+{
+        int    rwidth;
+       // TODO: Fill only what is needed? What about the rest of the line?
+       WM_Render_DrawRect(Window, X, Row*info->LineHeight,
+               Window->W - X, info->LineHeight,
+               BG
+               );
+       // TODO: Bold, Italic, Underline
+       rwidth = WM_Render_DrawText(Window,
+               X, Row*info->LineHeight,
+               Window->W - X, info->LineHeight,
+               info->Font, FG,
+               Text, Bytes
+               );
+       return rwidth;
+}
+
+void Renderer_RichText_RenderText(tWindow *Window, int Line, const char *Text)
+{
+       tRichText_Window        *info = Window->RendererInfo;
+       tColour fg = info->DefaultFG;
+       tColour bg = info->DefaultBG;
+        int    flagset = 0;
+        int    bRender = 0;
+        int    curx = 0;
+       const char      *oldtext = Text;
+       
+       for( int i = 0; curx < Window->W; i ++ )
+       {
+               char    ch, flags;
+                int    len;
+
+               if( i == info->FirstVisCol )
+                       bRender = 1;
+
+               ch = *Text++;
+               if( ch == 0 )   break;
+
+               // Not an escape - move along
+               if( ch > 4 )
+                       continue ;              
+
+               if( bRender ) {
+                       // Render previous characters
+                       curx += Renderer_RichText_RenderText_Act(Window, info, curx, Line,
+                               oldtext, Text - oldtext - 1, fg, bg, flagset);
+                       if( curx >= Window->W )
+                               break;
+               }
+               oldtext = Text;
+               switch(ch)
+               {
+               case 1: // FG Select (\1 RRGGBB)
+                       if( sscanf(Text, "%6x%n", &fg, &len) != 1 || len != 6 ) {
+                               // Bad client
+                               _SysDebug("foreground scanf failed - len=%i", len);
+                               len = 0;
+                       }
+                       Text += len;
+                       oldtext = Text;
+                       _SysDebug("FG update to %x", fg);
+                       break ;
+               case 2: // BG Select (\2 RRGGBB)
+                       if( sscanf(Text, "%6x%n", &bg, &len) != 1 || len != 6 ) {
+                               // Bad client
+                               _SysDebug("background scanf failed - len=%i", len);
+                               len = 0;
+                       }
+                       Text += len;
+                       oldtext = Text;
+                       _SysDebug("BG update to %x", bg);
+                       break ;
+               case 3: // Flagset (0,it,uline,bold)
+                       if( sscanf(Text, "%1hhx%n", &flags, &len) != 1 || len != 1 ) {
+                               // Bad client
+                               _SysDebug("Flagset scanf failed - len=%i", len);
+                       }
+                       flagset = flags & 7;
+                       Text += len;
+                       oldtext = Text;
+                       break ;
+               case 4: // Escape (do nothing)
+                       Text ++;
+                       // NOTE: No update to oldtext
+                       break;
+               default: // Error.
+                       break;
+               }
+       }
+       curx += Renderer_RichText_RenderText_Act(Window, info, curx,
+               Line, oldtext, Text - oldtext + 1, fg, bg, flagset);
+       WM_Render_DrawRect(Window, curx, Line * info->LineHeight,
+               Window->W - curx, info->LineHeight, info->DefaultBG);
+}
+
+void Renderer_RichText_Redraw(tWindow *Window)
+{
+       tRichText_Window        *info = Window->RendererInfo;
+        int    i;
+       tRichText_Line  *line = info->FirstVisLine;
+       
+       if( !line ) {
+               line = info->FirstLine;
+               while(line && line->Num < info->FirstVisRow )
+                       line = line->Next;
+               info->FirstVisLine = line;
+       }
+       while( line && line->Prev && line->Prev->Num > info->FirstVisRow )
+               line = line->Prev;
+
+       for( i = 0; i < info->DispLines && line; i ++ )
+       {
+               if( i >= info->nLines - info->FirstVisRow )
+                       break;
+               // TODO: Dirty rectangles?
+               WM_Render_FillRect(Window,
+                       0, i*info->LineHeight,
+                       Window->W, info->LineHeight,
+                       info->DefaultBG
+                       );
+               if( line->Num > info->FirstVisRow + i )
+                       continue ;
+               // TODO: Horizontal scrolling?
+               // TODO: Formatting
+               
+               // Formatted text out
+               Renderer_RichText_RenderText(Window, i, line->Data);
+               _SysDebug("RichText: %p - Render %i '%.*s'", Window,
+                       line->Num, line->ByteLength, line->Data);
+
+               line = line->Next;
+       }
+       // Clear out i -- info->DispLines
+       _SysDebug("RichText: %p - Clear %i px lines with %06x starting at %i",
+               Window, (info->DispLines-i)*info->LineHeight, info->DefaultBG, i*info->LineHeight);
+       WM_Render_FillRect(Window,
+               0, i*info->LineHeight,
+               Window->W, (info->DispLines-i)*info->LineHeight,
+               info->DefaultBG
+               );
+}
+
+int Renderer_RichText_HandleIPC_SetAttr(tWindow *Window, size_t Len, const void *Data)
+{
+       tRichText_Window        *info = Window->RendererInfo;
+       const struct sRichTextIPC_SetAttr *msg = Data;
+       if(Len < sizeof(*msg))  return -1;
+
+       _SysDebug("RichText Attr %i set to %x", msg->Attr, msg->Value);
+       switch(msg->Attr)
+       {
+       case _ATTR_DEFBG:
+               info->DefaultBG = msg->Value;
+               break;
+       case _ATTR_DEFFG:
+               info->DefaultFG = msg->Value;
+               break;
+       case _ATTR_SCROLL:
+               // TODO: Set scroll flag
+               break;
+       case _ATTR_LINECOUNT:
+               info->nLines = msg->Value;
+               break;
+       }
+       
+       return 0;
+}
+
+int Renderer_RichText_HandleIPC_WriteLine(tWindow *Window, size_t Len, const void *Data)
+{
+       tRichText_Window        *info = Window->RendererInfo;
+       const struct sRichTextIPC_WriteLine     *msg = Data;
+       if( Len < sizeof(*msg) )        return -1;
+       if( msg->Line >= info->nLines ) return 1;       // Bad count
+
+       tRichText_Line  *line = info->FirstLine;
+       tRichText_Line  *prev = NULL;
+       while(line && line->Num < msg->Line)
+               prev = line, line = line->Next;
+       if( !line || line->Num > msg->Line )
+       {
+               // New line!
+               // Round up to 32
+                int    space = ((Len - sizeof(*msg)) + 32-1) & ~(32-1);
+               tRichText_Line  *new = malloc(sizeof(*line) + space);
+               // TODO: Bookkeeping on how much memory each window uses
+               new->Next = line;
+               new->Prev = prev;
+               new->Num = msg->Line;
+               new->Space = space;
+               if(new->Prev)   new->Prev->Next = new;
+               else    info->FirstLine = new;
+               if(new->Next)   new->Next->Prev = new;
+               line = new;
+       }
+       else if( line->Space < Len - sizeof(*msg) )
+       {
+               // Need to allocate more space
+                int    space = ((Len - sizeof(*msg)) + 32-1) & ~(32-1);
+               tRichText_Line *new = realloc(line, space);
+               // TODO: Bookkeeping on how much memory each window uses
+               new->Space = space;
+
+               if(new->Prev)   new->Prev->Next = new;
+               else    info->FirstLine = new;
+               if(new->Next)   new->Next->Prev = new;
+               line = new;
+       }
+       else
+       {
+               // It fits :)
+       }
+       line->ByteLength = Len - sizeof(*msg);
+       memcpy(line->Data, msg->LineData, Len - sizeof(*msg));
+       
+       return  0;
+}
+
+int Renderer_RichText_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
+{
+       tRichText_Window        *info = Target->RendererInfo;
+       switch(Msg)
+       {
+       case WNDMSG_RESIZE: {
+               const struct sWndMsg_Resize *msg = Data;
+               if(Len < sizeof(*msg))  return -1;
+               info->DispLines = msg->H / info->LineHeight;
+               return 1; }
+       }
+       return 0;
+}
index 46b3198..49f1f64 100644 (file)
@@ -26,10 +26,15 @@ void        Widget_UpdateDimensions(tElement *Element);
 void   Widget_UpdatePosition(tElement *Element);
 // --- Messages
 tElement       *Widget_GetElementById(tWidgetWin *Info, uint32_t ID);
-void   Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg);
-void   Widget_SetFlags(tWidgetWin *Info, int Len, const tWidgetMsg_SetFlags *Msg);
-void   Widget_SetSize(tWidgetWin *Info, int Len, const tWidgetMsg_SetSize *Msg);
-void   Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg);
+ int   Widget_IPC_Create(tWindow *Win, size_t Len, const void *Data);
+ int   Widget_IPC_NewWidgetSubwin(tWindow *Win, size_t Len, const void *Data);
+// int Widget_IPC_Delete(tWindow *Win, size_t Len, const void *Data);
+ int   Widget_IPC_SetFocus(tWindow *Win, size_t Len, const void *Data);
+ int   Widget_IPC_SetFlags(tWindow *Win, size_t Len, const void *Data);
+ int   Widget_IPC_SetSize(tWindow *Win, size_t Len, const void *Data);
+ int   Widget_IPC_SetText(tWindow *Win, size_t Len, const void *Data);
+ int   Widget_IPC_GetText(tWindow *Win, size_t Len, const void *Data);
+// int Widget_IPC_SetColour(tWindow *Win, size_t Len, const void *Data);
  int   Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data);
 
 // === GLOBALS ===
@@ -37,7 +42,17 @@ tWMRenderer  gRenderer_Widget = {
        .Name = "Widget",
        .CreateWindow = Renderer_Widget_Create,
        .Redraw = Renderer_Widget_Redraw,
-       .HandleMessage = Renderer_Widget_HandleMessage
+       .HandleMessage = Renderer_Widget_HandleMessage,
+       .nIPCHandlers = N_IPC_WIDGET,
+       .IPCHandlers = {
+               [IPC_WIDGET_CREATE] = Widget_IPC_Create,
+               [IPC_WIDGET_CREATESUBWIN] = Widget_IPC_NewWidgetSubwin,
+               [IPC_WIDGET_SETFOCUS] = Widget_IPC_SetFocus,
+               [IPC_WIDGET_SETFLAGS] = Widget_IPC_SetFlags,
+               [IPC_WIDGET_SETSIZE] = Widget_IPC_SetSize,
+               [IPC_WIDGET_SETTEXT] = Widget_IPC_SetText,
+               [IPC_WIDGET_GETTEXT] = Widget_IPC_GetText,
+       }
 };
        
 // --- Element callbacks
@@ -87,7 +102,7 @@ tWindow      *Renderer_Widget_Create(int Flags)
        tWidgetWin      *info;
         int    eletable_size = DEFAULT_ELETABLE_SIZE;
 
-       _SysDebug("Renderer_Widget_Create: (Flags = 0x%x)", Flags);
+       //_SysDebug("Renderer_Widget_Create: (Flags = 0x%x)", Flags);
 
        // TODO: Use `Flags` as default element count?
        // - Actaully, it's taken by the root ele flags
@@ -214,14 +229,14 @@ void Widget_UpdateDimensions(tElement *Element)
        else
                fullCross = Element->CachedH - Element->PaddingT - Element->PaddingB;
 
-       _SysDebug("%i (p=%i) - WxH=%ix%i",
-               Element->ID, (Element->Parent ? Element->Parent->ID : -1),
-               Element->CachedW, Element->CachedH
-               );
-       _SysDebug("  %s dynWith = %i, fullCross = %i",
-               (Element->Flags & ELEFLAG_VERTICAL ? "Vert" : "Horiz"),
-               dynWith, fullCross
-               );
+       //_SysDebug("%i (p=%i) - WxH=%ix%i",
+       //      Element->ID, (Element->Parent ? Element->Parent->ID : -1),
+       //      Element->CachedW, Element->CachedH
+       //      );
+       //_SysDebug("  %s dynWith = %i, fullCross = %i",
+       //      (Element->Flags & ELEFLAG_VERTICAL ? "Vert" : "Horiz"),
+       //      dynWith, fullCross
+       //      );
        
        // Pass 2 - Set sizes and recurse
        for( child = Element->FirstChild; child; child = child->NextSibling )
@@ -423,61 +438,33 @@ tElement *Widget_GetElementById(tWidgetWin *Info, uint32_t ID)
        return ele;
 }
 
-// --- Message Handlers ---
-void Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg)
+tElement *Widget_int_Create(tWidgetWin *Info, tElement *Parent, int ID, int Type, int Flags)
 {
-       const int       max_debugname_len = Len - sizeof(tWidgetMsg_Create);
-       tElement        *parent, *new;
-
-       // Sanity check
-       if( Len < sizeof(*Msg) )
-               return ;
-       if( strnlen(Msg->DebugName, max_debugname_len) == max_debugname_len )
-               return ;
-       
-       _SysDebug("Widget_NewWidget (%i %i Type %i Flags 0x%x)",
-               Msg->Parent, Msg->NewID, Msg->Type, Msg->Flags);
-       
-       if(Msg->Type >= ciWM_NumWidgetTypes)
-       {
-               _SysDebug("Widget_NewWidget - Bad widget type %i", Msg->Type);
-               return ;
-       }
-
-       // Create
-       parent = Widget_GetElementById(Info, Msg->Parent);
-       if(!parent)
-       {
-               _SysDebug("Widget_NewWidget - Bad parent ID %i", Msg->Parent);
-               return ;
-       }
-
-       // Check if the ID is already in use
-       if( Widget_GetElementById(Info, Msg->NewID) )
-               return ;
+       if( Widget_GetElementById(Info, ID) )
+               return NULL;
 
        // Create new element
-       new = calloc(sizeof(tElement), 1);
-       new->Window = parent->Window;
-       new->ID = Msg->NewID;
-       new->Type = Msg->Type;
-       new->Parent = parent;
-       new->Flags = Msg->Flags;
+       tElement *new = calloc(sizeof(tElement), 1);
+       new->Window = Parent->Window;
+       new->ID = ID;
+       new->Type = Type;
+       new->Parent = Parent;
+       new->Flags = Flags;
        new->PaddingT = 2;
        new->PaddingB = 2;
        new->PaddingL = 2;
        new->PaddingR = 2;
        new->CachedX = -1;
        
-       if( gaWM_WidgetTypes[new->Type]->Init )
-               gaWM_WidgetTypes[new->Type]->Init(new);
+       if( gaWM_WidgetTypes[Type]->Init )
+               gaWM_WidgetTypes[Type]->Init(new);
        
        // Add to parent's list
-       if(parent->LastChild)
-               parent->LastChild->NextSibling = new;
+       if(Parent->LastChild)
+               Parent->LastChild->NextSibling = new;
        else
-               parent->FirstChild = new;
-       parent->LastChild = new;
+               Parent->FirstChild = new;
+       Parent->LastChild = new;
 
        // Add to info
        {
@@ -488,8 +475,8 @@ void Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg
                else
                        Info->ElementTable[new->ID % Info->TableSize] = new;
        }
-
-       Widget_UpdateMinDims(parent);
+       
+       return new;
 }
 
 void Widget_SetFocus(tWidgetWin *Info, tElement *Ele)
@@ -499,47 +486,130 @@ void Widget_SetFocus(tWidgetWin *Info, tElement *Ele)
        Info->FocusedElement = Ele;
 }
 
-void Widget_SetFlags(tWidgetWin *Info, int Len, const tWidgetMsg_SetFlags *Msg)
+
+// --- Message Handlers ---
+int Widget_IPC_Create(tWindow *Win, size_t Len, const void *Data)
+{
+       tWidgetWin      *Info = Win->RendererInfo;
+       const tWidgetIPC_Create *Msg = Data;
+       const int       max_debugname_len = Len - sizeof(*Msg);
+       tElement        *parent;
+
+       // Sanity check
+       if( Len < sizeof(*Msg) )
+               return -1;
+       if( strnlen(Msg->DebugName, max_debugname_len) == max_debugname_len )
+               return -1;
+       
+       _SysDebug("Widget_NewWidget (%i %i Type %i Flags 0x%x)",
+               Msg->Parent, Msg->NewID, Msg->Type, Msg->Flags);
+       
+       if(Msg->Type >= ciWM_NumWidgetTypes)
+       {
+               _SysDebug("Widget_NewWidget - Bad widget type %i", Msg->Type);
+               return 1;
+       }
+
+       // Create
+       parent = Widget_GetElementById(Info, Msg->Parent);
+       if(!parent)
+       {
+               _SysDebug("Widget_NewWidget - Bad parent ID %i", Msg->Parent);
+               return 1;
+       }
+
+       Widget_int_Create(Info, parent, Msg->NewID, Msg->Type, Msg->Flags);
+
+       Widget_UpdateMinDims(parent);
+       return 0;
+}
+
+int Widget_IPC_NewWidgetSubwin(tWindow *Win, size_t Len, const void *Data)
+{
+       tWidgetWin      *Info = Win->RendererInfo;
+       const tWidgetIPC_CreateSubWin   *Msg = Data;
+       const int       max_debugname_len = Len - sizeof(*Msg);
+       tElement        *parent, *new;
+
+       // Sanity check
+       if( Len < sizeof(*Msg) )
+               return -1;
+       if( strnlen(Msg->DebugName, max_debugname_len) == max_debugname_len )
+               return -1;
+       
+       parent = Widget_GetElementById(Info, Msg->Parent);
+       if(!parent)     return 1;
+       if( Widget_GetElementById(Info, Msg->NewID) )   return 1;
+       
+       new = Widget_int_Create(Info, parent, Msg->NewID, Msg->Type, Msg->Flags);
+       new->Data = WM_GetWindowByID(parent->Window, Msg->WindowHandle);
+       Widget_UpdateMinDims(parent);
+       return 0;
+}
+
+// TODO: Widget_IPC_Delete
+
+int Widget_IPC_SetFocus(tWindow *Win, size_t Len, const void *Data)
+{
+       tWidgetWin      *info = Win->RendererInfo;
+       tElement        *ele;
+       const tWidgetIPC_SetFocus       *msg = Data;
+       if(Len < sizeof(*msg))  return -1;
+       
+       ele = Widget_GetElementById(info, msg->WidgetID);
+       Widget_SetFocus(info, ele);
+       return 0;
+}
+
+int Widget_IPC_SetFlags(tWindow *Win, size_t Len, const void *Data)
 {
+       tWidgetWin *Info = Win->RendererInfo;
+       const tWidgetIPC_SetFlags       *Msg = Data;
        tElement        *ele;
        
        if( Len < sizeof(*Msg) )
-               return ;
+               return -1;
 
        _SysDebug("Widget_SetFlags: (%i 0x%x 0x%x)", Msg->WidgetID, Msg->Value, Msg->Mask);
        
        ele = Widget_GetElementById(Info, Msg->WidgetID);
-       if(!ele)        return;
+       if(!ele)        return 1;
 
        ele->Flags &= ~Msg->Mask;
        ele->Flags |= Msg->Value & Msg->Mask;
+       
+       return 0;
 }
 
-void Widget_SetSize(tWidgetWin *Info, int Len, const tWidgetMsg_SetSize *Msg)
+int Widget_IPC_SetSize(tWindow *Win, size_t Len, const void *Data)
 {
+       tWidgetWin      *Info = Win->RendererInfo;
+       const tWidgetIPC_SetSize        *Msg = Data;
        tElement        *ele;
        
        if( Len < sizeof(*Msg) )
-               return ;
+               return -1;
        
        ele = Widget_GetElementById(Info, Msg->WidgetID);
-       if(!ele)        return ;
+       if(!ele)        return 1;
        
        ele->FixedWith = Msg->Value;
+       return 0;
 }
 
-void Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg)
+int Widget_IPC_SetText(tWindow *Win, size_t Len, const void *Data)
 {
+       tWidgetWin      *Info = Win->RendererInfo;
+       const tWidgetIPC_SetText        *Msg = Data;
        tElement        *ele;
        
        if( Len < sizeof(*Msg) + 1 )
-               return ;
+               return -1;
        if( Msg->Text[Len - sizeof(*Msg) - 1] != '\0' )
-               return ;
+               return -1;
 
        ele = Widget_GetElementById(Info, Msg->WidgetID);
-       if(!ele)        return ;
-
+       if(!ele)        return 1;
 
        if( gaWM_WidgetTypes[ele->Type]->UpdateText )
        {
@@ -550,22 +620,23 @@ void Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg)
 //             if(ele->Text)   free(ele->Text);
 //             ele->Text = strdup(Msg->Text);
 //     }
+       return 0;
 }
 
-int Widget_GetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg)
+int Widget_IPC_GetText(tWindow *Win, size_t Len, const void *Data)
 {
+       tWidgetWin      *Info = Win->RendererInfo;
+       const tWidgetIPC_SetText        *Msg = Data;
        if( Len < sizeof(*Msg) )
-               return 0;
-       if( Len > sizeof(*Msg) )
-               return 1;       // Pass to user
+               return -1;
        
        const char      *text = NULL;
        tElement *ele = Widget_GetElementById(Info, Msg->WidgetID);
        if(ele)
                text = ele->Text;
        
-       char    buf[sizeof(tWidgetMsg_SetText) + strlen(text?text:"") + 1];
-       tWidgetMsg_SetText      *omsg = (void*)buf;
+       char    buf[sizeof(tWidgetIPC_SetText) + strlen(text?text:"") + 1];
+       tWidgetIPC_SetText      *omsg = (void*)buf;
        
        if( text ) {
                omsg->WidgetID = Msg->WidgetID;
@@ -576,7 +647,7 @@ int Widget_GetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg)
                omsg->Text[0] = 0;
        }
        
-       WM_SendMessage(Info->RootElement.Window, Info->RootElement.Window, MSG_WIDGET_GETTEXT, sizeof(buf), buf);
+       WM_SendIPCReply(Win, IPC_WIDGET_GETTEXT, sizeof(buf), buf);
        return 0;
 }
 
@@ -685,43 +756,6 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void
                }
                return 0; }
 
-       // New Widget
-       case MSG_WIDGET_CREATE:
-               Widget_NewWidget(info, Len, Data);
-               return 0;
-
-       // Delete a widget
-       case MSG_WIDGET_DELETE:
-               _SysDebug("TODO: Implement MSG_WIDGET_DELETE");
-               return 0;
-
-       // Set focused widget
-       case MSG_WIDGET_SETFOCUS: {
-               tElement        *ele;
-               const tWidgetMsg_SetFocus       *msg = Data;
-               if(Len < sizeof(*msg))  return -1;
-               
-               ele = Widget_GetElementById(info, msg->WidgetID);
-               Widget_SetFocus(info, ele);
-               return 0; }
-
-       // Set Flags
-       case MSG_WIDGET_SETFLAGS:
-               Widget_SetFlags(info, Len, Data);
-               return 0;
-       
-       // Set length
-       case MSG_WIDGET_SETSIZE:
-               Widget_SetSize(info, Len, Data);
-               return 0;
-       
-       // Set text
-       case MSG_WIDGET_SETTEXT:
-               Widget_SetText(info, Len, Data);
-               return 0;
-       case MSG_WIDGET_GETTEXT:
-               return Widget_GetText(info, Len, Data);
-       
        // 
        default:
                return 1;       // Unhandled, pass to user
@@ -732,6 +766,7 @@ void Widget_Fire(tElement *Element)
 {
        tWidgetMsg_Fire msg;
        msg.WidgetID = Element->ID;
+       _SysDebug("Widget_Fire: Fire on %p %i", Element->Window, Element->ID);
        WM_SendMessage(Element->Window, Element->Window, MSG_WIDGET_FIRE, sizeof(msg), &msg);
 }
 
diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget/subwin.c b/Usermode/Applications/axwin3_src/WM/renderers/widget/subwin.c
new file mode 100644 (file)
index 0000000..fcf196d
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Acess2 Window Manager v3
+ * - By John Hodge (thePowersGang)
+ * 
+ * renderer/widget/subwin.c
+ * - Embedded Window Widget Type
+ */
+#include <common.h>
+#include "./common.h"
+#include "./colours.h"
+
+void Widget_SubWin_Render(tWindow *Window, tElement *Element)
+{
+       // Ensure that child window is positioned relative to this window
+       WM_SetRelative(Element->Data, 1);
+       // Note: Doesn't actually render, but does poke the child window
+       WM_MoveWindow(Element->Data, Element->CachedX, Element->CachedY);
+       WM_ResizeWindow(Element->Data, Element->CachedW, Element->CachedH);
+}
+
+DEFWIDGETTYPE(ELETYPE_SUBWIN,
+       WIDGETTYPE_FLAG_NOCHILDREN,
+       .Render = Widget_SubWin_Render
+       )
index 3adb17d..3916baa 100644 (file)
@@ -88,7 +88,7 @@ void Video_Update(void)
        _SysDebug("Video_Update - Updating lines %i to %i (0x%x+0x%x px)",
                giVideo_FirstDirtyLine, giVideo_LastDirtyLine, ofs, size);
        seek(giTerminalFD, ofs*4, 1);
-       _SysDebug("Video_Update - Sending");
+       _SysDebug("Video_Update - Sending FD %i %p 0x%x", giTerminalFD, gpScreenBuffer+ofs, size*4);
        write(giTerminalFD, gpScreenBuffer+ofs, size*4);
        _SysDebug("Video_Update - Done");
        giVideo_FirstDirtyLine = 0;
@@ -140,7 +140,7 @@ void Video_Blit(uint32_t *Source, short DstX, short DstY, short W, short H)
        // TODO: Handle out of bounds by clipping too
        if( DstX + W > giScreenWidth )  return;
        if( DstY + H > giScreenHeight )
-               H = giScreenWidth - DstY;
+               H = giScreenHeight - DstY;
 
        if( W <= 0 || H <= 0 )  return;
 
index 2478151..464eeb1 100644 (file)
@@ -15,6 +15,8 @@
 
 // === IMPORTS ===
 extern void    IPC_SendWMMessage(tIPC_Client *Client, uint32_t Src, uint32_t Dst, int Msg, int Len, const void *Data);
+extern void    IPC_SendReply(tIPC_Client *Client, uint32_t WinID, int MsgID, size_t Len, const void *Data);
+extern tWindow *IPC_int_GetWindow(tIPC_Client *Client, uint32_t ID);
 
 // === GLOBALS ===
 tWMRenderer    *gpWM_Renderers;
@@ -92,6 +94,11 @@ tWindow *WM_CreateWindow(tWindow *Parent, tIPC_Client *Client, uint32_t ID, int
        return ret;
 }
 
+tWindow *WM_GetWindowByID(tWindow *Requester, uint32_t ID)
+{
+       return IPC_int_GetWindow(Requester->Client, ID);
+}
+
 tWindow *WM_CreateWindowStruct(size_t ExtraSize)
 {
        tWindow *ret;
@@ -144,11 +151,17 @@ void WM_FocusWindow(tWindow *Destination)
        if( Destination && !(Destination->Flags & WINFLAG_SHOW) )
                return ;
        
-       _msg.Val = 0;
-       WM_SendMessage(NULL, gpWM_FocusedWindow, WNDMSG_FOCUS, sizeof(_msg), &_msg);
-       _msg.Val = 1;
-       WM_SendMessage(NULL, Destination, WNDMSG_FOCUS, sizeof(_msg), &_msg);
-       
+       if( gpWM_FocusedWindow )
+       {
+               _msg.Val = 0;
+               WM_SendMessage(NULL, gpWM_FocusedWindow, WNDMSG_FOCUS, sizeof(_msg), &_msg);
+       }
+       if( Destination )
+       {
+               _msg.Val = 1;
+               WM_SendMessage(NULL, Destination, WNDMSG_FOCUS, sizeof(_msg), &_msg);
+       }
+               
        WM_Invalidate(gpWM_FocusedWindow);
        WM_Invalidate(Destination);
        gpWM_FocusedWindow = Destination;
@@ -210,16 +223,49 @@ void WM_DecorateWindow(tWindow *Window, int bDecorate)
        WM_Invalidate(Window);
 }
 
+void WM_SetRelative(tWindow *Window, int bRelativeToParent)
+{
+//     _SysDebug("WM_SetRelative: (%p{Parent=%p},%i)", Window, Window->Parent, bRelativeToParent);
+       // No meaning if no parent
+       if( !Window->Parent )
+               return ;
+
+       // Check that the flag is changing
+       if( !!bRelativeToParent == !!(Window->Flags & WINFLAG_RELATIVE) )
+               return ;
+
+       if( bRelativeToParent ) {
+               // Set
+               Window->Flags |= WINFLAG_RELATIVE;
+               WM_MoveWindow(Window, Window->X, Window->Y);
+       }
+       else {
+               // Clear
+               Window->Flags &= ~WINFLAG_RELATIVE;
+               WM_MoveWindow(Window, Window->X - Window->Parent->X, Window->Y - Window->Parent->Y);
+       }
+}
+
 int WM_MoveWindow(tWindow *Window, int X, int Y)
 {
+//     _SysDebug("Move %p to (%i,%i)", Window, X, Y);
        // Clip coordinates
        if(X + Window->W < 0)   X = -Window->W + 1;
        if(Y + Window->H < 0)   Y = -Window->H + 1;
        if(X >= giScreenWidth)  X = giScreenWidth - 1;
        if(Y >= giScreenHeight) Y = giScreenHeight - 1;
        
+       // If relative to the parent, extra checks
+       if( (Window->Flags & WINFLAG_RELATIVE) && Window->Parent )
+       {
+               if( X > Window->Parent->W )     return 1;
+               if( Y > Window->Parent->H )     return 1;
+       }
+       // TODO: Re-sanitise
+
        Window->X = X;  Window->Y = Y;
 
+       // TODO: Why invalidate buffer?
        WM_Invalidate(Window);
 
        return 0;
@@ -231,6 +277,9 @@ int WM_ResizeWindow(tWindow *Window, int W, int H)
        if(Window->X + W < 0)   Window->X = -W + 1;
        if(Window->Y + H < 0)   Window->Y = -H + 1;
 
+       if( Window->W == W && Window->H == H )
+               return 0;
+
        Window->W = W;  Window->H = H;
 
        if(Window->RenderBuffer) {
@@ -251,12 +300,20 @@ int WM_ResizeWindow(tWindow *Window, int W, int H)
 
 int WM_SendMessage(tWindow *Source, tWindow *Dest, int Message, int Length, const void *Data)
 {
-       if(Dest == NULL)        return -2;
-       if(Length > 0 && Data == NULL)  return -1;
+//     _SysDebug("WM_SendMessage: (%p, %p, %i, %i, %p)", Source, Dest, Message, Length, Data);
+       if(Dest == NULL) {
+               _SysDebug("WM_SendMessage: NULL destination from %p", __builtin_return_address(0));
+               return -2;
+       }
+       if(Length > 0 && Data == NULL) {
+               _SysDebug("WM_SendMessage: non-zero length and NULL data");
+               return -1;
+       }
 
        if( Decorator_HandleMessage(Dest, Message, Length, Data) != 1 )
        {
                // TODO: Catch errors from ->HandleMessage
+//             _SysDebug("WM_SendMessage: Decorator grabbed message?");
                return 0;
        }
        
@@ -264,11 +321,13 @@ int WM_SendMessage(tWindow *Source, tWindow *Dest, int Message, int Length, cons
        if( Dest->Renderer->HandleMessage(Dest, Message, Length, Data) != 1 )
        {
                // TODO: Catch errors from ->HandleMessage
+//             _SysDebug("WM_SendMessage: Renderer grabbed message?");
                return 0;
        }
 
        // TODO: Implement message masking
 
+       // Dispatch to client
        if(Dest->Client)
        {
                uint32_t        src_id;
@@ -283,16 +342,23 @@ int WM_SendMessage(tWindow *Source, tWindow *Dest, int Message, int Length, cons
                        src_id = Source->ID;
                }
                
+//             _SysDebug("WM_SendMessage: IPC Dispatch");
                IPC_SendWMMessage(Dest->Client, src_id, Dest->ID, Message, Length, Data);
        }       
 
        return 1;
 }
 
+int WM_SendIPCReply(tWindow *Window, int Message, size_t Length, const void *Data)
+{
+       IPC_SendReply(Window->Client, Window->ID, Message, Length, Data);
+       return 0;
+}
+
 void WM_Invalidate(tWindow *Window)
 {
        if(!Window)     return ;
-       _SysDebug("Invalidating %p", Window);
+//     _SysDebug("Invalidating %p", Window);
        // Don't invalidate twice (speedup)
 //     if( !(Window->Flags & WINFLAG_CLEAN) )  return;
 
@@ -319,7 +385,7 @@ void WM_int_UpdateWindow(tWindow *Window)
                // Calculate RealW/RealH
                if( !(Window->Flags & WINFLAG_NODECORATE) )
                {
-                       _SysDebug("Applying decorations to %p", Window);
+                       //_SysDebug("Applying decorations to %p", Window);
                        Decorator_UpdateBorderSize(Window);
                        Window->RealW = Window->BorderL + Window->W + Window->BorderR;
                        Window->RealH = Window->BorderT + Window->H + Window->BorderB;
@@ -335,6 +401,17 @@ void WM_int_UpdateWindow(tWindow *Window)
                        Window->RealH = Window->H;
                }
                
+               if( (Window->Flags & WINFLAG_RELATIVE) && Window->Parent )
+               {
+                       Window->RealX = Window->Parent->X + Window->Parent->BorderL + Window->X;
+                       Window->RealY = Window->Parent->Y + Window->Parent->BorderT + Window->Y;
+               }
+               else
+               {
+                       Window->RealX = Window->X;
+                       Window->RealY = Window->Y;
+               }
+
                Window->Renderer->Redraw(Window);
                Window->Flags |= WINFLAG_CLEAN;
        }
@@ -362,18 +439,18 @@ void WM_int_BlitWindow(tWindow *Window)
        if( !(Window->Flags & WINFLAG_SHOW) )
                return ;
 
-//     _SysDebug("Blit %p to (%i,%i) %ix%i", Window, Window->X, Window->Y, Window->RealW, Window->RealH);
-       Video_Blit(Window->RenderBuffer, Window->X, Window->Y, Window->RealW, Window->RealH);
+//     _SysDebug("Blit %p (%p) to (%i,%i) %ix%i", Window, Window->RenderBuffer,
+//             Window->RealX, Window->RealY, Window->RealW, Window->RealH);
+       Video_Blit(Window->RenderBuffer, Window->RealX, Window->RealY, Window->RealW, Window->RealH);
        
        if( Window == gpWM_FocusedWindow && Window->CursorW )
        {
                Video_FillRect(
-                       Window->X + Window->BorderL + Window->CursorX,
-                       Window->Y + Window->BorderT + Window->CursorY,
+                       Window->RealX + Window->BorderL + Window->CursorX,
+                       Window->RealY + Window->BorderT + Window->CursorY,
                        Window->CursorW, Window->CursorH,
                        0x000000
                        );
-                       
        }
 
        for( child = Window->FirstChild; child; child = child->NextSibling )
index 034999b..7b2a049 100644 (file)
@@ -8,21 +8,22 @@
 #ifndef _AXWIN3__FRAMEBUFFER_MESSAGES_H_
 #define _AXWIN3__FRAMEBUFFER_MESSAGES_H_
 
-enum
+enum eFrameBuffer_IPCCalls
 {
-       MSG_FB_COMMIT = 0x1000,
-       MSG_FB_NEWBUF,
-       MSG_FB_UPLOAD,
-       MSG_FB_DOWNLOAD,
-       MSG_FB_BLIT,
-       MSG_FB_FILL
+       IPC_FB_COMMIT,
+       IPC_FB_NEWBUF,
+       IPC_FB_UPLOAD,
+       IPC_FB_DOWNLOAD,        // Replies with requested data
+       IPC_FB_BLIT,
+       IPC_FB_FILL,
+       N_IPC_FB
 };
 
 typedef struct
 {
        uint16_t        Buffer;
        uint16_t        W, H;
-} tFBMsg_NewBuf;
+} tFBIPC_NewBuf;
 
 typedef struct
 {
@@ -30,7 +31,7 @@ typedef struct
        uint16_t        W, H;
        uint16_t        X, Y;
        uint32_t        ImageData[];
-} tFBMsg_Transfer;
+} tFBIPC_Transfer;
 
 typedef struct
 {
@@ -39,7 +40,7 @@ typedef struct
        uint16_t        SrcX, SrcY;
        uint16_t        DstX, DstY;
        uint16_t        W, H;
-} tFBMsg_Blit;
+} tFBIPC_Blit;
 
 typedef struct
 {
@@ -47,7 +48,7 @@ typedef struct
        uint16_t        X, Y;
        uint16_t        W, H;
        uint32_t        Colour;
-} tFBMsg_Fill;
+} tFBIPC_Fill;
 
 #endif
 
index 6e61ba8..50a9955 100644 (file)
@@ -28,6 +28,8 @@ typedef struct sIPCMsg_RetDisplayDims tIPCMsg_RetDisplayDims;
  */
 //! Request a return value
 #define IPCMSG_FLAG_RETURN     0x01
+//! IPC Message for renderer
+#define IPCMSG_FLAG_RENDERER   0x80
 /**
  * \}
  */
index 04dcd2d..12d7ba5 100644 (file)
 
 #include "ipcmessages.h"
 
-enum eMenuMessages
+// Client->Server IPC methods
+enum eMenuIPCCalls
 {
-       MSG_MENU_ADDITEM = 0x1000,
-       MSG_MENU_SETFLAGS,
-       
-       MSG_MENU_SELECT
+       IPC_MENU_ADDITEM,
+       IPC_MENU_SETFLAGS
 };
 
 typedef struct
@@ -24,14 +23,20 @@ typedef struct
        uint16_t        Flags;
        uint32_t        SubMenuID;
        char    Label[];
-} tMenuMsg_AddItem;
+} tMenuIPC_AddItem;
 
 typedef struct
 {
        uint16_t        ID;
        uint16_t        Value;
        uint16_t        Mask;
-} tMenuMsg_SetFlags;
+} tMenuIPC_SetFlags;
+
+// Server->Client messages
+enum eMenuMessages
+{
+       MSG_MENU_SELECT = 0x1000
+};
 
 typedef struct
 {
diff --git a/Usermode/Applications/axwin3_src/include/richtext_messages.h b/Usermode/Applications/axwin3_src/include/richtext_messages.h
new file mode 100644 (file)
index 0000000..7f53eb2
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Acess2 Window Manager v3
+ * - By John Hodge (thePowersGang)
+ *
+ * richtext_messages.h
+ * - Formatted Text Field
+ */
+#ifndef _RICHTEXT_MESSAGES_H_
+#define _RICHTEXT_MESSAGES_H_
+
+enum eRichText_Attrs {
+       _ATTR_DEFBG,
+       _ATTR_DEFFG,
+       _ATTR_SCROLL,
+       _ATTR_LINECOUNT,
+       _ATTR_COLCOUNT,
+       _ATTR_CURSOR,
+       _ATTR_CURSORBLINK,
+       _ATTR_CURSORPOS,
+};
+
+enum eRichText_IPCCalls
+{
+       IPC_RICHTEXT_SETATTR,
+       IPC_RICHTEXT_SETFONT,
+       IPC_RICHTEXT_DELLINE,
+       IPC_RICHTEXT_ADDLINE,
+       IPC_RICHTEXT_WRITELINE, // Set line contents
+       IPC_RICHTEXT_READLINE,  // Request line contents
+       N_IPC_RICHTEXT
+};
+
+struct sRichTextIPC_SetAttr
+{
+       uint32_t        Attr;
+       uint32_t        Value;
+};
+
+struct sRichTextIPC_SetFont
+{
+       uint16_t        Size;
+       char    Name[];
+};
+
+struct sRichTextIPC_AddDelLine
+{
+       uint32_t        Line;
+};
+
+struct sRichTextIPC_ReadLine
+{
+       uint32_t        Line;
+};
+
+struct sRichTextIPC_WriteLine
+{
+       uint32_t        Line;
+       char    LineData[];
+};
+
+enum
+{
+       // Events
+       MSG_RICHTEXT_KEYPRESS = 0x1000,
+       MSG_RICHTEXT_MOUSEBTN,
+
+       // Sent by server to get a line that is not cached (expects IPC WRITELINE)
+       MSG_RICHTEXT_REQLINE,
+       // Response to IPC READLINE
+       MSG_RICHTEXT_LINEDATA,
+};
+
+struct sRichTextMsg_ReqLine
+{
+       uint32_t        Line;
+};
+
+struct sRichTextMsg_LineData
+{
+       uint32_t        Line;
+       char    LineData[];
+};
+
+#endif
+
index 0a4b250..6064d6f 100644 (file)
@@ -8,27 +8,31 @@
 #ifndef _WIDGET_MESSAGES_H_
 #define _WIDGET_MESSAGES_H_
 
-enum
+enum eWidgetIPCCalls
 {
        // Control (Client->Server) messages
-       MSG_WIDGET_CREATE = 0x1000,
-       MSG_WIDGET_DELETE,
-       MSG_WIDGET_SETFOCUS,
-       MSG_WIDGET_SETFLAGS,
-       MSG_WIDGET_SETSIZE,
-       MSG_WIDGET_SETTEXT,
-       MSG_WIDGET_SETCOLOUR,
+       IPC_WIDGET_CREATE,
+       IPC_WIDGET_CREATESUBWIN,
+       IPC_WIDGET_DELETE,
+       IPC_WIDGET_SETFOCUS,
+       IPC_WIDGET_SETFLAGS,
+       IPC_WIDGET_SETSIZE,
+       IPC_WIDGET_SETTEXT,
+       IPC_WIDGET_SETCOLOUR,
        
-
-       // Request (Client->Server->Client) messages
-       MSG_WIDGET_GETTEXT,
-
-       // Event (Server->Client) messages
-       MSG_WIDGET_FIRE,
-       MSG_WIDGET_KEYPRESS,
-       MSG_WIDGET_MOUSEBTN,
+       IPC_WIDGET_GETTEXT,
+       
+       N_IPC_WIDGET
 };
 
+typedef struct
+{
+       uint32_t        Parent;
+       uint32_t        NewID;
+       uint32_t        Type;
+       uint32_t        Flags;
+       char    DebugName[];
+} tWidgetIPC_Create;
 
 typedef struct
 {
@@ -36,44 +40,55 @@ typedef struct
        uint32_t        NewID;
        uint32_t        Type;
        uint32_t        Flags;
+       uint32_t        WindowHandle;
        char    DebugName[];
-} tWidgetMsg_Create;
+} tWidgetIPC_CreateSubWin;
 
 typedef struct
 {
        uint32_t        WidgetID;
-} tWidgetMsg_Delete;
+} tWidgetIPC_Delete;
 
 typedef struct
 {
        uint32_t        WidgetID;
-} tWidgetMsg_SetFocus;
+} tWidgetIPC_SetFocus;
 
 typedef struct
 {
        uint32_t        WidgetID;
        uint32_t        Value;
        uint32_t        Mask;
-} tWidgetMsg_SetFlags;
+} tWidgetIPC_SetFlags;
 
 typedef struct
 {
        uint32_t        WidgetID;
        uint32_t        Value;
-} tWidgetMsg_SetSize;
+} tWidgetIPC_SetSize;
 
 typedef struct
 {
        uint32_t        WidgetID;
        char    Text[];
-} tWidgetMsg_SetText;
+} tWidgetIPC_SetText;
 
 typedef struct
 {
        uint32_t        WidgetID;
        uint32_t        Index;
        uint32_t        Colour;
-} tWidgetMsg_SetColour;
+} tWidgetIPC_SetColour;
+
+enum eWidgetMessages
+{
+       // Event (Server->Client) messages
+       MSG_WIDGET_FIRE = 0x1000,
+       MSG_WIDGET_KEYPRESS,
+       MSG_WIDGET_MOUSEBTN,
+};
+
+
 
 typedef struct
 {
index 3d37b5b..f425cc7 100644 (file)
@@ -8,6 +8,7 @@ CFLAGS   += -Wall
 LDFLAGS  += -lc -soname libaxwin3.so
 
 OBJ = main.o msg.o wm.o r_widget.o r_menu.o
+OBJ += r_richtext.o
 BIN = libaxwin3.so
 
 include ../../../Libraries/Makefile.tpl
index 913cf35..19ee8fd 100644 (file)
@@ -22,6 +22,8 @@ struct sAxWin3_Window
 
 extern void    *AxWin3_int_GetDataPtr(tHWND Window);
 extern uint32_t        AxWin3_int_GetWindowID(tHWND Window);
+extern void    AxWin3_SendIPC(tHWND Window, int Message, size_t Length, const void *Data);
+extern void    *AxWin3_WaitIPCMessage(tHWND Window, int Message, size_t *Length);
 
 #endif
 
index 82f76c6..6457c97 100644 (file)
@@ -14,7 +14,7 @@ extern const char     *gsAxWin3_int_ServerDesc;
 
 extern tAxWin_IPCMessage       *AxWin3_int_AllocateIPCMessage(tHWND Window, int Message, int Flags, int ExtraBytes);
 extern void    AxWin3_int_SendIPCMessage(tAxWin_IPCMessage *Msg);
-extern tAxWin_IPCMessage       *AxWin3_int_GetIPCMessage(void);
+extern tAxWin_IPCMessage       *AxWin3_int_GetIPCMessage(int nFD, fd_set *FDs);
 extern tAxWin_IPCMessage       *AxWin3_int_WaitIPCMessage(int WantedID);
 extern void    AxWin3_int_HandleMessage(tAxWin_IPCMessage *Msg);
 
index d8f6a61..453d4ba 100644 (file)
@@ -25,15 +25,21 @@ void AxWin3_MainLoop(void)
 
        while(!bExit)
        {
-               msg = AxWin3_int_GetIPCMessage();
+               msg = AxWin3_int_GetIPCMessage(0, NULL);
                if(!msg)        continue;       
 
-               _SysDebug("oh look, a message (Type=%i, Window=%i, Len=%i)",
+               _SysDebug("AxWin3_MainLoop - Message (Type=%i, Window=%i, Len=%i)",
                        msg->ID, msg->Window, msg->Size);
 
                AxWin3_int_HandleMessage( msg );
-               
-               free(msg);
        }
 }
 
+void AxWin3_MessageSelect(int nFD, fd_set *FDs)
+{
+       tAxWin_IPCMessage *msg;
+       msg = AxWin3_int_GetIPCMessage(nFD, FDs);
+       if( msg )
+               AxWin3_int_HandleMessage( msg );
+}
+
index ac51e27..6c134a3 100644 (file)
@@ -33,9 +33,8 @@ tAxWin3_MessageCallback       gAxWin3_MessageCallback;
 // === CODE ===
 void AxWin3_Connect(const char *ServerDesc)
 {
-       _SysDebug("ServerDesc = %s", ServerDesc);
-       if( !ServerDesc )
-       {
+       _SysDebug("ServerDesc (argument) = %s", ServerDesc);
+       if( !ServerDesc ) {
                ServerDesc = gsAxWin3_int_ServerDesc;
        }
        _SysDebug("ServerDesc = %s", ServerDesc);
@@ -50,6 +49,10 @@ void AxWin3_Connect(const char *ServerDesc)
        case '6': case '7': case '8': case '9': case '0':
                giConnectionType = CONNTYPE_SENDMESSAGE;
                giConnectionNum = atoi(ServerDesc);
+               if( giConnectionNum == 0 ) {
+                       _SysDebug("Invalid server PID");
+                       exit(-1);
+               }
                break;
        case 'u':
                while(*ServerDesc && *ServerDesc != ':')        ServerDesc ++;
@@ -115,57 +118,43 @@ void AxWin3_int_SendIPCMessage(tAxWin_IPCMessage *Msg)
        }
 }
 
-tAxWin_IPCMessage *AxWin3_int_GetIPCMessage(void)
+tAxWin_IPCMessage *AxWin3_int_GetIPCMessage(int nFD, fd_set *fds)
 {
         int    len;
        tAxWin_IPCMessage       *ret = NULL;
-       switch(giConnectionType)
+       pid_t   tid;
+
+       _SysSelect(nFD, fds, NULL, NULL, NULL, THREAD_EVENT_IPCMSG);
+       
+       // Clear out IPC messages
+       while( (len = SysGetMessage(&tid, 0, NULL)) )
        {
-       case CONNTYPE_SENDMESSAGE:
-               for( ;; )
+               if( giConnectionType != CONNTYPE_SENDMESSAGE || tid != giConnectionNum )
                {
-                       pid_t   tid;
-               
-                       // Wait for a message to arrive 
-                       while( !(len = SysGetMessage(&tid, 0, NULL)) )
-                       {
-                               _SysWaitEvent(THREAD_EVENT_IPCMSG);
-                       }
-                       
-                       // Check if the message came from the server
-                       if(tid != giConnectionNum)
-                       {
-                               _SysDebug("%i byte message from %i", len, tid);
-                               // If not, pass the buck (or ignore)
-                               if( gAxWin3_MessageCallback )
-                                       gAxWin3_MessageCallback(tid, len);
-                               else
-                                       SysGetMessage(NULL, 0, GETMSG_IGNORE);
-                               continue ;
-                       }
-                       
-                       // If it's from the server, allocate a buffer and return it
-                       ret = malloc(len);
-                       if(ret == NULL) {
-                               _SysDebug("malloc() failed, ignoring message");
+                       _SysDebug("%i byte message from %i", len, tid);
+                       // If not, pass the buck (or ignore)
+                       if( gAxWin3_MessageCallback )
+                               gAxWin3_MessageCallback(tid, len);
+                       else
                                SysGetMessage(NULL, 0, GETMSG_IGNORE);
-                               return NULL;
-                       }
-                       SysGetMessage(NULL, len, ret);
-                       break;
+                       continue ;
                }
-               break;
-       default:
-               // TODO: Implement
-               _SysDebug("TODO: Implement AxWin3_int_GetIPCMessage for TCP/UDP");
+               
+               // Using CONNTYPE_SENDMESSAGE and server message has arrived
+               ret = malloc(len);
+               if(ret == NULL) {
+                       _SysDebug("malloc() failed, ignoring message");
+                       SysGetMessage(NULL, 0, GETMSG_IGNORE);
+                       return NULL;
+               }
+               SysGetMessage(NULL, len, ret);
                break;
        }
 
-       // No message?
-       if( ret == NULL )
-               return NULL;
-
-       // TODO: Sanity checks, so a stupid server can't crash us
+       if( giConnectionType == CONNTYPE_TCP || giConnectionType == CONNTYPE_UDP )
+       {
+               // Check fds
+       }
 
        return ret;
 }
@@ -175,10 +164,9 @@ tAxWin_IPCMessage *AxWin3_int_WaitIPCMessage(int WantedID)
        tAxWin_IPCMessage       *msg;
        for(;;)
        {
-               msg = AxWin3_int_GetIPCMessage();
+               msg = AxWin3_int_GetIPCMessage(0, NULL);
                if(msg->ID == WantedID) return msg;
                AxWin3_int_HandleMessage( msg );
-               free(msg);
        }
 }
 
index 1a6bfdf..4b7bb56 100644 (file)
@@ -96,7 +96,7 @@ tAxWin3_MenuItem *AxWin3_Menu_AddItem(
        ret->SubMenu = SubMenu; 
 
        {
-               tMenuMsg_AddItem        *req;
+               tMenuIPC_AddItem        *req;
                 int    data_size;
                if(!Label)      Label = "";
                data_size = sizeof(*req)+strlen(Label)+1;
@@ -105,7 +105,7 @@ tAxWin3_MenuItem *AxWin3_Menu_AddItem(
                req->Flags = Flags;
                req->SubMenuID = AxWin3_int_GetWindowID(SubMenu);
                strcpy(req->Label, Label);
-               AxWin3_SendMessage(Menu, Menu, MSG_MENU_ADDITEM, data_size, req);
+               AxWin3_SendIPC(Menu, IPC_MENU_ADDITEM, data_size, req);
                free(req);
        }
        
diff --git a/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_richtext.c b/Usermode/Applications/axwin3_src/libaxwin3.so_src/r_richtext.c
new file mode 100644 (file)
index 0000000..fd1cf39
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * AxWin3 Interface Library
+ * - By John Hodge (thePowersGang)
+ *
+ * r_richtext.c
+ * - Formatted Text window type
+ */
+#include <axwin3/axwin.h>
+#include <axwin3/richtext.h>
+#include "include/internal.h"
+#include <richtext_messages.h>
+#include <string.h>
+//#include <alloca.h>
+
+// === TYPES ===
+typedef struct sRichText_Window
+{
+       tAxWin3_RichText_KeyHandler     KeyCallback;
+       tAxWin3_RichText_MouseHandler   MouseCallback;
+       tAxWin3_RichText_LineHandler    LineHandler;
+} tRichText_Window;
+
+// === CODE ===
+int AxWin3_RichText_MessageHandler(tHWND Window, int MessageID, int Size, void *Data)
+{
+       return 0;
+}
+
+static void _SendAttrib(tHWND Window, int Attr, uint32_t Value)
+{
+       struct sRichTextIPC_SetAttr     msg;
+       msg.Attr = Attr;
+       msg.Value = Value;
+       AxWin3_SendIPC(Window, IPC_RICHTEXT_SETATTR, sizeof(msg), &msg);
+}
+
+tHWND AxWin3_RichText_CreateWindow(tHWND Parent, int Flags)
+{
+       tHWND ret = AxWin3_CreateWindow(Parent, "RichText", Flags, sizeof(tRichText_Window), AxWin3_RichText_MessageHandler);
+//     tRichText_Window *info = AxWin3_int_GetDataPtr(ret);
+       return ret;
+}
+
+void AxWin3_RichText_SetKeyHandler(tHWND Window, tAxWin3_RichText_KeyHandler Handler)
+{
+       tRichText_Window        *info = AxWin3_int_GetDataPtr(Window);
+       info->KeyCallback = Handler;
+}
+
+void AxWin3_RichText_SetMouseHandler(tHWND Window, tAxWin3_RichText_MouseHandler Handler)
+{
+       tRichText_Window        *info = AxWin3_int_GetDataPtr(Window);
+       info->MouseCallback = Handler;
+}
+
+void AxWin3_RichText_EnableScroll(tHWND Window, int bEnable)
+{
+       _SendAttrib(Window, _ATTR_SCROLL, bEnable);
+}
+void AxWin3_RichText_SetLineCount(tHWND Window, int Lines)
+{
+       _SendAttrib(Window, _ATTR_LINECOUNT, Lines);
+}
+void AxWin3_RichText_SetColCount(tHWND Window, int Cols)
+{
+       _SendAttrib(Window, _ATTR_COLCOUNT, Cols);
+}
+void AxWin3_RichText_SetBackground(tHWND Window, uint32_t ARGB_Colour)
+{
+       _SendAttrib(Window, _ATTR_DEFBG, ARGB_Colour);
+}
+void AxWin3_RichText_SetDefaultColour(tHWND Window, uint32_t ARGB_Colour)
+{
+       _SendAttrib(Window, _ATTR_DEFFG, ARGB_Colour);
+}
+void AxWin3_RichText_SetFont(tHWND Window, const char *FontName, int PointSize)
+{
+       // TODO: Send message
+}
+void AxWin3_RichText_SetCursorType(tHWND Window, int Type)
+{
+       _SendAttrib(Window, _ATTR_CURSOR, Type);
+}
+void AxWin3_RichText_SetCursorBlink(tHWND Window, int bBlink)
+{
+       _SendAttrib(Window, _ATTR_CURSORBLINK, bBlink);
+}
+void AxWin3_RichText_SetCursorPos(tHWND Window, int Row, int Column)
+{
+       if(Row < 0 || Row > 0xFFFFF || Column > 0xFFF || Column < 0)
+               return ;
+       _SendAttrib(Window, _ATTR_CURSORPOS, ((Row & 0xFFFFF) << 12) | (Column & 0xFFF));
+}
+
+void AxWin3_RichText_SendLine(tHWND Window, int Line, const char *Text)
+{
+       // TODO: Local sanity check on `Line`?
+       struct sRichTextIPC_WriteLine   *msg;
+       size_t  len = sizeof(*msg) + strlen(Text) + 1;
+       char    buffer[len];
+               msg = (void*)buffer;
+       msg->Line = Line;
+       strcpy(msg->LineData, Text);
+       AxWin3_SendIPC(Window, IPC_RICHTEXT_WRITELINE, len, msg);
+}
+
index 450e4b4..62e4277 100644 (file)
@@ -46,6 +46,33 @@ tAxWin3_Widget *AxWin3_Widget_int_GetElementByID(tHWND Window, uint32_t ID)
        return info->Elements[ID];
 }
 
+uint32_t AxWin3_Widget_int_AllocateID(tWidgetWindowInfo *Info)
+{
+       uint32_t        newID;
+       // BUG BUG BUG - Double Allocations! (citation needed)
+       // TODO: Atomicity
+       for( newID = Info->FirstFreeID; newID < Info->nElements; newID ++ )
+       {
+               if( Info->Elements[newID] == NULL )
+                       break;
+       }
+       if( newID == Info->nElements )
+       {
+               const int size_step = 4;
+               Info->nElements += 4;
+               Info->Elements = realloc(Info->Elements, sizeof(*Info->Elements)*Info->nElements);
+               newID = Info->nElements - 4;
+               memset( &Info->Elements[newID+1], 0, (size_step-1)*sizeof(Info->Elements));
+               _SysDebug("Widget: Expanded to %i and allocated %i", Info->nElements, newID);
+       }
+       else
+               _SysDebug("Widget: Allocated %i", newID);
+       Info->Elements[newID] = (void*)-1;
+       
+       return newID;
+       
+}
+
 int AxWin3_Widget_MessageHandler(tHWND Window, int MessageID, int Size, void *Data)
 {
        tAxWin3_Widget  *widget;
@@ -58,7 +85,7 @@ int AxWin3_Widget_MessageHandler(tHWND Window, int MessageID, int Size, void *Da
                widget = AxWin3_Widget_int_GetElementByID(Window, msg->WidgetID);
                if(widget->Fire)        widget->Fire(widget);
                
-               return 0; }
+               return 1; }
        default:
                return 0;
        }
@@ -108,26 +135,7 @@ tAxWin3_Widget *AxWin3_Widget_AddWidget(tAxWin3_Widget *Parent, int Type, int Fl
 
        info = AxWin3_int_GetDataPtr(Parent->Window);
        
-       // Assign ID
-       // BUG BUG BUG - Double Allocations!
-       // TODO: Atomicity
-       for( newID = info->FirstFreeID; newID < info->nElements; newID ++ )
-       {
-               if( info->Elements[newID] == NULL )
-                       break;
-       }
-       if( newID == info->nElements )
-       {
-               const int size_step = 4;
-               info->nElements += 4;
-               info->Elements = realloc(info->Elements, sizeof(*info->Elements)*info->nElements);
-               newID = info->nElements - 4;
-               memset( &info->Elements[newID+1], 0, (size_step-1)*sizeof(info->Elements));
-               _SysDebug("Expanded to %i and allocated %i", info->nElements, newID);
-       }
-       else
-               _SysDebug("Allocated %i", newID);
-       info->Elements[newID] = (void*)-1;
+       newID = AxWin3_Widget_int_AllocateID(info);
        
        // Create new widget structure
        ret = calloc(sizeof(tAxWin3_Widget), 1);
@@ -138,26 +146,53 @@ tAxWin3_Widget *AxWin3_Widget_AddWidget(tAxWin3_Widget *Parent, int Type, int Fl
 
        // Send create widget message
        {
-               char    tmp[sizeof(tWidgetMsg_Create)+1];
-               tWidgetMsg_Create       *msg = (void*)tmp;
+               char    tmp[sizeof(tWidgetIPC_Create)+1];
+               tWidgetIPC_Create       *msg = (void*)tmp;
                msg->Parent = Parent->ID;
                msg->NewID = newID;
                msg->Type = Type;
                msg->Flags = Flags;
                msg->DebugName[0] = '\0';
-               AxWin3_SendMessage(ret->Window, ret->Window, MSG_WIDGET_CREATE, sizeof(tmp), tmp);
+               AxWin3_SendIPC(ret->Window, IPC_WIDGET_CREATE, sizeof(tmp), tmp);
+       }
+
+       return ret;
+}
+
+tAxWin3_Widget *AxWin3_Widget_AddWidget_SubWindow(tAxWin3_Widget *Parent, tHWND Window, int Flags, const char *DbgName)
+{
+       tWidgetWindowInfo       *info = AxWin3_int_GetDataPtr(Parent->Window);
+       int newID = AxWin3_Widget_int_AllocateID(info);
+       
+       tAxWin3_Widget  *ret = calloc(sizeof(tAxWin3_Widget), 1);
+       ret->Window = Parent->Window;
+       ret->ID = newID;
+       info->Elements[newID] = ret;
+
+       // Send message
+       {
+               char    tmp[sizeof(tWidgetIPC_CreateSubWin)+1];
+               tWidgetIPC_CreateSubWin *msg = (void*)tmp;
+               msg->Parent = Parent->ID;
+               msg->NewID = newID;
+               msg->Type = ELETYPE_SUBWIN;
+               msg->Flags = Flags;     // TODO: Flags
+               msg->WindowHandle = AxWin3_int_GetWindowID(Window);
+               msg->DebugName[0] = '\0';
+               AxWin3_SendIPC(ret->Window, IPC_WIDGET_CREATESUBWIN, sizeof(tmp), tmp);
        }
 
        return ret;
 }
 
+
 void AxWin3_Widget_DelWidget(tAxWin3_Widget *Widget)
 {
-       tWidgetMsg_Delete       msg;
+       tWidgetIPC_Delete       msg;
        tWidgetWindowInfo       *info = AxWin3_int_GetDataPtr(Widget->Window);
        
        msg.WidgetID = Widget->ID;
-       AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_DELETE, sizeof(msg), &msg);
+       AxWin3_SendIPC(Widget->Window, IPC_WIDGET_DELETE, sizeof(msg), &msg);
        
        info->Elements[Widget->ID] = NULL;
        if(Widget->ID < info->FirstFreeID)
@@ -199,45 +234,45 @@ void AxWin3_Widget_SetMouseButtonHandler(tAxWin3_Widget *Widget, tAxWin3_Widget_
 // --- Manipulation
 void AxWin3_Widget_SetFlags(tAxWin3_Widget *Widget, int FlagSet, int FlagMask)
 {
-       tWidgetMsg_SetFlags     msg;
+       tWidgetIPC_SetFlags     msg;
        msg.WidgetID = Widget->ID;
        msg.Value = FlagSet;
        msg.Mask = FlagMask;
        
-       AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETFLAGS, sizeof(msg), &msg);
+       AxWin3_SendIPC(Widget->Window, IPC_WIDGET_SETFLAGS, sizeof(msg), &msg);
 }
 
 void AxWin3_Widget_SetSize(tAxWin3_Widget *Widget, int Size)
 {
-       tWidgetMsg_SetSize      msg;
+       tWidgetIPC_SetSize      msg;
        
        msg.WidgetID = Widget->ID;
        msg.Value = Size;
-       AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETSIZE, sizeof(msg), &msg);
+       AxWin3_SendIPC(Widget->Window, IPC_WIDGET_SETSIZE, sizeof(msg), &msg);
 }
 
 void AxWin3_Widget_SetText(tAxWin3_Widget *Widget, const char *Text)
 {
-       char    buf[sizeof(tWidgetMsg_SetText) + strlen(Text) + 1];
-       tWidgetMsg_SetText      *msg = (void*)buf;
+       char    buf[sizeof(tWidgetIPC_SetText) + strlen(Text) + 1];
+       tWidgetIPC_SetText      *msg = (void*)buf;
        
        msg->WidgetID = Widget->ID;
        strcpy(msg->Text, Text);
        
-       AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETTEXT, sizeof(buf), buf);
+       AxWin3_SendIPC(Widget->Window, IPC_WIDGET_SETTEXT, sizeof(buf), buf);
 }
 
 char *AxWin3_Widget_GetText(tAxWin3_Widget *Widget)
 {
-       char    buf[sizeof(tWidgetMsg_SetText)];
-       tWidgetMsg_SetText      *msg = (void*)buf;
+       char    buf[sizeof(tWidgetIPC_SetText)];
+       tWidgetIPC_SetText      *msg = (void*)buf;
        size_t  retmsg_size;
        
        msg->WidgetID = Widget->ID;
 
-       AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_GETTEXT, sizeof(buf), buf);
+       AxWin3_SendIPC(Widget->Window, IPC_WIDGET_GETTEXT, sizeof(buf), buf);
 
-       msg = AxWin3_WaitMessage(Widget->Window, MSG_WIDGET_GETTEXT, &retmsg_size);
+       msg = AxWin3_WaitIPCMessage(Widget->Window, IPC_WIDGET_GETTEXT, &retmsg_size);
        if( retmsg_size < sizeof(*msg) ) {
                free(msg);
                return NULL;
@@ -250,10 +285,10 @@ char *AxWin3_Widget_GetText(tAxWin3_Widget *Widget)
 
 void AxWin3_Widget_SetColour(tAxWin3_Widget *Widget, int Index, tAxWin3_Colour Colour)
 {
-       tWidgetMsg_SetColour    msg;
+       tWidgetIPC_SetColour    msg;
        
        msg.WidgetID = Widget->ID;
        msg.Index = Index;
        msg.Colour = Colour;
-       AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETCOLOUR, sizeof(msg), &msg);
+       AxWin3_SendIPC(Widget->Window, IPC_WIDGET_SETCOLOUR, sizeof(msg), &msg);
 }
index 4a6d8d3..53208f2 100644 (file)
@@ -127,7 +127,7 @@ int AxWin3_GetDisplayDims(int Display, int *X, int *Y, int *Width, int *Height)
        ret = (void*)msg->Data;
        
        if(X)   *X = ret->X;
-       if(X)   *X = ret->Y;
+       if(Y)   *Y = ret->Y;
        if(Width)       *Width = ret->W;
        if(Height)      *Height = ret->H;
        
@@ -161,6 +161,8 @@ tHWND AxWin3_CreateWindow(
        AxWin3_int_SendIPCMessage(msg);
        free(msg);
 
+       _SysDebug("AxWin3_CreateWindow: %i :: '%s'", newWinID, Renderer);
+
        // TODO: Detect and handle possible errors
 
        // Return success
@@ -217,7 +219,7 @@ void AxWin3_int_HandleMessage(tAxWin_IPCMessage *Msg)
                                        gAxWin3_Hotkeys[mi->ID]();
                                }break;
                        default:
-                               _SysDebug("--- Unhandled SENDMSG %i", info->ID);
+                               _SysDebug("--- Unhandled SENDMSG 0x%x win %i", info->ID, Msg->Window);
                                break;
                        }
                }
@@ -226,6 +228,8 @@ void AxWin3_int_HandleMessage(tAxWin_IPCMessage *Msg)
                _SysDebug("Unknow message ID %i", Msg->ID);
                break;
        }
+       
+       free(Msg);
 }
 
 void AxWin3_SetWindowTitle(tHWND Window, const char *Title)
@@ -283,6 +287,36 @@ void *AxWin3_WaitMessage(tHWND Window, int MessageID, size_t *Length)
        }
 }
 
+void AxWin3_SendIPC(tHWND Window, int Message, size_t Length, const void *Data)
+{
+       tAxWin_IPCMessage       *msg;
+       
+       msg = AxWin3_int_AllocateIPCMessage(Window, Message, IPCMSG_FLAG_RENDERER, Length);
+       memcpy(msg->Data, Data, Length);
+       AxWin3_int_SendIPCMessage(msg);
+       free(msg);
+}
+
+void *AxWin3_WaitIPCMessage(tHWND Window, int MessageID, size_t *Length)
+{
+       tAxWin_IPCMessage       *msg;
+       for( ;; )
+       {
+               msg = AxWin3_int_WaitIPCMessage(MessageID);
+               if( !(msg->Flags & IPCMSG_FLAG_RENDERER) || msg->Window != AxWin3_int_GetWindowID(Window) ) {
+                       AxWin3_int_HandleMessage(msg);
+                       continue ;
+               }
+
+               *Length = msg->Size;
+               void    *ret = malloc(msg->Size);
+               memcpy(ret, msg->Data, msg->Size);
+               free(msg);
+       
+               return ret;
+       }
+}
+
 void AxWin3_FocusWindow(tHWND Window)
 {
        tAxWin_IPCMessage       *msg;
diff --git a/Usermode/Applications/gui_ate_src/Makefile b/Usermode/Applications/gui_ate_src/Makefile
new file mode 100644 (file)
index 0000000..569e141
--- /dev/null
@@ -0,0 +1,11 @@
+# Project: [GUI] Acess Text Editor (ATE)
+
+-include ../Makefile.cfg
+
+LDFLAGS += -laxwin3
+
+OBJ = main.o
+BIN = ate
+DIR := Apps/AxWin/3.0
+
+-include ../Makefile.tpl
diff --git a/Usermode/Applications/gui_ate_src/edit.c b/Usermode/Applications/gui_ate_src/edit.c
new file mode 100644 (file)
index 0000000..8e1f01e
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Acess Text Editor (ATE)
+ * - By John Hodge (thePowersGang)
+ *
+ * edit.c
+ * - File Loading / Manipulation
+ */
+#include <stdio.h>
+#include "include/file.h"
+#include "include/syntax.h"
+
+// === CODE ===
+tFile *File_New(void)
+{
+       tFile *ret = malloc(sizeof(tFile) + 1);
+       ret->Handle = NULL;
+       ret->nLines = 0;
+       ret->Lines = NULL;
+       ret->NameOfs = 0;
+       ret->Path[0] = 0;
+       return ret;
+}
+
+tFile *File_Load(const char *Path)
+{
+       return NULL;
+}
+
+int File_Save(tFile *File)
+{
+       
+       //file->bIsDirty = 0;
+       return -1;
+}
+
+int File_Close(tFile *File, int bDiscard)
+{
+       //if( file->bIsDirty && !bDiscard )
+       //      return 1;
+       if( file->Handle )
+               fclose(File->Handle);
+       
+       return 0;
+}
+
diff --git a/Usermode/Applications/gui_ate_src/include/file.h b/Usermode/Applications/gui_ate_src/include/file.h
new file mode 100644 (file)
index 0000000..5eb15b0
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Acess Text Editor (ATE)
+ * - By John Hodge (thePowersGang)
+ *
+ * include/file.h
+ * - In-memory file structures
+ */
+#ifndef _ATE__FILE_H_
+#define _ATE__FILE_H_
+#include <stdio.h>
+
+typedef struct sFileLine
+{
+        int    Num;
+
+       // State data for hilighting
+        int    HilightState;
+       char    *Rendered;
+
+        int    Space;
+        int    Length;
+       char    Data[];
+} tFileLine;
+
+typedef struct sFile
+{
+       FILE    *Handle;
+        int    nLines;
+       tFileLine       **Lines;        // TODO: Handle very large files?
+        int    NameOfs;
+       const char      Path[];
+} tFile;
+
+#endif
+
diff --git a/Usermode/Applications/gui_ate_src/include/syntax.h b/Usermode/Applications/gui_ate_src/include/syntax.h
new file mode 100644 (file)
index 0000000..99b35ce
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * Acess Text Editor (ATE)
+ * - By John Hodge (thePowersGang)
+ *
+ * include/syntax.h
+ * - Syntax Hilighting / Rendering structures
+ */
+#ifndef _ATE__SYNTAX_H_
+#define _ATE__SYNTAX_H_
+
+#endif
+
diff --git a/Usermode/Applications/gui_ate_src/main.c b/Usermode/Applications/gui_ate_src/main.c
new file mode 100644 (file)
index 0000000..a6ed8aa
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Acess Text Editor (ATE)
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ * - Core
+ */
+#include <axwin3/axwin.h>
+#include <axwin3/widget.h>
+#include <axwin3/menu.h>
+#include <axwin3/richtext.h>
+#include <stdio.h>
+
+// === PROTOTYPES ===
+ int   main(int argc, char *argv[]);
+ int   TextArea_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translated);
+ int   TextArea_MouseHandler(tHWND Window, int bPress, int Button, int Row, int Col);
+void   add_toolbar_button(tAxWin3_Widget *Toolbar, const char *Ident, tAxWin3_Widget_FireCb Callback);
+ int   Toolbar_New(tAxWin3_Widget *Widget);
+ int   Toolbar_Open(tAxWin3_Widget *Widget);
+ int   Toolbar_Save(tAxWin3_Widget *Widget);
+
+// === GLOBALS ===
+tHWND  gMainWindow;
+tAxWin3_Widget *gMainWindow_Root;
+tHWND  gMainWindow_MenuBar;
+tAxWin3_Widget *gMainWindow_Toolbar;
+tHWND  gMainWindow_TextArea;
+
+// === CODE ===
+int main(int argc, char *argv[])
+{
+       AxWin3_Connect(NULL);
+       
+       // --- Build up window
+       gMainWindow = AxWin3_Widget_CreateWindow(NULL, 700, 400, ELEFLAG_VERTICAL);
+       AxWin3_SetWindowTitle(gMainWindow, "Acess Text Editor");        // TODO: Update title with other info
+       gMainWindow_Root = AxWin3_Widget_GetRoot(gMainWindow);
+
+       //gMainWindow_MenuBar = AxWin3_Menu_Create(gMainWindow);
+       //AxWin3_Widget_AddWidget_SubWindow(gMainWindow_Root, gMainWindow_MenuBar);
+       // TODO: Populate menu  
+
+       // Create toolbar
+       gMainWindow_Toolbar = AxWin3_Widget_AddWidget(gMainWindow_Root, ELETYPE_TOOLBAR, ELEFLAG_NOSTRETCH, "Toolbar");
+       add_toolbar_button(gMainWindow_Toolbar, "BtnNew", Toolbar_New);
+       add_toolbar_button(gMainWindow_Toolbar, "BtnOpen", Toolbar_Open);
+       add_toolbar_button(gMainWindow_Toolbar, "BtnSave", Toolbar_Save);
+       AxWin3_Widget_AddWidget(gMainWindow_Toolbar, ELETYPE_SPACER, 0, "");
+       add_toolbar_button(gMainWindow_Toolbar, "BtnUndo", NULL);
+       add_toolbar_button(gMainWindow_Toolbar, "BtnRedo", NULL);
+       AxWin3_Widget_AddWidget(gMainWindow_Toolbar, ELETYPE_SPACER, 0, "");
+       add_toolbar_button(gMainWindow_Toolbar, "BtnCut", NULL);
+       add_toolbar_button(gMainWindow_Toolbar, "BtnCopy", NULL);
+       add_toolbar_button(gMainWindow_Toolbar, "BtnPaste", NULL);
+       AxWin3_Widget_AddWidget(gMainWindow_Toolbar, ELETYPE_SPACER, 0, "");
+       add_toolbar_button(gMainWindow_Toolbar, "BtnSearch", NULL);
+       add_toolbar_button(gMainWindow_Toolbar, "BtnReplace", NULL);
+
+       // TODO: Tab control?   
+
+       gMainWindow_TextArea = AxWin3_RichText_CreateWindow(gMainWindow, 0);
+       AxWin3_Widget_AddWidget_SubWindow(gMainWindow_Root, gMainWindow_TextArea, 0, "TextArea");
+       AxWin3_RichText_SetKeyHandler   (gMainWindow_TextArea, TextArea_KeyHandler);
+       AxWin3_RichText_SetMouseHandler (gMainWindow_TextArea, TextArea_MouseHandler);
+       AxWin3_RichText_SetBackground   (gMainWindow_TextArea, 0xFFFFFF);
+       AxWin3_RichText_SetDefaultColour(gMainWindow_TextArea, 0x000000);
+       AxWin3_RichText_SetFont         (gMainWindow_TextArea, "#monospace", 10);
+       AxWin3_RichText_SetCursorPos    (gMainWindow_TextArea, 0, 0);
+       AxWin3_RichText_SetCursorType   (gMainWindow_TextArea, AXWIN3_RICHTEXT_CURSOR_VLINE);
+       AxWin3_RichText_SetCursorBlink  (gMainWindow_TextArea, 1);
+
+       // <testing>
+       AxWin3_RichText_SetLineCount(gMainWindow_TextArea, 3);
+       AxWin3_RichText_SendLine(gMainWindow_TextArea, 0, "First line!");
+       AxWin3_RichText_SendLine(gMainWindow_TextArea, 2, "Third line! \x01""ff0000A red");
+       // </testing>
+
+       AxWin3_ShowWindow(gMainWindow_TextArea, 1);
+       // TODO: Status Bar?
+
+       AxWin3_MoveWindow(gMainWindow, 50, 50);
+       AxWin3_ShowWindow(gMainWindow, 1);
+       AxWin3_FocusWindow(gMainWindow);
+       
+       // Main loop
+       AxWin3_MainLoop();
+
+       return 0;
+}
+
+int TextArea_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translated)
+{
+       return 0;
+}
+
+int TextArea_MouseHandler(tHWND Window, int bPress, int Button, int Row, int Col)
+{
+       return 0;
+}
+
+void add_toolbar_button(tAxWin3_Widget *Toolbar, const char *Ident, tAxWin3_Widget_FireCb Callback)
+{
+       tAxWin3_Widget *btn = AxWin3_Widget_AddWidget(Toolbar, ELETYPE_BUTTON, ELEFLAG_NOSTRETCH, Ident);
+       tAxWin3_Widget *txt = AxWin3_Widget_AddWidget(btn, ELETYPE_TEXT, 0, Ident);
+       // TODO: Get image / text using `Ident` as a lookup key
+       AxWin3_Widget_SetText(txt, Ident);
+       AxWin3_Widget_SetFireHandler(btn, Callback);
+}
+
+int Toolbar_New(tAxWin3_Widget *Widget)
+{
+       return 0;
+}
+int Toolbar_Open(tAxWin3_Widget *Widget)
+{
+       return 0;
+}
+int Toolbar_Save(tAxWin3_Widget *Widget)
+{
+       return 0;
+}
+
diff --git a/Usermode/Applications/gui_shell_src/Makefile b/Usermode/Applications/gui_shell_src/Makefile
new file mode 100644 (file)
index 0000000..7ccfff4
--- /dev/null
@@ -0,0 +1,11 @@
+# Project: [GUI] Terminal
+
+-include ../Makefile.cfg
+
+LDFLAGS += -laxwin3
+
+OBJ = main.o
+BIN = terminal
+DIR := Apps/AxWin/3.0
+
+-include ../Makefile.tpl
diff --git a/Usermode/Applications/gui_shell_src/include/display.h b/Usermode/Applications/gui_shell_src/include/display.h
new file mode 100644 (file)
index 0000000..80bc69c
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Acess GUI Terminal
+ * - By John Hodge (thePowersGang)
+ *
+ * display.h
+ * - RichText Termianl Translation
+ */
+#ifndef _DISPLAY_H_
+#define _DISPLAY_H_
+
+extern void    Display_AddText(int Length, const char *UTF8Text);
+extern void    Display_Newline(int bCarriageReturn);
+extern void    Display_SetCursor(int Row, int Col);
+extern void    Display_MoveCursor(int RelRow, int RelCol);
+extern void    Display_ClearLine(int Dir);     // 0: All, 1: Forward, -1: Reverse
+extern void    Display_ClearLines(int Dir);    // 0: All, 1: Forward, -1: Reverse
+extern void    Display_SetForeground(uint32_t RGB);
+extern void    Display_SetBackground(uint32_t RGB);
+
+#endif
+
diff --git a/Usermode/Applications/gui_shell_src/include/vt100.h b/Usermode/Applications/gui_shell_src/include/vt100.h
new file mode 100644 (file)
index 0000000..13f830e
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Acess GUI Terminal
+ * - By John Hodge (thePowersGang)
+ *
+ * vt100.h
+ * - VT100/xterm emulation
+ */
+#ifndef _VT100_H_
+#define _VT100_H_
+
+/**
+ * Returns either a positive or negative byte count.
+ * Positive means that many bytes were used as part of the escape sequence
+ * and should not be sent to the display.
+ * Negative means that there were that many bytes before the next escape
+ * sequence (and hence those should be displayed).
+ */
+extern int     Term_HandleVT100(int Len, const char *Buf);
+
+
+#endif
+
diff --git a/Usermode/Applications/gui_shell_src/main.c b/Usermode/Applications/gui_shell_src/main.c
new file mode 100644 (file)
index 0000000..f5524bc
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Acess GUI Terminal
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ * - Core
+ */
+#include <axwin3/axwin.h>
+#include <axwin3/menu.h>
+#include <axwin3/richtext.h>
+#include <stdio.h>
+#include "include/display.h"
+#include "include/vt100.h"
+
+// === PROTOTYPES ===
+ int   main(int argc, char *argv[], const char **envp);
+ int   Term_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translated);
+ int   Term_MouseHandler(tHWND Window, int bPress, int Button, int Row, int Col);
+
+// === GLOBALS ===
+tHWND  gMainWindow;
+tHWND  gMenuWindow;
+ int   giChildStdin;
+ int   giChildStdout;
+
+// === CODE ===
+int main(int argc, char *argv[], const char **envp)
+{
+       AxWin3_Connect(NULL);
+       
+       // --- Build up window
+       gMainWindow = AxWin3_RichText_CreateWindow(NULL, 0);
+       AxWin3_SetWindowTitle(gMainWindow, "Terminal"); // TODO: Update title with other info
+
+       gMenuWindow = AxWin3_Menu_Create(gMainWindow);
+       AxWin3_Menu_AddItem(gMenuWindow, "Copy\tWin+C", NULL, NULL, 0, NULL);
+       AxWin3_Menu_AddItem(gMenuWindow, "Paste\tWin+V", NULL, NULL, 0, NULL);
+       // TODO: Populate menu  
+
+
+       // TODO: Tabs?
+       
+       AxWin3_RichText_SetKeyHandler   (gMainWindow, Term_KeyHandler);
+       AxWin3_RichText_SetMouseHandler (gMainWindow, Term_MouseHandler);
+       AxWin3_RichText_SetDefaultColour(gMainWindow, 0xFFFFFF);
+       AxWin3_RichText_SetBackground   (gMainWindow, 0x000000);
+       AxWin3_RichText_SetFont         (gMainWindow, "#monospace", 10);
+       AxWin3_RichText_SetCursorPos    (gMainWindow, 0, 0);
+       AxWin3_RichText_SetCursorType   (gMainWindow, AXWIN3_RICHTEXT_CURSOR_INV);
+       AxWin3_RichText_SetCursorBlink  (gMainWindow, 1);
+
+       // <testing>
+       AxWin3_RichText_SetLineCount(gMainWindow, 3);
+       AxWin3_RichText_SendLine(gMainWindow, 0, "First line!");
+       AxWin3_RichText_SendLine(gMainWindow, 2, "Third line! \x01""ff0000A red");
+       // </testing>
+
+       AxWin3_ResizeWindow(gMainWindow, 600, 400);
+       AxWin3_MoveWindow(gMainWindow, 50, 50);
+       AxWin3_ShowWindow(gMainWindow, 1);
+       AxWin3_FocusWindow(gMainWindow);
+
+       // Spawn shell
+       giChildStdout = open("/Devices/FIFO/anon", O_RDWR);
+       giChildStdin = open("/Devices/FIFO/anon", O_RDWR);
+
+       {
+                int    fds[] = {giChildStdin, giChildStdout, giChildStdout};
+               const char      *argv[] = {"CLIShell", NULL};
+               _SysSpawn("/Acess/Bin/CLIShell", argv, envp, 3, fds, NULL);
+       }
+
+       // Main loop
+       for( ;; )
+       {
+               fd_set  fds;
+               
+               FD_ZERO(&fds);
+               FD_SET(giChildStdout, &fds);
+               AxWin3_MessageSelect(giChildStdout + 1, &fds);
+               
+               if( FD_ISSET(giChildStdout, &fds) )
+               {
+                       // Read and update screen
+                       char    buf[32];
+                       int len = read(giChildStdout, buf, sizeof(buf));
+                       if( len <= 0 )  break;
+                       
+                       //Term_HandleOutput(len, buf);
+               }
+       }
+
+       return 0;
+}
+
+int Term_KeyHandler(tHWND Window, int bPress, uint32_t KeySym, uint32_t Translated)
+{
+       static int      ctrl_state = 0;
+
+       // Handle modifiers
+       #define _bitset(var,bit,set) do{if(set)var|=1<<(bit);else var&=1<<(bit);}while(0)
+       switch(KeySym)
+       {
+       case KEY_LCTRL:
+               _bitset(ctrl_state, 0, bPress);
+               return 0;
+       case KEY_RCTRL:
+               _bitset(ctrl_state, 0, bPress);
+               return 0;
+       }
+       #undef _bitset
+
+       // Handle shortcuts
+       // - Ctrl-A -- Ctrl-Z
+       if( ctrl_state && KeySym >= KEY_a && KeySym <= KEY_z )
+       {
+               Translated = KeySym - KEY_a + 1;
+       }
+
+       if( Translated )
+       {
+               // Encode and send
+               
+               return 0;
+       }
+       
+       // No translation, look for escape sequences to send
+       switch(KeySym)
+       {
+       case KEY_LEFTARROW:
+       //      str = "\x1b[D";
+               break;
+       }
+       return 0;
+}
+
+int Term_MouseHandler(tHWND Window, int bPress, int Button, int Row, int Col)
+{
+       return 0;
+}
+
+void Term_HandleOutput(int Len, const char *Buf)
+{
+       // TODO: Handle graphical / accelerated modes
+
+        int    ofs = 0;
+        int    esc_len = 0;
+
+       while( ofs < Len )
+       {
+               esc_len = Term_HandleVT100(Len - ofs, Buf + ofs);
+               if( esc_len < 0 ) {
+                       Display_AddText(-esc_len, Buf + ofs);
+                       esc_len = -esc_len;
+               }
+               Len -= esc_len;
+               ofs += esc_len;
+       }
+}
+
diff --git a/Usermode/Applications/gui_shell_src/vt100.c b/Usermode/Applications/gui_shell_src/vt100.c
new file mode 100644 (file)
index 0000000..51c8016
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Acess GUI Terminal
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ * - Core
+ */
+#include <string.h>
+#include "include/vt100.h"
+#include "include/display.h"
+
+int Term_HandleVT100(int Len, const char *Buf)
+{
+       const int       max_length = 16;
+       static char     inc_buf[max_length]
+       static int      inc_len = 0;
+
+       if( inc_len > 0 || *Buf == '\x1b' )
+       {
+               memcpy(inc_buf + inc_len, Buf, min(max_length - inc_len, Len));
+               // Handle VT100 (like) escape sequence
+               
+               inc_len = 0;
+               return 1;
+       }
+
+       switch( *Buf )
+       {
+       case '\b':
+               // TODO: Backspace
+               return 1;
+       case '\t':
+               // TODO: tab
+               return 1;
+       case '\n':
+               Display_Newline(1);
+               return 1;
+       case '\r':
+               // TODO: Carriage return
+               return ;
+       }
+
+        int    ret = 0;
+       while( ret < Len )
+       {
+               if( *Buf == '\n' )
+                       break;
+               if( *Buf == '\x1b' )
+                       break;
+               ret ++;
+               Buf ++;
+       }
+       return -ret;
+}
index 8a66ad7..a62d0dd 100644 (file)
@@ -132,7 +132,7 @@ void Server_NewClient(int FD)
        {
                int fds[3] = {clt->stdin, clt->stdout, clt->stdout};
                const char      *argv[] = {NULL};
-               _SysSpawn("/Acess/SBin/login", argv, argv, 3, fds);
+               _SysSpawn("/Acess/SBin/login", argv, argv, 3, fds, NULL);
        }
 }
 
index e252210..bf2e932 100644 (file)
@@ -38,7 +38,7 @@ $(_BIN): $(OBJ) $(_LIBS)
        @mkdir -p $(dir $(_BIN))
        @echo [LD] -o $(BIN) $(OBJ)
        @$(LD) $(LDFLAGS) -o $(_BIN) $(OBJ) $(shell $(CC) -print-libgcc-file-name)
-       @$(DISASM) -S $(_BIN) > $(_OBJPREFIX)$(BIN).dsm
+       @$(DISASM) -D -S $(_BIN) > $(_OBJPREFIX)$(BIN).dsm
 
 $(_OBJPREFIX)%.o: %.c
        @echo [CC] -o $@
index 9132c02..2c85b14 100644 (file)
@@ -39,29 +39,29 @@ __clear_cache:
        svc #0x1001
        mov pc, lr
 
-@ DEST
-@ SRC
-@_memcpy:
-@      push rbp
-@      mov rbp, rsp
-@      
-@      ; RDI - First Param
-@      ; RSI - Second Param
-@      mov rcx, rdx    ; RDX - Third
-@      rep movsb
-@      
-@      pop rbp
-@      ret
-@
+
+@ >r0: PC
+@ >r1: Pointer to item count
+@ <r0: Address
+@ STUBBED
+__gnu_Unwind_Find_exidx:
+       mov r0, #0
+       str r0, [r1]
+       mov pc, lr
+
+.section .data
 .globl _errno
 _errno:        .long   0       @ Placed in .text, to allow use of relative addressing
+.section .text
 
 .macro syscall0 _name, _num    
 .globl \_name
 \_name:
        push {lr}
        svc #\_num
-       str r2, _errno
+       @mrc p15, 0, r3, c13, c0, 2
+       ldr r3, =_errno
+       str r2, [r3]
        pop {pc}
 .endm
 
@@ -71,7 +71,8 @@ _errno:       .long   0       @ Placed in .text, to allow use of relative addressing
        push {r4, lr}
        ldr r4, [sp,#8]
        svc #\_num
-       str r2, _errno
+       ldr r3, =_errno
+       str r2, [r3]
        pop {r4, pc}
 .endm
 
@@ -82,7 +83,8 @@ _errno:       .long   0       @ Placed in .text, to allow use of relative addressing
        ldr r4, [sp,#12]
        ldr r5, [sp,#16]
        svc #\_num
-       str r2, _errno
+       ldr r3, =_errno
+       str r2, [r3]
        pop {r4,r5,pc}
 .endm
 
@@ -107,7 +109,8 @@ _clone:
        push {r4}
        mov r4, r1
        svc #SYS_CLONE
-       str r2, _errno
+       ldr r3, =_errno
+       str r2, [r3]
        tst r4, r4
        beq _clone_ret
        @ If in child, set SP
index a978a35..a59e857 100644 (file)
@@ -37,6 +37,7 @@ SYSCALL1(_SysSetFaultHandler, SYS_SETFAULTHANDLER)
 SYSCALL6(_SysDebug, 0x100)
 SYSCALL1(_SysGetPhys, SYS_GETPHYS)     // uint64_t _SysGetPhys(uint addr)
 SYSCALL1(_SysAllocate, SYS_ALLOCATE)   // uint64_t _SysAllocate(uint addr)
+SYSCALL3(SysSetMemFlags, SYS_SETFLAGS) // uint32_t SysSetMemFlags(uint addr, uint flags, uint mask)
 // VFS System calls
 SYSCALL2(open, SYS_OPEN)       // char*, int
 SYSCALL3(reopen, SYS_REOPEN)   // int, char*, int
index 6f67811..eb9b83b 100644 (file)
@@ -39,7 +39,7 @@ extern void   *DoRelocate(void *Base, char **envp, const char *Filename);
 // === Library/Symbol Manipulation ==
 extern void    *LoadLibrary(const char *Filename, const char *SearchDir, char **envp);
 extern void    AddLoaded(const char *File, void *base);
-extern void    *GetSymbol(const char *name, size_t *size);
+extern int     GetSymbol(const char *Name, void **Value, size_t *size);
 extern int     GetSymbolFromBase(void *base, const char *name, void **ret, size_t *size);
 
 // === Library Functions ===
index dc9dca3..dd64ab0 100644 (file)
@@ -9,6 +9,10 @@
 # define DEBUG 0
 #endif
 
+#ifndef PAGE_SIZE
+# define PAGE_SIZE     4096
+#endif
+
 #include "common.h"
 #include <stdint.h>
 #include "elf32.h"
@@ -35,8 +39,9 @@ void  *ElfRelocate(void *Base, char **envp, const char *Filename);
  int   ElfGetSymbol(void *Base, const char *Name, void **Ret, size_t *Size);
 void   *Elf32Relocate(void *Base, char **envp, const char *Filename);
  int   Elf32GetSymbol(void *Base, const char *Name, void **Ret, size_t *Size);
-void   elf_doRelocate_386(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff);
-void   elf_doRelocate_arm(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff);
+ int   elf_doRelocate_386(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff);
+ int   elf_doRelocate_arm(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff);
+ int   elf_doRelocate_unk(uint32_t , uint32_t *, Elf32_Addr , int , int , const char *, intptr_t);
 #ifdef SUPPORT_ELF64
 void   *Elf64Relocate(void *Base, char **envp, const char *Filename);
  int   Elf64GetSymbol(void *Base, const char *Name, void **Ret, size_t *Size);
@@ -87,26 +92,28 @@ int ElfGetSymbol(void *Base, const char *Name, void **ret, size_t *Size)
        }
 }
 
-void elf_doRelocate_386(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff)
+int elf_doRelocate_386(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type,
+               int bRela, const char *Sym, intptr_t iBaseDiff)
 {
-       intptr_t        val;
+       void    *symval;
        switch( type )
        {
        // Standard 32 Bit Relocation (S+A)
        case R_386_32:
-               val = (intptr_t) GetSymbol(Sym, NULL);
-               DEBUGS(" elf_doRelocate: R_386_32 *0x%x += 0x%x('%s')",
-                               ptr, val, Sym);
-               *ptr = val + addend;
+               if( !GetSymbol(Sym, &symval, NULL) )
+                       return 1;
+               DEBUGS(" elf_doRelocate: R_386_32 *0x%x += %p('%s')",
+                               ptr, symval, Sym);
+               *ptr = (intptr_t)symval + addend;
                break;
                
        // 32 Bit Relocation wrt. Offset (S+A-P)
        case R_386_PC32:
                DEBUGS(" elf_doRelocate: '%s'", Sym);
-               val = (intptr_t) GetSymbol(Sym, NULL);
-               DEBUGS(" elf_doRelocate: R_386_PC32 *0x%x = 0x%x + 0x%x - 0x%x",
-                       ptr, *ptr, val, (intptr_t)ptr );
-               *ptr = val + addend - (intptr_t)ptr;
+               if( !GetSymbol(Sym, &symval, NULL) )    return 1;
+               DEBUGS(" elf_doRelocate: R_386_PC32 *0x%x = 0x%x + 0x%p - 0x%x",
+                       ptr, *ptr, symval, (intptr_t)ptr );
+               *ptr = (intptr_t)symval + addend - (intptr_t)ptr;
                //*ptr = val + addend - ((Uint)ptr - iBaseDiff);
                break;
 
@@ -114,9 +121,9 @@ void elf_doRelocate_386(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int t
        case R_386_GLOB_DAT:
        case R_386_JMP_SLOT:
                DEBUGS(" elf_doRelocate: '%s'", Sym);
-               val = (intptr_t) GetSymbol( Sym, NULL );
-               DEBUGS(" elf_doRelocate: %s *0x%x = 0x%x", csaR_NAMES[type], ptr, val);
-               *ptr = val;
+               if( !GetSymbol(Sym, &symval, NULL) )    return 1;
+               DEBUGS(" elf_doRelocate: %s *0x%x = %p", csaR_NAMES[type], ptr, symval);
+               *ptr = (intptr_t)symval;
                break;
 
        // Base Address (B+A)
@@ -127,18 +134,19 @@ void elf_doRelocate_386(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int t
 
        case R_386_COPY: {
                size_t  size;
-               void    *src = GetSymbol(Sym, &size);
-               DEBUGS(" elf_doRelocate_386: R_386_COPY (%p, %p, %i)", ptr, src, size);
-               memcpy(ptr, src, size);
+               if( !GetSymbol(Sym, &symval, &size) )   return 1;
+               DEBUGS(" elf_doRelocate_386: R_386_COPY (%p, %p, %i)", ptr, symval, size);
+               memcpy(ptr, symval, size);
                break; }
 
        default:
                SysDebug("elf_doRelocate_386: Unknown relocation %i", type);
-               break;
+               return 2;
        }
+       return 0;
 }
 
-void elf_doRelocate_arm(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff)
+int elf_doRelocate_arm(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff)
 {
        uint32_t        val;
        switch(type)
@@ -146,32 +154,35 @@ void elf_doRelocate_arm(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int t
        // (S + A) | T
        case R_ARM_ABS32:
                DEBUGS(" elf_doRelocate_arm: R_ARM_ABS32 %p (%s + %x)", ptr, Sym, addend);
-               val = (intptr_t)GetSymbol(Sym, NULL);
+               if( !GetSymbol(Sym, (void**)&val, NULL) )       return 1;
                *ptr = val + addend;
                break;
        case R_ARM_GLOB_DAT:
                DEBUGS(" elf_doRelocate_arm: R_ARM_GLOB_DAT %p (%s + %x)", ptr, Sym, addend);
-               val = (intptr_t)GetSymbol(Sym, NULL);
+               if( !GetSymbol(Sym, (void**)&val, NULL) )       return 1;
                *ptr = val + addend;
                break;
        case R_ARM_JUMP_SLOT:
                if(!bRela)      addend = 0;
                DEBUGS(" elf_doRelocate_arm: R_ARM_JUMP_SLOT %p (%s + %x)", ptr, Sym, addend);
-               val = (intptr_t)GetSymbol(Sym, NULL);
+               if( !GetSymbol(Sym, (void**)&val, NULL) )       return 1;
                *ptr = val + addend;
                break;
        // Copy
        case R_ARM_COPY: {
                size_t  size;
-               void    *src = GetSymbol(Sym, &size);
+               void    *src;
+               if( !GetSymbol(Sym, &src, &size) )      return 1;
                DEBUGS(" elf_doRelocate_arm: R_ARM_COPY (%p, %p, %i)", ptr, src, size);
                memcpy(ptr, src, size);
                break; }
        // Delta between link and runtime locations + A
        case R_ARM_RELATIVE:
+               DEBUGS(" elf_doRelocate_arm: R_ARM_RELATIVE %p (0x%x + 0x%x)", ptr, iBaseDiff, addend);
                if(Sym[0] != '\0') {
                        // TODO: Get delta for a symbol
                        SysDebug("elf_doRelocate_arm: TODO - Implment R_ARM_RELATIVE for symbols");
+                       return 2;
                }
                else {
                        *ptr = iBaseDiff + addend;
@@ -179,8 +190,14 @@ void elf_doRelocate_arm(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int t
                break;
        default:
                SysDebug("elf_doRelocate_arm: Unknown Relocation, %i", type);
-               break;
+               return 2;
        }
+       return 0;
+}
+
+int elf_doRelocate_unk(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff)
+{
+       return 1;
 }
 
 void *Elf32Relocate(void *Base, char **envp, const char *Filename)
@@ -202,8 +219,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
        Elf32_Dyn       *dynamicTab = NULL;     // Dynamic Table Pointer
        char    *dynstrtab = NULL;      // .dynamic String Table
        Elf32_Sym       *dynsymtab;
-       void    (*do_relocate)(uint32_t t_info, uint32_t *ptr, Elf32_Addr addend, int Type, int bRela, const char *Sym, intptr_t iBaseDiff);
-       auto void _doRelocate(uint32_t r_info, uint32_t *ptr, int bRela, Elf32_Addr addend);
+       int     (*do_relocate)(uint32_t t_info, uint32_t *ptr, Elf32_Addr addend, int Type, int bRela, const char *Sym, intptr_t iBaseDiff);
        
        DEBUGS("ElfRelocate: (Base=0x%x)", Base);
        
@@ -236,7 +252,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
        
        // Adjust "Real" Base
        iBaseDiff = (intptr_t)Base - iRealBase;
-       
+
 //     hdr->entrypoint += iBaseDiff;   // Adjust Entrypoint
        
        // Check if a PT_DYNAMIC segement was found
@@ -244,11 +260,24 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
                SysDebug(" elf_relocate: No PT_DYNAMIC segment in image %p, returning", Base);
                return (void *)(intptr_t)(hdr->entrypoint + iBaseDiff);
        }
-       
+
+       // Allow writing to read-only segments, just in case they need to be relocated
+       // - Will be reversed at the end of the function
+       for( i = 0; i < iSegmentCount; i ++ )
+       {
+               if(phtab[i].Type == PT_LOAD && !(phtab[i].Flags & PF_W) ) {
+                       uintptr_t       addr = phtab[i].VAddr + iBaseDiff;
+                       uintptr_t       end = addr + phtab[i].MemSize;
+                       for( ; addr < end; addr += PAGE_SIZE )
+                               SysSetMemFlags(addr, 0, 1);     // Unset RO
+               }
+       }
+
        // Adjust Dynamic Table
        dynamicTab = (void *)( (intptr_t)dynamicTab + iBaseDiff );
        
        // === Get Symbol table and String Table ===
+       dynsymtab = NULL;
        for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++)
        {
                switch(dynamicTab[j].d_tag)
@@ -340,13 +369,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
        
        DEBUGS(" elf_relocate: Beginning Relocation");
 
-       void _doRelocate(uint32_t r_info, uint32_t *ptr, int bRela, Elf32_Addr addend)
-       {
-                int    type = ELF32_R_TYPE(r_info);
-                int    sym = ELF32_R_SYM(r_info);
-               const char      *symname = dynstrtab + dynsymtab[sym].nameOfs;
-               do_relocate(r_info, ptr, addend, type, bRela, symname, iBaseDiff);
-       }
+        int    fail = 0;
 
        switch(hdr->machine)
        {
@@ -358,11 +381,17 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
                break;
        default:
                SysDebug("Elf32Relocate: Unknown machine type %i", hdr->machine);
+               do_relocate = elf_doRelocate_unk;
+               fail = 1;
                break;
        }
        
        DEBUGS("do_relocate = %p (%p or %p)", do_relocate, &elf_doRelocate_386, &elf_doRelocate_arm);
 
+       #define _doRelocate(r_info, ptr, bRela, addend) \
+               do_relocate(r_info, ptr, addend, ELF32_R_TYPE(r_info), bRela, \
+                       dynstrtab + dynsymtab[ELF32_R_SYM(r_info)].nameOfs, iBaseDiff);
+
        // Parse Relocation Entries
        if(rel && relSz)
        {
@@ -373,7 +402,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
                {
                        //DEBUGS("  Rel %i: 0x%x+0x%x", i, iBaseDiff, rel[i].r_offset);
                        ptr = (void*)(iBaseDiff + rel[i].r_offset);
-                       _doRelocate(rel[i].r_info, ptr, 0, *ptr);
+                       fail |= _doRelocate(rel[i].r_info, ptr, 0, *ptr);
                }
        }
        // Parse Relocation Entries
@@ -385,7 +414,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
                for( i = 0; i < j; i++ )
                {
                        ptr = (void*)(iBaseDiff + rela[i].r_offset);
-                       _doRelocate(rel[i].r_info, ptr, 1, rela[i].r_addend);
+                       fail |= _doRelocate(rel[i].r_info, ptr, 1, rela[i].r_addend);
                }
        }
        
@@ -402,7 +431,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
                        for(i=0;i<j;i++)
                        {
                                ptr = (void*)(iBaseDiff + pltRel[i].r_offset);
-                               _doRelocate(pltRel[i].r_info, ptr, 0, *ptr);
+                               fail |= _doRelocate(pltRel[i].r_info, ptr, 0, *ptr);
                        }
                }
                else
@@ -413,11 +442,30 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename)
                        for(i=0;i<j;i++)
                        {
                                ptr = (void*)(iRealBase + pltRela[i].r_offset);
-                               _doRelocate(pltRela[i].r_info, ptr, 1, pltRela[i].r_addend);
+                               fail |= _doRelocate(pltRela[i].r_info, ptr, 1, pltRela[i].r_addend);
                        }
                }
        }
-       
+
+       // Re-set readonly
+       for( i = 0; i < iSegmentCount; i ++ )
+       {
+               // If load and not writable
+               if(phtab[i].Type == PT_LOAD && !(phtab[i].Flags & PF_W) ) {
+                       uintptr_t       addr = phtab[i].VAddr + iBaseDiff;
+                       uintptr_t       end = addr + phtab[i].MemSize;
+                       for( ; addr < end; addr += PAGE_SIZE )
+                               SysSetMemFlags(addr, 1, 1);     // Unset RO
+               }
+       }
+
+       if( fail ) {
+               DEBUGS("ElfRelocate: Failure");
+               return NULL;
+       }       
+
+       #undef _doRelocate
+
        DEBUGS("ElfRelocate: RETURN 0x%x to %p", hdr->entrypoint + iBaseDiff, __builtin_return_address(0));
        return (void*)(intptr_t)( hdr->entrypoint + iBaseDiff );
 }
@@ -663,45 +711,54 @@ void *Elf64Relocate(void *Base, char **envp, const char *Filename)
        }
 
        // Relocation function
-       void _Elf64DoReloc(Elf64_Xword r_info, void *ptr, Elf64_Sxword addend)
+       auto int _Elf64DoReloc(Elf64_Xword r_info, void *ptr, Elf64_Sxword addend);
+       int _Elf64DoReloc(Elf64_Xword r_info, void *ptr, Elf64_Sxword addend)
        {
                 int    sym = ELF64_R_SYM(r_info);
                 int    type = ELF64_R_TYPE(r_info);
                const char      *symname = strtab + symtab[sym].st_name;
+               void    *symval;
+               //DEBUGS("_Elf64DoReloc: %s", symname);
                switch( type )
                {
                case R_X86_64_NONE:
                        break;
                case R_X86_64_64:
-                       *(uint64_t*)ptr = (uintptr_t)GetSymbol(symname, NULL) + addend;
+                       if( !GetSymbol(symname, &symval, NULL)  )       return 1;
+                       *(uint64_t*)ptr = (uintptr_t)symval + addend;
                        break;
                case R_X86_64_COPY: {
                        size_t  size;
-                       void    *symptr = GetSymbol(symname, &size);
-                       memcpy(ptr, symptr, size);
+                       if( !GetSymbol(symname, &symval, &size)  )      return 1;
+                       memcpy(ptr, symval, size);
                        } break;
                case R_X86_64_GLOB_DAT:
-                       *(uint64_t*)ptr = (uintptr_t)GetSymbol(symname, NULL);
+                       if( !GetSymbol(symname, &symval, NULL)  )       return 1;
+                       *(uint64_t*)ptr = (uintptr_t)symval;
                        break;
                case R_X86_64_JUMP_SLOT:
-                       *(uint64_t*)ptr = (uintptr_t)GetSymbol(symname, NULL);
+                       if( !GetSymbol(symname, &symval, NULL)  )       return 1;
+                       *(uint64_t*)ptr = (uintptr_t)symval;
                        break;
                case R_X86_64_RELATIVE:
                        *(uint64_t*)ptr = (uintptr_t)Base + addend;
                        break;
                default:
                        SysDebug("ld-acess - _Elf64DoReloc: Unknown relocation type %i", type);
-                       break;
+                       return 2;
                }
+               //DEBUGS("_Elf64DoReloc: - Good");
+               return 0;
        }
 
+       int fail = 0;
        if( rel )
        {
                DEBUGS("rel_count = %i", rel_count);
                for( i = 0; i < rel_count; i ++ )
                {
                        uint64_t *ptr = (void *)(uintptr_t)( rel[i].r_offset + baseDiff );
-                       _Elf64DoReloc( rel[i].r_info, ptr, *ptr);
+                       fail |= _Elf64DoReloc( rel[i].r_info, ptr, *ptr);
                }
        }
 
@@ -711,7 +768,7 @@ void *Elf64Relocate(void *Base, char **envp, const char *Filename)
                for( i = 0; i < rela_count; i ++ )
                {
                        uint64_t *ptr = (void *)(uintptr_t)( rela[i].r_offset + baseDiff );
-                       _Elf64DoReloc( rela[i].r_info, ptr, rela[i].r_addend );
+                       fail |= _Elf64DoReloc( rela[i].r_info, ptr, rela[i].r_addend );
                }
        }
 
@@ -724,7 +781,7 @@ void *Elf64Relocate(void *Base, char **envp, const char *Filename)
                        for( i = 0; i < count; i ++ )
                        {
                                uint64_t *ptr = (void *)(uintptr_t)( plt[i].r_offset + baseDiff );
-                               _Elf64DoReloc( plt[i].r_info, ptr, *ptr);
+                               fail |= _Elf64DoReloc( plt[i].r_info, ptr, *ptr);
                        }
                }
                else {
@@ -734,11 +791,16 @@ void *Elf64Relocate(void *Base, char **envp, const char *Filename)
                        for( i = 0; i < count; i ++ )
                        {
                                uint64_t *ptr = (void *)(uintptr_t)( plt[i].r_offset + baseDiff );
-                               _Elf64DoReloc( plt[i].r_info, ptr, plt[i].r_addend);
+                               fail |= _Elf64DoReloc( plt[i].r_info, ptr, plt[i].r_addend);
                        }
                }
        }
 
+       if( fail ) {
+               DEBUGS("Elf64Relocate: Failure");
+               return NULL;
+       }
+
        {
        void *ret = (void *)(uintptr_t)(hdr->e_entry + baseDiff);
        DEBUGS("Elf64Relocate: Relocations done, return %p", ret);
index 1cec11e..586078a 100644 (file)
@@ -11,7 +11,6 @@ extern int32_t        __modsi3(int32_t Num, int32_t Den);
 extern uint32_t        __udivsi3(uint32_t Num, uint32_t Den);
 extern uint32_t        __umodsi3(uint32_t Num, uint32_t Den);
 
-
 #define _STR(x)        #x
 #define STR(x) _STR(x)
 #define EXP(sym)       {&sym, STR(sym)}
@@ -35,6 +34,13 @@ const struct {
        #define __ASSEMBLER__
        #include "arch/syscalls.s.h"
        #undef __ASSEMBLER__
+       
+       #ifdef ARCHDIR_is_armv7
+       {0, "__gnu_Unwind_Find_exidx"},
+       {0, "__cxa_call_unexpected"},
+       {0, "__cxa_type_match"},
+       {0, "__cxa_begin_cleanup"},
+       #endif
 #if 0
        EXP(__umoddi3),
        EXP(__udivdi3),
index 2452972..88502b0 100644 (file)
@@ -49,7 +49,7 @@ extern int    _SysWaitEvent(int EventMask);
 extern int     waittid(int id, int *status);
 extern int     clone(int flags, void *stack);
 extern int     execve(char *path, char **argv, char **envp);
-extern int     _SysSpawn(const char *Path, const char **argv, const char **envp, int nFDs, int *FDs);
+extern int     _SysSpawn(const char *Path, const char **argv, const char **envp, int nFDs, int *FDs, struct s_sys_spawninfo *info);
 extern int     gettid(void);
 extern int     getpid(void);
 extern int     _SysSetFaultHandler(int (*Handler)(int));
@@ -90,5 +90,6 @@ extern int    SysGetMessage(pid_t *src, uint buflen, void *Data);
 // --- MEMORY ---
 uint64_t       _SysGetPhys(uint vaddr);
 uint64_t       _SysAllocate(uint vaddr);
+uint32_t       SysSetMemFlags(uint vaddr, uint32_t flags, uint32_t mask);
 
 #endif
diff --git a/Usermode/Libraries/ld-acess.so_src/include_exp/acess/syscall_types.h b/Usermode/Libraries/ld-acess.so_src/include_exp/acess/syscall_types.h
new file mode 100644 (file)
index 0000000..2da7333
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Acess2 Dynamic Linker
+ * - By John Hodge (thePowersGang)
+ *
+ * acess/syscall_types.h
+ * - Structures used for syscalls
+ */
+
+#ifndef _ACESS__SYSCALL_TYPES_H_
+#define _ACESS__SYSCALL_TYPES_H_
+
+struct s_sysACL {
+       unsigned long   object; /*!< Group or user (bit 31 determines) */
+       unsigned long   perms;  /*!< Inverted by bit 31 */
+};
+struct s_sysFInfo {
+       unsigned int    mount;
+       unsigned long long      inode;
+       unsigned int    uid;
+       unsigned int    gid;
+       unsigned int    flags;
+       unsigned long long      size;
+       time_t  atime;
+       time_t  mtime;
+       time_t  ctime;
+        int    numacls;
+       struct s_sysACL acls[];
+} __attribute__((packed));
+typedef struct s_sysFInfo      t_sysFInfo;
+typedef struct s_sysACL        t_sysACL;
+
+struct s_sys_spawninfo
+{
+       unsigned int    flags;
+       unsigned int    uid;
+       unsigned int    gid;
+};
+
+#endif
+
index 7c584d2..f71aed2 100644 (file)
@@ -30,25 +30,7 @@ typedef struct
        fd_set_ent_t    flags[FD_SETSIZE/16];
 }      fd_set;
 
-struct s_sysACL {
-       unsigned long   object; /*!< Group or user (bit 31 determines) */
-       unsigned long   perms;  /*!< Inverted by bit 31 */
-};
-struct s_sysFInfo {
-       unsigned int    mount;
-       unsigned long long      inode;
-       unsigned int    uid;
-       unsigned int    gid;
-       unsigned int    flags;
-       unsigned long long      size;
-       time_t  atime;
-       time_t  mtime;
-       time_t  ctime;
-        int    numacls;
-       struct s_sysACL acls[];
-} __attribute__((packed));
-typedef struct s_sysFInfo      t_sysFInfo;
-typedef struct s_sysACL        t_sysACL;
+#include "../acess/syscall_types.h"
 
 extern void    FD_ZERO(fd_set *fdsetp);
 extern void    FD_CLR(int fd, fd_set *fdsetp);
index 3f8e674..f59caf2 100644 (file)
@@ -15,7 +15,6 @@
 
 // === PROTOTYPES ===
 void   *IsFileLoaded(const char *file);
- int   GetSymbolFromBase(void *base, const char *name, void **ret, size_t *size);
 
 // === IMPORTS ===
 extern const struct {
@@ -88,6 +87,9 @@ void *LoadLibrary(const char *SoName, const char *SearchDir, char **envp)
        
        // Load Symbols
        fEntry = DoRelocate( base, envp, filename );
+       if( !fEntry ) {
+               return 0;
+       }
        
        // Call Entrypoint
        DEBUGS(" LoadLibrary: '%s' Entry %p", SoName, fEntry);
@@ -198,26 +200,31 @@ void Unload(void *Base)
  \fn Uint GetSymbol(const char *name)
  \brief Gets a symbol value from a loaded library
 */
-void *GetSymbol(const char *name, size_t *Size)
+int GetSymbol(const char *name, void **Value, size_t *Size)
 {
         int    i;
-       void    *ret;
        
        //SysDebug("ciNumLocalExports = %i", ciNumLocalExports);
        for(i=0;i<ciNumLocalExports;i++)
        {
-               if( strcmp(caLocalExports[i].Name, name) == 0 )
-                       return caLocalExports[i].Value;
+               if( strcmp(caLocalExports[i].Name, name) == 0 ) {
+                       *Value = caLocalExports[i].Value;
+                       if(Size)
+                               *Size = 0;
+                       return 1;
+               }
        }
        
        // Entry 0 is ld-acess, ignore it
        for(i = 1; i < MAX_LOADED_LIBRARIES; i ++)
        {
-               if(gLoadedLibraries[i].Base == 0)       break;
+               if(gLoadedLibraries[i].Base == 0)
+                       break;
                
                //SysDebug(" GetSymbol: Trying 0x%x, '%s'",
                //      gLoadedLibraries[i].Base, gLoadedLibraries[i].Name);
-               if(GetSymbolFromBase(gLoadedLibraries[i].Base, name, &ret, Size))       return ret;
+               if(GetSymbolFromBase(gLoadedLibraries[i].Base, name, Value, Size))
+                       return 1;
        }
        SysDebug("GetSymbol: === Symbol '%s' not found ===", name);
        return 0;
index 8d91173..04abfaf 100644 (file)
@@ -9,6 +9,7 @@
 #define _AXWIN3_AXWIN_H_
 
 #include <stddef.h>    // size_t
+#include <unistd.h>
 
 // === CONSTANTS ===
 
@@ -25,6 +26,7 @@ typedef int   (*tAxWin3_WindowMessageHandler)(tHWND Window, int Message, int Lengt
 extern void    AxWin3_Connect(const char *ServerDesc);
 extern tAxWin3_MessageCallback AxWin3_SetMessageCallback(tAxWin3_MessageCallback Callback);
 extern void    AxWin3_MainLoop(void);
+extern void    AxWin3_MessageSelect(int nFD, fd_set *FDs);
 
 // --- Non-Window based functions
 extern int     AxWin3_GetDisplayCount(void);
diff --git a/Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/richtext.h b/Usermode/Libraries/libaxwin3.so_src/include_exp/axwin3/richtext.h
new file mode 100644 (file)
index 0000000..661c02b
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Acess2 GUI Version 3 (AxWin3)
+ * - By John Hodge (thePowersGang)
+ *
+ * richtext.h
+ * - Rich Text line editor
+ */
+#ifndef _AXWIN3_RICHTEXT_H_
+#define _AXWIN3_RICHTEXT_H_
+
+#include <stdint.h>
+
+typedef        int     (*tAxWin3_RichText_KeyHandler)(tHWND Window, int bPress, uint32_t Sym, uint32_t Unicode);
+typedef int    (*tAxWin3_RichText_MouseHandler)(tHWND Window, int bPress, int Button, int Row, int Col);
+typedef int    (*tAxWin3_RichText_LineHandler)(tHWND Window, int Row);
+
+#define AXWIN3_RICHTEXT_NOSCROLL       0x0001  // Disables server-side scrolling
+#define AXWIN3_RICHTEXT_READONLY       0x0002  // Disables automatic insertion of translated characters
+enum eAxWin3_RichText_CursorType {
+       AXWIN3_RICHTEXT_CURSOR_NONE,
+       AXWIN3_RICHTEXT_CURSOR_VLINE,   // Vertical line
+       AXWIN3_RICHTEXT_CURSOR_ULINE,   // Underline
+       AXWIN3_RICHTEXT_CURSOR_INV,     // Inverted
+};
+
+extern tHWND   AxWin3_RichText_CreateWindow(tHWND Parent, int Flags);
+extern void    AxWin3_RichText_SetKeyHandler(tHWND Window, tAxWin3_RichText_KeyHandler Handler);
+extern void    AxWin3_RichText_SetMouseHandler(tHWND Window, tAxWin3_RichText_MouseHandler Handler);
+/**
+ * \brief Sets the function called when the server requests an update on a line's contents
+ */
+extern void    AxWin3_RichText_SetLineHandler(tHWND Window, tAxWin3_RichText_LineHandler Handler);
+extern void    AxWin3_RichText_EnableScroll(tHWND Window, int bEnable);
+extern void    AxWin3_RichText_SetLineCount(tHWND Window, int Lines);
+extern void    AxWin3_RichText_SetColCount(tHWND Window, int Cols);
+extern void    AxWin3_RichText_SetBackground(tHWND Window, uint32_t ARGB_Colour);
+extern void    AxWin3_RichText_SetDefaultColour(tHWND Window, uint32_t ARGB_Colour);
+extern void    AxWin3_RichText_SetFont(tHWND Window, const char *FontName, int PointSize);
+extern void    AxWin3_RichText_SetCursorType(tHWND Window, int Type);
+extern void    AxWin3_RichText_SetCursorBlink(tHWND Window, int bBlink);
+extern void    AxWin3_RichText_SetCursorPos(tHWND Window, int Row, int Column);
+extern void    AxWin3_RichText_SendLine(tHWND Window, int Line, const char *Text);
+
+#endif
+
index 9eca0b0..58386eb 100644 (file)
@@ -26,6 +26,7 @@ extern tAxWin3_Widget *AxWin3_Widget_GetRoot(tHWND Window);
 
 // --- Element Creation
 extern tAxWin3_Widget  *AxWin3_Widget_AddWidget(tAxWin3_Widget *Parent, int Type, int Flags, const char *DebugName);
+extern tAxWin3_Widget  *AxWin3_Widget_AddWidget_SubWindow(tAxWin3_Widget *Parent, tHWND Window, int Flags, const char *DebugName);
 extern void    AxWin3_Widget_DelWidget(tAxWin3_Widget *Widget);
 
 // --- Callbacks
index 6484897..d2c3190 100644 (file)
@@ -4,14 +4,14 @@
 -include ../Makefile.cfg\r
 \r
 CPPFLAGS += \r
-CFLAGS   += \r
+CFLAGS   += -Werror -Wextra\r
 ASFLAGS  +=\r
-LDFLAGS  += -soname libc.so -Map map.txt -lgcc\r
+LDFLAGS  += -soname libc.so -Map map.txt\r
 \r
 INCFILES := stdio.h stdlib.h\r
 \r
 OBJ  = stub.o heap.o stdlib.o env.o fileIO.o string.o select.o rand.o\r
-OBJ += perror.o\r
+OBJ += perror.o scanf.o signals.o\r
 OBJ += arch/$(ARCHDIR).ao\r
 # signals.o\r
 DEPFILES := $(OBJ:%.o=%.d)\r
index c0013c9..af8f007 100644 (file)
@@ -30,56 +30,80 @@ struct sFILE        *stderr;        // Standard Error
 ///\note Initialised in SoMain\r
 \r
 // === CODE ===\r
+int _fopen_modetoflags(const char *mode)\r
+{\r
+       int flags = 0;\r
+       \r
+       // Get main mode\r
+       switch(*mode)\r
+       {\r
+       case 'r':       flags = FILE_FLAG_MODE_READ;    break;\r
+       case 'w':       flags = FILE_FLAG_MODE_WRITE;   break;\r
+       case 'a':       flags = FILE_FLAG_MODE_APPEND;  break;\r
+       case 'x':       flags = FILE_FLAG_MODE_EXEC;    break;  // Acess addon\r
+       default:\r
+               return -1;\r
+       }\r
+       mode ++;\r
+\r
+       // Get Modifiers\r
+       for( ; *mode; mode ++ )\r
+       {\r
+               switch(*mode)\r
+               {\r
+               case 'b':       flags |= FILE_FLAG_M_BINARY;    break;\r
+               case '+':       flags |= FILE_FLAG_M_EXT;       break;\r
+               default:\r
+                       return -1;\r
+               }\r
+       }\r
+       \r
+       return flags;\r
+}\r
+\r
 /**\r
  * \fn FILE *freopen(char *file, char *mode, FILE *fp)\r
  */\r
 EXPORT FILE *freopen(const char *file, const char *mode, FILE *fp)\r
 {\r
         int    openFlags = 0;\r
-        int    i;\r
        \r
        // Sanity Check Arguments\r
        if(!fp || !file || !mode)       return NULL;\r
        \r
-       if(fp->Flags) {\r
+       if(fp->FD != -1) {\r
                fflush(fp);\r
-       } else\r
-               fp->FD = -1;\r
-       \r
-       // Get main mode\r
-       switch(mode[0])\r
-       {\r
-       case 'r':       fp->Flags = FILE_FLAG_MODE_READ;        break;\r
-       case 'w':       fp->Flags = FILE_FLAG_MODE_WRITE;       break;\r
-       case 'a':       fp->Flags = FILE_FLAG_MODE_APPEND;      break;\r
-       case 'x':       fp->Flags = FILE_FLAG_MODE_EXEC;        break;\r
-       default:\r
-               return NULL;\r
-       }\r
-       // Get Modifiers\r
-       for(i=1;mode[i];i++)\r
-       {\r
-               switch(mode[i])\r
-               {\r
-               case '+':       fp->Flags |= FILE_FLAG_M_EXT;\r
-               }\r
        }\r
+\r
+       // Get stdio flags\r
+       fp->Flags = _fopen_modetoflags(mode);\r
+       if(fp->Flags == -1)\r
+               return NULL;\r
        \r
        // Get Open Flags\r
-       switch(mode[0])\r
+       switch(fp->Flags & FILE_FLAG_MODE_MASK)\r
        {\r
        // Read\r
-       case 'r':       openFlags = OPENFLAG_READ;\r
+       case FILE_FLAG_MODE_READ:\r
+               openFlags = OPENFLAG_READ;\r
                if(fp->Flags & FILE_FLAG_M_EXT)\r
                        openFlags |= OPENFLAG_WRITE;\r
                break;\r
        // Write\r
-       case 'w':       openFlags = OPENFLAG_WRITE;\r
+       case FILE_FLAG_MODE_WRITE:\r
+               openFlags = OPENFLAG_WRITE;\r
                if(fp->Flags & FILE_FLAG_M_EXT)\r
                        openFlags |= OPENFLAG_READ;\r
                break;\r
        // Execute\r
-       case 'x':       openFlags = OPENFLAG_EXEC;\r
+       case FILE_FLAG_MODE_APPEND:\r
+               openFlags = OPENFLAG_APPEND;\r
+               if(fp->Flags & FILE_FLAG_M_EXT)\r
+                       openFlags |= OPENFLAG_READ;\r
+               break;\r
+       // Execute\r
+       case FILE_FLAG_MODE_EXEC:\r
+               openFlags = OPENFLAG_EXEC;\r
                break;\r
        }\r
 \r
@@ -93,7 +117,7 @@ EXPORT FILE *freopen(const char *file, const char *mode, FILE *fp)
                return NULL;\r
        }\r
        \r
-       if(mode[0] == 'a') {\r
+       if( (fp->Flags & FILE_FLAG_MODE_MASK) == FILE_FLAG_MODE_APPEND ) {\r
                seek(fp->FD, 0, SEEK_END);      //SEEK_END\r
        }\r
        \r
@@ -118,9 +142,34 @@ EXPORT FILE *fopen(const char *file, const char *mode)
        return freopen(file, mode, retFile);\r
 }\r
 \r
+EXPORT FILE *fmemopen(void *buffer, size_t length, const char *mode)\r
+{\r
+       FILE    *ret;\r
+       \r
+       if( !buffer || !mode )  return NULL;\r
+       \r
+       ret = get_file_struct();\r
+       \r
+       ret->FD = -2;\r
+       ret->Flags = _fopen_modetoflags(mode);\r
+       if(ret->Flags == -1) {\r
+               ret->Flags = 0;\r
+               return NULL;\r
+       }\r
+       \r
+       ret->Buffer = buffer;\r
+       ret->BufferStart = 0;\r
+       ret->BufferSize = length;\r
+       \r
+       return ret;\r
+}\r
+\r
 EXPORT int fclose(FILE *fp)\r
 {\r
-       close(fp->FD);\r
+       fflush(fp);\r
+       if( fp->FD != -1 ) {\r
+               close(fp->FD);\r
+       }\r
        fp->Flags = 0;\r
        fp->FD = -1;\r
        return 0;\r
@@ -128,21 +177,36 @@ EXPORT int fclose(FILE *fp)
 \r
 EXPORT void fflush(FILE *fp)\r
 {\r
-       ///\todo Implement\r
+       if( !fp || fp->FD == -1 )\r
+               return ;\r
+       \r
+       if( !(fp->Flags & FILE_FLAG_DIRTY) )\r
+               return ;\r
+       \r
+       // Nothing to do for memory files\r
+       if( fp->FD == -2 )\r
+               return ;\r
 }\r
 \r
-EXPORT void clearerr(FILE *stream)\r
+EXPORT void clearerr(FILE *fp)\r
 {\r
-       /// \todo Impliment\r
+       if( !fp || fp->FD == -1 )\r
+               return ;\r
+       \r
+       // TODO: Impliment clearerr()\r
 }\r
 \r
-EXPORT int feof(FILE *stream)\r
+EXPORT int feof(FILE *fp)\r
 {\r
-       return 0;       //stream->;     // ?\r
+       if( !fp || fp->FD == -1 )\r
+               return 0;\r
+       return !!(fp->Flags & FILE_FLAG_EOF);\r
 }\r
 \r
-EXPORT int ferror(FILE *stream)\r
+EXPORT int ferror(FILE *fp)\r
 {\r
+       if( !fp || fp->FD == -1 )\r
+               return 0;\r
        return 0;\r
 }\r
 EXPORT int fileno(FILE *stream)\r
@@ -152,16 +216,42 @@ EXPORT int fileno(FILE *stream)
 \r
 EXPORT off_t ftell(FILE *fp)\r
 {\r
-       if(!fp || !fp->FD)      return -1;\r
-       \r
-       return tell(fp->FD);\r
+       if(!fp || fp->FD == -1) return -1;\r
+\r
+       if( fp->FD == -2 )\r
+               return fp->Pos; \r
+       else\r
+               return tell(fp->FD);\r
 }\r
 \r
 EXPORT int fseek(FILE *fp, long int amt, int whence)\r
 {\r
-       if(!fp || !fp->FD)      return -1;\r
-       \r
-       return seek(fp->FD, amt, whence);\r
+       if(!fp || fp->FD == -1) return -1;\r
+\r
+       if( fp->FD == -2 ) {\r
+               switch(whence)\r
+               {\r
+               case SEEK_CUR:\r
+                       fp->Pos += amt;\r
+                       break;\r
+               case SEEK_SET:\r
+                       fp->Pos = amt;\r
+                       break;\r
+               case SEEK_END:\r
+                       if( fp->BufferSize < (size_t)amt )\r
+                               fp->Pos = 0;\r
+                       else\r
+                               fp->Pos = fp->BufferSize - amt;\r
+                       break;\r
+               }\r
+               if(fp->Pos > (off_t)fp->BufferSize) {\r
+                       fp->Pos = fp->BufferSize;\r
+                       fp->Flags |= FILE_FLAG_EOF;\r
+               }\r
+               return 0;\r
+       }\r
+       else\r
+               return seek(fp->FD, amt, whence);\r
 }\r
 \r
 \r
@@ -183,10 +273,7 @@ EXPORT int vfprintf(FILE *fp, const char *format, va_list args)
        vsnprintf(buf, size+1, (char*)format, args);\r
        \r
        // Write to stream\r
-       write(fp->FD, buf, size);\r
-       \r
-       // Free buffer\r
-       free(buf);\r
+       fwrite(buf, size, 1, fp);\r
        \r
        // Return written byte count\r
        return size;\r
@@ -215,10 +302,25 @@ EXPORT int fprintf(FILE *fp, const char *format, ...)
  */\r
 EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp)\r
 {\r
-        int    ret;\r
-       if(!fp || !fp->FD)      return -1;\r
-       \r
-       ret = write(fp->FD, ptr, size*num);\r
+       size_t  ret;\r
+       \r
+       if(!fp || fp->FD == -1)\r
+               return -1;\r
+\r
+       if( fp->FD == -2 ) {\r
+               size_t  avail = (fp->BufferSize - fp->Pos) / size;\r
+               if( avail == 0 )\r
+                       fp->Flags |= FILE_FLAG_EOF;\r
+               if( num > avail )       num = avail;\r
+               size_t  bytes = num * size;\r
+               memcpy((char*)fp->Buffer + fp->Pos, ptr, bytes);\r
+               fp->Pos += bytes;\r
+               ret = num;\r
+       }\r
+       else {  \r
+               ret = write(fp->FD, ptr, size*num);\r
+               ret /= size;\r
+       }\r
        \r
        return ret;\r
 }\r
@@ -229,12 +331,26 @@ EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp)
  */\r
 EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp)\r
 {\r
-        int    ret;\r
-       if(!fp || !fp->FD)      return -1;\r
-\r
-       // TODO: Fit the spec better with the return value      \r
-       ret = read(fp->FD, ptr, size*num);\r
-       \r
+       size_t  ret;\r
+       \r
+       if(!fp || fp->FD == -1)\r
+               return -1;\r
+\r
+       if( fp->FD == -2 ) {\r
+               size_t  avail = (fp->BufferSize - fp->Pos) / size;\r
+               if( avail == 0 )\r
+                       fp->Flags |= FILE_FLAG_EOF;\r
+               if( num > avail )       num = avail;\r
+               size_t  bytes = num * size;\r
+               memcpy(ptr, (char*)fp->Buffer + fp->Pos, bytes);\r
+               fp->Pos += bytes;\r
+               ret = num;\r
+       }\r
+       else {\r
+               ret = read(fp->FD, ptr, size*num);\r
+               ret /= size;\r
+       }\r
+               \r
        return ret;\r
 }\r
 \r
@@ -244,8 +360,7 @@ EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp)
  */\r
 EXPORT int fputc(int c, FILE *fp)\r
 {\r
-       if(!fp || !fp->FD)      return -1;\r
-       return write(fp->FD, &c, 1);\r
+       return fwrite(&c, 1, 1, fp);\r
 }\r
 \r
 EXPORT int putchar(int c)\r
@@ -261,8 +376,8 @@ EXPORT int putchar(int c)
 EXPORT int fgetc(FILE *fp)\r
 {\r
        char    ret = 0;\r
-       if(!fp) return -1;\r
-       if(read(fp->FD, &ret, 1) == -1) return -1;\r
+       if( fread(&ret, 1, 1, fp) == (size_t)-1 )\r
+               return -1;\r
        return ret;\r
 }\r
 \r
@@ -283,7 +398,12 @@ FILE *get_file_struct()
         int    i;\r
        for(i=0;i<STDIO_MAX_STREAMS;i++)\r
        {\r
-               if(_iob[i].Flags == 0)  return &_iob[i];\r
+               if(_iob[i].Flags & FILE_FLAG_ALLOC)\r
+                       continue ;\r
+               _iob[i].Flags |= FILE_FLAG_ALLOC;\r
+               _iob[i].FD = -1;\r
+               _iob[i].Pos = 0;\r
+               return &_iob[i];\r
        }\r
        return NULL;\r
 }\r
@@ -317,7 +437,7 @@ EXPORT int vsnprintf(char *buf, size_t __maxlen, const char *format, va_list arg
 {\r
        char    tmp[65];\r
         int    c, minSize, precision, len;\r
-        int    pos = 0;\r
+       size_t  pos = 0;\r
        char    *p;\r
        char    pad;\r
        uint64_t        arg;\r
@@ -547,7 +667,6 @@ EXPORT void itoa(char *buf, uint64_t num, size_t base, int minLength, char pad,
  */\r
 EXPORT int printf(const char *format, ...)\r
 {\r
-       #if 1\r
         int    size;\r
        va_list args;\r
        \r
@@ -568,16 +687,6 @@ EXPORT int printf(const char *format, ...)
        free(buf);\r
        // Return\r
        return size;\r
-       \r
-       #else\r
-       \r
-        int    ret;\r
-       va_list args;\r
-       va_start(args, format);\r
-       ret = fprintfv(stdout, (char*)format, args);\r
-       va_end(args);\r
-       return ret;\r
-       #endif\r
 }\r
 \r
 /**\r
index d529f65..bdf64de 100644 (file)
@@ -185,7 +185,7 @@ EXPORT void free(void *mem)
        DEBUGS("free(%p) : 0x%x bytes", mem, head->size);\r
        \r
        //Unify Right\r
-       if((intptr_t)head + head->size < (intptr_t)_heap_end)\r
+       if((uintptr_t)head + head->size < (uintptr_t)_heap_end)\r
        {\r
                heap_head       *nextHead = (heap_head*)((intptr_t)head + head->size);\r
                if(nextHead->magic == MAGIC_FREE) {     //Is the next block free\r
@@ -194,7 +194,7 @@ EXPORT void free(void *mem)
                }\r
        }\r
        //Unify Left\r
-       if((intptr_t)head - sizeof(heap_foot) > (intptr_t)_heap_start)\r
+       if((uintptr_t)head - sizeof(heap_foot) > (uintptr_t)_heap_start)\r
        {\r
                heap_head       *prevHead;\r
                heap_foot       *prevFoot = (heap_foot *)((intptr_t)head - sizeof(heap_foot));\r
index 4c5613b..ddb0a61 100644 (file)
@@ -35,5 +35,11 @@ static inline int isspace(int ch) {
        if(ch == '\n')  return 1;
        return 0;
 }
+// C99
+static inline int isblank(int ch) {
+       if(ch == ' ')   return 1;
+       if(ch == '\t')  return 1;
+       return 0;
+}
 
 #endif
index cc72b00..bf03c7f 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef _SIGNAL_H_
 #define _SIGNAL_H_
 
+typedef void (*sighandler_t)(int);
+
 #define SIG_DFL        ((void*)0)
 #define SIG_ERR        ((void*)-1)
 
@@ -16,5 +18,7 @@
 #define SIGPIPE        1001
 #define SIGCHLD        1002
 
+extern int     raise(int sig);
+
 #endif
 
index faf20f0..d8643eb 100644 (file)
@@ -45,6 +45,14 @@ extern int   putchar(int ch);
 extern int     fprintf(FILE *fp, const char *format, ...);
 extern int     vfprintf(FILE *fp, const char *format, va_list args);
 
+// scanf
+extern int     scanf(const char *format, ...);
+extern int     fscanf(FILE *stream, const char *format, ...);
+extern int     sscanf(const char *str, const char *format, ...);
+extern int     vscanf(const char *format, va_list ap);
+extern int     vsscanf(const char *str, const char *format, va_list ap);
+extern int     vfscanf(FILE *stream, const char *format, va_list ap);
+
 extern FILE    *stdin;
 extern FILE    *stdout;
 extern FILE    *stderr;
index 8acfb8b..dbe557f 100644 (file)
@@ -24,6 +24,7 @@ extern long long      strtoll(const char *ptr, char **end, int base);
 extern long    strtol(const char *ptr, char **end, int base);\r
 extern int     atoi(const char *ptr);\r
 extern void    exit(int status) __attribute__((noreturn));\r
+extern void    abort(void);\r
 extern void    atexit(void (*__func)(void));\r
 extern void    qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));\r
 extern int     abs(int j);\r
index 9f773dc..9e91c9f 100644 (file)
@@ -18,6 +18,8 @@
 #define        LOCAL\r
 #endif\r
 \r
+#define UNUSED(type, param)    __attribute__((unused)) type UNUSED__##param\r
+\r
 extern void *memcpy(void *dest, const void *src, size_t n);\r
 \r
 typedef struct sCPUID  tCPUID;\r
diff --git a/Usermode/Libraries/libc.so_src/scanf.c b/Usermode/Libraries/libc.so_src/scanf.c
new file mode 100644 (file)
index 0000000..3a561c4
--- /dev/null
@@ -0,0 +1,445 @@
+/*
+ * Acess2 C Library
+ * - By John Hodge (thePowersGang)
+ *
+ * scanf.c
+ * - *scanf family of functions
+ */
+#include <stdio.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <string.h>
+
+extern void    _SysDebug(const char *format, ...);
+
+enum e_vcscanf_types
+{
+       _VCSCANF_NOTYPE,
+       _VCSCANF_INT,
+       _VCSCANF_REAL,
+};
+
+enum e_vcscanf_sizes
+{
+       _VCSCANF_UNDEF,
+       _VCSCANF_CHAR,
+       _VCSCANF_SHORT,
+       _VCSCANF_LONG,
+       _VCSCANF_LONGLONG,
+       _VCSCANF_INTMAX,
+       _VCSCANF_SIZET,
+       _VCSCANF_PTRDIFF,
+       _VCSCANF_LONGDOUBLE
+};
+
+// === CODE ===
+int _vcscanf_int(int (*__getc)(void *), void (*__rewind)(void*), void *h, int base, int maxlen, long long *outval)
+{
+       char    ich;
+        int    sgn = 1;
+       long long int   ret = 0;
+        int    n_read = 0;
+
+       // Initialise output to something sane
+       *outval = 0;
+
+       // First character
+       // - maxlen == 0 means no limit
+       ich = __getc(h);
+       n_read ++;
+       
+       // Sign?
+       if( ich == '-' || ich == '+' ) {
+               sgn = (ich == '-' ? -1 : 1);
+               if( n_read == maxlen )
+                       return n_read;
+               ich = __getc(h);
+               n_read ++;
+       }
+       
+       // Determine base
+       if( base == 0 ) {
+               if( ich != '0' ) {
+                       base = 10;
+               }
+               else {
+                       if( n_read == maxlen )
+                               return n_read;
+                       ich = __getc(h);
+                       n_read ++;
+                       if( ich != 'x' ) {
+                               base = 8;
+                       }
+                       else {
+                               base = 16;
+                               if( n_read == maxlen )
+                                       return n_read;
+                               ich = __getc(h);
+                               n_read ++;
+                       }
+               }
+       }
+       
+       if( ich == 0 ) {
+               // Oops?
+               return n_read;
+       }
+       
+       while( ich )
+       {
+                int    next = -1;
+               
+               // Get the digit value
+               if( base <= 10 ) {
+                       if( '0' <= ich && ich <= '0'+base-1 )
+                               next = ich - '0';
+               }
+               else {
+                       if( '0' <= ich && ich <= '9' )
+                               next = ich - '0';
+                       if( 'A' <= ich && ich <= 'A'+base-10-1 )
+                               next = ich - 'A' + 10;
+                       if( 'a' <= ich && ich <= 'a'+base-10-1 )
+                               next = ich - 'a' + 10;
+               }
+               // if it's not a digit, rewind and break
+               if( next < 0 ) {
+                       __rewind(h);
+                       n_read --;
+                       break;
+               }
+               
+               // Add to the result
+               ret *= base;
+               ret += next;
+               //_SysDebug("- %i/%i read, 0x%x val", n_read, maxlen, ret);
+
+               // Check if we've reached the limit
+               if( n_read == maxlen )
+                       break ;
+
+               // Next character
+               ich = __getc(h);
+               n_read ++;
+       }
+       
+       // Apply sign
+       if( sgn == -1 )
+               ret = -ret;
+
+       *outval = ret;
+       return n_read;
+}
+
+int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char *format, va_list ap)
+{
+       char    fch, ich;
+        int    ret = 0, nch = 0;
+       
+       while( (fch = *format++) )
+       {
+               union {
+                       void    *_void;
+                       char    *_char;
+                       short   *_short;
+                        int    *_int;
+                       long    *_long;
+                       long long       *_longlong;
+               }       ptr;
+               long long       ival;
+               //long double   rval;
+                int    maxlen = 0, offset = -1;
+               enum e_vcscanf_sizes    size = _VCSCANF_UNDEF;
+               enum e_vcscanf_types    valtype;
+
+               const char      *set_start;
+                int    set_len;                
+
+               // Whitespace matches any ammount of whitespace (including none)
+               if( isspace(fch) )
+               {
+                       while( (ich = __getc(h)) && isspace(ich) )
+                               nch ++;
+                       continue ;
+               }
+               
+               // Any non-whitespace and non-% characters must match exactly
+               if( fch != '%' )
+               {
+                       if( __getc(h) != fch )
+                               break;
+                       nch ++;
+                       continue ;
+               }
+               
+               // Format specifier
+               fch = *format++;
+               if(!fch)        break;
+
+               // Catch '%%' early
+               if( fch == '%' ) {
+                       if( __getc(h) != '%' )
+                               break;
+                       nch ++;
+                       continue ;
+               }               
+
+               // %n$ - Direct offset selection, shouldn't be mixed with just %
+               for( ; isdigit(fch); fch = *format++ )
+                       maxlen = maxlen * 10 + (fch - '0');
+               if( fch == '$' ) {
+                       offset = maxlen;
+                       maxlen = 0;
+               }
+               
+               // Supress assignemnt?
+               if( fch == '*' )
+               {
+                       fch = *format++;
+                       ptr._void = NULL;
+                       ret --;
+               }
+               else
+                       ptr._void = va_arg(ap, void*);
+               
+               // Max field length
+               while( isdigit(fch) )
+               {
+                       maxlen = maxlen * 10 + fch - '0';
+                       fch = *format++;
+               }
+               
+               // Length modifier
+               switch( fch )
+               {
+               case 'h':
+                       // 'short'
+                       size = _VCSCANF_SHORT;
+                       fch = *format++;
+                       if( fch == 'h' ) {
+                               // 'char'
+                               size = _VCSCANF_CHAR;
+                               fch = *format++;
+                       }
+                       break;
+               case 'l':
+                       // 'long'
+                       size = _VCSCANF_LONG;
+                       fch = *format++;
+                       if( fch == 'l' ) {
+                               // 'long long'
+                               size = _VCSCANF_LONGLONG;
+                               fch = *format++;
+                       }
+                       break;
+               case 'j':
+                       // '(u)intmax_t'
+                       size = _VCSCANF_INTMAX;
+                       fch = *format++;
+                       break;
+               case 'z':
+                       // 'size_t'
+                       size = _VCSCANF_SIZET;
+                       fch = *format++;
+                       break;
+               case 't':
+                       // 'ptrdiff_t'
+                       size = _VCSCANF_PTRDIFF;
+                       fch = *format++;
+                       break;
+               case 'L':
+                       // 'long double' (a, A, e, E, f, F, g, G)
+                       size = _VCSCANF_LONGDOUBLE;
+                       fch = *format++;
+                       break;
+               }
+               
+               // Format specifiers
+               switch( fch )
+               {
+               // Decimal integer
+               case 'd':
+                       nch += _vcscanf_int(__getc, __rewind, h, 10, maxlen, &ival);
+                       valtype = _VCSCANF_INT;
+                       break;
+               // variable-base integer
+               case 'i':
+                       nch += _vcscanf_int(__getc, __rewind, h, 0, maxlen, &ival);
+                       valtype = _VCSCANF_INT;
+                       break;
+               // Octal integer
+               case 'o':
+                       nch += _vcscanf_int(__getc, __rewind, h, 8, maxlen, &ival);
+                       valtype = _VCSCANF_INT;
+                       break;
+               // Hexadecimal integer
+               case 'x': case 'X':
+                       nch += _vcscanf_int(__getc, __rewind, h, 16, maxlen, &ival);
+                       valtype = _VCSCANF_INT;
+                       break;
+               // strtod format float
+               case 'a': case 'A':
+               case 'e': case 'E':
+               case 'f': case 'F':
+               case 'g': case 'G':
+                       valtype = _VCSCANF_REAL;
+                       break;
+               // `maxlen` or 1 characters
+               case 'c':
+                       if( maxlen == 0 )
+                               maxlen = 1;
+                       while( maxlen -- && (ich = __getc(h)) )
+                       {
+                               if(ptr._char)   *ptr._char++ = ich;
+                               nch ++;
+                       }
+                       valtype = _VCSCANF_NOTYPE;
+                       break;
+               // sequence of non-whitespace characters
+               case 's':
+                       if( maxlen == 0 )
+                               maxlen = -1;
+
+                       ich = 0;
+                       while( maxlen -- && (ich = __getc(h)) && !isblank(ich) )
+                       {
+                               if(ptr._char)   *ptr._char++ = ich;
+                               nch ++;
+                       }
+                       if( maxlen >= 0 && ich )
+                               __rewind(h);
+                       valtype = _VCSCANF_NOTYPE;
+                       break;
+               // match a set of characters
+               case '[':
+                       fch = *format++;
+                       if( fch == '^' ) {
+                               // Invert
+                               fch = *format;
+                       }
+                       set_start = format;
+                       set_len = 0;
+                       // if the first character is ']' it's part of the set
+                       do {
+                               // permissable character
+                               set_len ++;
+                               fch = *format++;
+                       } while( fch && fch != ']' );
+
+                       ich = 0;
+                       while( maxlen -- && (ich = __getc(h)) && memchr(set_start, set_len, ich) )
+                       {
+                               if(ptr._char)   *ptr._char++ = ich;
+                               nch ++;
+                       }
+                       if( maxlen >= 0 && ich )
+                               __rewind(h);
+                       valtype = _VCSCANF_NOTYPE;
+                       break;
+               case 'p': // read back printf("%p")
+                       valtype = _VCSCANF_NOTYPE;
+                       break;
+               case 'n': // number of read characters to this point
+                       if(ptr._int) {
+                               *ptr._int = nch;
+                               ret --; // negates the ret ++ at the end
+                       }
+                       valtype = _VCSCANF_NOTYPE;
+                       break;
+               default:
+                       // Implimentation defined
+                       valtype = _VCSCANF_NOTYPE;
+                       break;
+               }
+               
+               switch(valtype)
+               {
+               case _VCSCANF_NOTYPE:
+                       // Used when assignment is done above
+                       break;
+               case _VCSCANF_INT:
+                       switch(size)
+                       {
+                       case _VCSCANF_UNDEF:    *ptr._int = ival;       break;
+                       case _VCSCANF_CHAR:     *ptr._char = ival;      break;
+                       case _VCSCANF_SHORT:    *ptr._short = ival;     break;
+                       case _VCSCANF_LONG:     *ptr._long = ival;      break;
+                       case _VCSCANF_LONGLONG: *ptr._longlong = ival;  break;
+                       default:        // ???
+                               break;
+                       }
+                       break;
+               case _VCSCANF_REAL:
+                       break;
+               }
+               
+               ret ++;
+       }
+       
+       return ret;
+}
+
+int _vsscanf_getc(void *h)
+{
+       const char      **ibuf = h;
+       return *(*ibuf)++;      // Dereference, read for return, increment
+}
+
+void _vsscanf_rewind(void *h)
+{
+       const char      **ibuf = h;
+       (*ibuf) --;     // NOTE: Breaks if there's a rewind before a getc, but that shouldn't happen
+}
+
+int vscanf(const char *format, va_list ap)
+{
+       return vfscanf(stdin, format, ap);
+}
+
+int vsscanf(const char *str, const char *format, va_list ap)
+{
+       return _vcscanf(_vsscanf_getc, _vsscanf_rewind, &str, format, ap);
+}
+
+int _vfscanf_getc(void *h)
+{
+       return fgetc(h);        // TODO: Handle -1 -> 0
+}
+void _vfscanf_rewind(void *h)
+{
+       fseek(h, -1, SEEK_CUR);
+}
+
+int vfscanf(FILE *stream, const char *format, va_list ap)
+{
+       return _vcscanf(_vfscanf_getc, _vfscanf_rewind, stream, format, ap);
+}
+
+int scanf(const char *format, ...)
+{
+       va_list args;
+        int    rv;
+       va_start(args, format);
+       rv = vfscanf(stdin, format, args);
+       va_end(args);
+       return rv;
+}
+int fscanf(FILE *stream, const char *format, ...)
+{
+       va_list args;
+        int    rv;
+       va_start(args, format);
+       rv = vfscanf(stream, format, args);
+       va_end(args);
+       return rv;
+}
+int sscanf(const char *str, const char *format, ...)
+{
+       va_list args;
+        int    rv;
+       va_start(args, format);
+       rv = vsscanf(str, format, args);
+       va_end(args);
+       return rv;
+}
+
index ddaf544..f8b71d3 100644 (file)
@@ -2,7 +2,7 @@
  * AcessOS Basic C Library
  * signals.c
 */
-#include <syscalls.h>
+//#include <acess/sys.h>
 #include <stdlib.h>
 #include <signal.h>
 #include "lib.h"
@@ -22,3 +22,22 @@ sighandler_t signal(int num, sighandler_t handler)
        sighandlers[num] = handler;
        return prev;
 }
+
+int raise(int signal)
+{
+       if( signal < 0 || signal > NUM_SIGNALS )
+               return 1;
+       switch(signal)
+       {
+       case SIGABRT:
+               abort();
+               break;
+       }
+       return 0;
+}
+
+void abort(void)
+{
+       // raise(SIGABRT);
+       _exit(-1);
+}
index 5bfbf98..f87da81 100644 (file)
@@ -4,28 +4,35 @@
  * Configuration Options
  */
 #ifndef _STDIO_INT_H
-# define _STDIO_INT_H
+#define _STDIO_INT_H
+
+#include <sys/types.h>
+#include <stddef.h>
 
 // === CONSTANTS ===
-#define FILE_FLAG_MODE_MASK    0x07
-#define FILE_FLAG_MODE_READ            0x01
-#define FILE_FLAG_MODE_WRITE   0x02
-#define FILE_FLAG_MODE_EXEC            0x03
-#define FILE_FLAG_MODE_APPEND  0x04
-#define FILE_FLAG_M_EXT                0x10
+#define FILE_FLAG_MODE_MASK    0x0007
+#define FILE_FLAG_MODE_READ    0x0001
+#define FILE_FLAG_MODE_WRITE   0x0002
+#define FILE_FLAG_MODE_EXEC    0x0003
+#define FILE_FLAG_MODE_APPEND  0x0004
+#define FILE_FLAG_M_EXT        0x0010
+#define FILE_FLAG_M_BINARY     0x0020
+#define FILE_FLAG_EOF          0x0100
+#define FILE_FLAG_DIRTY        0x0200
+#define FILE_FLAG_ALLOC        0x1000
 
 // === TYPES ===
 struct sFILE {
-        int    FD;
         int    Flags;
+        int    FD;
+       off_t   Pos;    
+
        #if DEBUG_BUILD
-       char    *FileName;
-       #endif
-       #if STDIO_LOCAL_BUFFER
-       char    *Buffer;
-       Uint64  BufferStart;
-        int    BufferSize;
+       char    *FileName;      // heap
        #endif
+       void    *Buffer;
+       off_t   BufferStart;
+       size_t  BufferSize;
 };
 
 #endif
index c91106c..469f51c 100644 (file)
@@ -48,7 +48,7 @@ EXPORT void exit(int status)
  */\r
 EXPORT void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *))\r
 {\r
-        int    i, j, min;\r
+       size_t  i, j, min;\r
        // With 0 items, there's nothing to do and with 1 its already sorted\r
        if(nmemb == 0 || nmemb == 1)    return;\r
        \r
index 3cadee9..d8d0872 100644 (file)
@@ -273,7 +273,7 @@ EXPORT void *memmove(void *dest, const void *src, size_t count)
        char *sp = (char *)src;
        char *dp = (char *)dest;
        // Check if the areas overlap
-       if( (intptr_t)src < (intptr_t)dest && (intptr_t)dest < (intptr_t)src+count )
+       if( (uintptr_t)src < (uintptr_t)dest && (uintptr_t)dest < (uintptr_t)src+count )
                for(;count--;)
                        dp[count] = sp[count];
        else
index 2494fc2..7cde4c1 100644 (file)
@@ -44,7 +44,7 @@ tCPUID        gCPU_Features;
  * \param argv Unused - Arguments (NULL for current version of ld-acess)\r
  * \param envp Environment Pointer\r
  */\r
-int SoMain(unsigned int BaseAddress, int argc, char **argv, char **envp)\r
+int SoMain(UNUSED(uintptr_t, BaseAddress), UNUSED(int, argc), UNUSED(char **, argv), char **envp)\r
 {\r
        // Init for env.c\r
        _envp = envp;\r

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