Cleanup Commit
authorJohn Hodge <[email protected]>
Sat, 27 Mar 2010 01:59:42 +0000 (09:59 +0800)
committerJohn Hodge <[email protected]>
Sat, 27 Mar 2010 01:59:42 +0000 (09:59 +0800)
- Adding a hell of a lot of files to the tree
 > EDI Interface (Incomplete)
 > AxWin Shell (Incomplete, Needs to be rewritten)
 > AxWin library and headers
- Restructuring AxWin to be non-windowed
- Changes to IpStack
- Fixes to kernel logging
- Added APIDoc files
- Cleaning up ifconfig and other helpers

36 files changed:
Kernel/Makefile.BuildNum
Kernel/include/acess.h
Kernel/include/apidoc/arch_x86.h [new file with mode: 0644]
Kernel/lib.c
Kernel/logging.c
Makefile.cfg
Modules/Filesystems/InitRD/.gitignore [new file with mode: 0644]
Modules/IPStack/ipstack.h
Modules/IPStack/main.c
Modules/Interfaces/EDI/Makefile [new file with mode: 0644]
Modules/Interfaces/EDI/edi/acess-edi.h [new file with mode: 0644]
Modules/Interfaces/EDI/edi/edi.h [new file with mode: 0644]
Modules/Interfaces/EDI/edi/edi_devices.h [new file with mode: 0644]
Modules/Interfaces/EDI/edi/edi_dma_streams.h [new file with mode: 0644]
Modules/Interfaces/EDI/edi/edi_interrupts.h [new file with mode: 0644]
Modules/Interfaces/EDI/edi/edi_memory_mapping.h [new file with mode: 0644]
Modules/Interfaces/EDI/edi/edi_objects.h [new file with mode: 0644]
Modules/Interfaces/EDI/edi/edi_port_io.h [new file with mode: 0644]
Modules/Interfaces/EDI/edi/edi_pthreads.h [new file with mode: 0644]
Modules/Interfaces/EDI/edi/helpers.h [new file with mode: 0644]
Modules/Interfaces/EDI/edi_int.inc.c [new file with mode: 0644]
Modules/Interfaces/EDI/edi_io.inc.c [new file with mode: 0644]
Modules/Interfaces/EDI/main.c [new file with mode: 0644]
Usermode/Applications/axwin2_src/Shell_src/Makefile [new file with mode: 0644]
Usermode/Applications/axwin2_src/Shell_src/main.c [new file with mode: 0644]
Usermode/Applications/axwin2_src/WM/common.h
Usermode/Applications/axwin2_src/WM/wm.h [new file with mode: 0644]
Usermode/Applications/ifconfig_src/main.c
Usermode/Libraries/Makefile.tpl [new file with mode: 0644]
Usermode/Libraries/libaxwin2.so_src/Makefile [new file with mode: 0644]
Usermode/Libraries/libaxwin2.so_src/common.h [new file with mode: 0644]
Usermode/Libraries/libaxwin2.so_src/main.c [new file with mode: 0644]
Usermode/Libraries/libaxwin2.so_src/messages.c [new file with mode: 0644]
Usermode/Libraries/libaxwin2.so_src/windows.c [new file with mode: 0644]
Usermode/include/axwin/axwin.h [new file with mode: 0644]
Usermode/include/axwin/messages.h

index b9b1128..fa878fd 100644 (file)
@@ -1 +1 @@
-BUILD_NUM = 1563
+BUILD_NUM = 1586
index 9363dc0..d4ea289 100644 (file)
@@ -101,6 +101,15 @@ extern void        System_Init(char *ArgString);
 // --- IRQs ---
 extern int     IRQ_AddHandler(int Num, void (*Callback)(int));
 
+// --- Logging ---
+extern void    Log_KernelPanic(char *Ident, char *Message, ...);
+extern void    Log_Panic(char *Ident, char *Message, ...);
+extern void    Log_Error(char *Ident, char *Message, ...);
+extern void    Log_Warning(char *Ident, char *Message, ...);
+extern void    Log_Log(char *Ident, char *Message, ...);
+extern void    Log_Notice(char *Ident, char *Message, ...);
+extern void    Log_Debug(char *Ident, char *Message, ...);
+
 // --- Debug ---
 /**
  * \name Debugging and Errors
@@ -300,6 +309,7 @@ extern int  vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list a
 extern int     sprintf(char *__s, const char *__format, ...);
 extern Uint    strlen(const char *Str);
 extern char    *strcpy(char *__dest, const char *__src);
+extern char    *strncpy(char *__dest, const char *__src, size_t max);
 extern int     strcmp(const char *__str1, const char *__str2);
 extern int     strncmp(const char *Str1, const char *Str2, size_t num);
 extern int     strucmp(const char *Str1, const char *Str2);
diff --git a/Kernel/include/apidoc/arch_x86.h b/Kernel/include/apidoc/arch_x86.h
new file mode 100644 (file)
index 0000000..7818c8c
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ * \file apidoc/arch_x86.h
+ * \brief x86(-64) Specific Functions
+ * \author John Hodge (thePowersGang)
+ *
+ * \section toc        Table of Contents
+ * - \ref portio "Port IO"
+ * - \ref dma "DMA - Direct Memory Access"
+ * 
+ * \section portio Port IO
+ * The x86 architecture has two memory spaces, the first is the system
+ * memory accessable using standard loads and stores. The second is the
+ * 16-bit IO Bus. This bus is accessed using the \a in and \a out opcodes
+ * and is used to configure devices attached to the system.
+ * A driver should not use \a in and \a out directly, but instead use
+ * the provided \a in* and \a out* functions to access the IO Bus.
+ * This allows the kernel to run a driver in userspace if requested without
+ * the binary needing to be altered.
+ * 
+ * \section dma        DMA - Direct Memory Access
+ */
+
+/**
+ * \name IO Bus Access
+ * \{
+ */
+extern Uint8   inb(Uint16 Port);       //!< Read 1 byte from the IO Bus
+extern Uint16  inw(Uint16 Port);       //!< Read 2 bytes from the IO Bus
+extern Uint32  inl(Uint16 Port);       //!< Read 4 bytes from the IO Bus
+extern Uint64  inq(Uint16 Port);       //!< Read 8 bytes from the IO Bus\
+
+extern void    outb(Uint16 Port, Uint8 Value); //!< Write 1 byte to the IO Bus
+extern void    outw(Uint16 Port, Uint16 Value);        //!< Write 2 bytes to the IO Bus
+extern void    outl(Uint16 Port, Uint32 Value);        //!< Write 4 bytes to the IO Bus
+extern void    outq(Uint16 Port, Uint64 Value);        //!< Write 8 bytes to the IO Bus
+/**
+ * \}
+ */
index 62500fe..eea64e0 100644 (file)
@@ -156,7 +156,14 @@ void itoa(char *buf, Uint num, int base, int minLength, char pad)
        buf[i] = 0;
 }
 
-#define PUTCH(c)       do{if(pos==__maxlen)break;if(__s){__s[pos++]=(c);}else{pos++;}}while(0)
+/**
+ * \brief Append a character the the vsnprintf output
+ */
+#define PUTCH(c)       do{\
+       char ch=(c);\
+       if(pos==__maxlen){return pos;}\
+       if(__s){__s[pos++]=ch;}else{pos++;}\
+       }while(0)
 int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
 {
        char    c, pad = ' ';
@@ -167,12 +174,15 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
        Uint64  val;
        size_t  pos = 0;
        
+       Log("vsnprintf: (__s=%p, __maxlen=%i, __format='%s', ...)\n", __s, __maxlen, __format);
+       
        while((c = *__format++) != 0)
        {
                // Non control character
                if(c != '%') { PUTCH(c); continue; }
                
                c = *__format++;
+               //Log("pos = %i", pos);
                
                // Literal %
                if(c == '%') { PUTCH('%'); continue; }
@@ -188,6 +198,8 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
                
                // Get Argument
                val = va_arg(args, Uint);
+               //Log("val = %x", val);
+
                
                // - Padding
                if(c == '0') {
@@ -258,6 +270,7 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
                case 's':
                        p = (char*)(Uint)val;
                printString:
+                       //Log("p = '%s'", p);
                        if(!p)          p = "(null)";
                        while(*p)       PUTCH(*p++);
                        break;
@@ -274,14 +287,10 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
                        PUTCH( (Uint8)val );
                        break;
                }
-               
-               if(pos == __maxlen)
-                       break;
        }
        
        if(__s && pos != __maxlen)
                __s[pos] = '\0';
-               
        
        return pos;
 }
index 567f64e..ad63a21 100644 (file)
@@ -21,7 +21,7 @@ enum eLogLevels
        LOG_LEVEL_DEBUG,
        NUM_LOG_LEVELS
 };
-const char     csaLevelCodes[] = {'k','p','f','e','w','n','l','d'};
+const char     *csaLevelCodes[] = {"k","p","f","e","w","n","l","d"};
 
 // === TYPES ===
 typedef struct sLogEntry
@@ -29,7 +29,7 @@ typedef struct sLogEntry
        struct sLogEntry        *Next;
        struct sLogEntry        *LevelNext;
        Sint64  Time;
-       Uint64  Ident;
+       char    Ident[8];
         int    Level;
         int    Length;
        char    Data[];
@@ -47,10 +47,19 @@ void        Log_KernelPanic(char *Ident, char *Message, ...);
 void   Log_Panic(char *Ident, char *Message, ...);
 void   Log_Error(char *Ident, char *Message, ...);
 void   Log_Warning(char *Ident, char *Message, ...);
-void   Log_Log(char *Ident, char *Message, ...);
 void   Log_Notice(char *Ident, char *Message, ...);
+void   Log_Log(char *Ident, char *Message, ...);
 void   Log_Debug(char *Ident, char *Message, ...);
-static Uint64  Log_Int_GetIdent(const char *Str);
+//static Uint64        Log_Int_GetIdent(const char *Str);
+
+// === EXPORTS ===
+EXPORT(Log_KernelPanic);
+EXPORT(Log_Panic);
+EXPORT(Log_Error);
+EXPORT(Log_Warning);
+EXPORT(Log_Notice);
+EXPORT(Log_Log);
+EXPORT(Log_Debug);
 
 // === GLOBALS ===
 tSpinlock      glLog;
@@ -65,19 +74,23 @@ void Log_AddEvent(char *Ident, int Level, char *Format, va_list Args)
 {
         int    len;
        tLogEntry       *ent;
-       Uint64  ident = Log_Int_GetIdent(Ident);
        
        if( Level >= NUM_LOG_LEVELS )   return;
        
        len = vsnprintf(NULL, 256, Format, Args);
        
+       Log("len = %i", len);
+       
        ent = malloc(sizeof(tLogEntry)+len+1);
        ent->Time = now();
-       ent->Ident = ident;
+       strncpy(ent->Ident, Ident, 7);
        ent->Level = Level;
        ent->Length = len;
        vsnprintf( ent->Data, 256, Format, Args );
        
+       Log("ent->Ident = '%s'", ent->Ident);
+       Log("ent->Data = '%s'", ent->Data);
+       
        LOCK( &glLog );
        
        ent->Next = gLog.Tail;
@@ -105,10 +118,10 @@ void Log_AddEvent(char *Ident, int Level, char *Format, va_list Args)
  */
 void Log_Int_PrintMessage(tLogEntry *Entry)
 {
-       LogF("%018%c [%8s] %s\n",
+       LogF("%018i% [%8s] %s\n",
                Entry->Time,
                csaLevelCodes[Entry->Level],
-               &Entry->Ident,
+               Entry->Ident,
                Entry->Data
                );
 }
@@ -190,30 +203,3 @@ void Log_Debug(char *Ident, char *Message, ...)
        Log_AddEvent(Ident, LOG_LEVEL_DEBUG, Message, args);
        va_end(args);
 }
-
-/**
- * \brief Converts a string into a 64-bit ident
- */
-static Uint64 Log_Int_GetIdent(const char *Str)
-{
-       Uint64  ret = 0;
-        int    i;
-       char    ch;
-       
-       for( i = 0; Str[i] && i < 7; i++ )
-       {
-               ch = Str[i];
-               
-               if(ch < ' ')
-                       ch = '?';
-               else if(ch > '~')
-                       ch = '?';
-               
-               ret |= (Uint64)ch << 8*i;
-       }
-       
-       for( ; i < 7; i++ )
-               ret |= 0x20 << (8*i);
-       
-       return ret;
-}
index 4de3cd0..e4ae222 100644 (file)
@@ -30,7 +30,7 @@ MODULES += Network/NE2000
 #MODULES += Display/BochsGA
 MODULES += Filesystems/Ext2
 MODULES += Filesystems/FAT
-#MODULES += IPStack
+MODULES += IPStack
 DYNMODS = USB Interfaces/UDI
 
 #DISTROOT = /mnt/AcessHDD/Acess2
diff --git a/Modules/Filesystems/InitRD/.gitignore b/Modules/Filesystems/InitRD/.gitignore
new file mode 100644 (file)
index 0000000..a311505
--- /dev/null
@@ -0,0 +1 @@
+files.c
index 54d8fb8..95f93c4 100644 (file)
@@ -61,6 +61,7 @@ struct sAdapter {
         int    NRef;
        
        tMacAddr        MacAddr;
+        int    DeviceLen;
        char    Device[];
 };
 
index e380320..9b132ec 100644 (file)
@@ -268,6 +268,7 @@ static const char *casIOCtls_Iface[] = {
        "get_address", "set_address",
        "getset_subnet",
        "get_gateway", "set_gateway",
+       "get_device",
        "ping",
        NULL
        };
@@ -465,11 +466,23 @@ int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data)
                }
                break;
        
+       /*
+        * get_device
+        * - Gets the name of the attached device
+        */
+       case 10:
+               if( Data == NULL )
+                       LEAVE_RET('i', iface->Adapter->DeviceLen);
+               if( !CheckMem( Data, iface->Adapter->DeviceLen+1 ) )
+                       LEAVE_RET('i', -1);
+               strcpy( Data, iface->Adapter->Device );
+               return iface->Adapter->DeviceLen;
+       
        /*
         * ping
         * - Send an ICMP Echo
         */
-       case 10:
+       case 11:
                switch(iface->Type)
                {
                case 0:
@@ -588,6 +601,7 @@ tAdapter *IPStack_GetAdapter(char *Path)
        // Fill Structure
        strcpy( dev->Device, Path );
        dev->NRef = 1;
+       dev->DeviceLen = strlen(Path);
        
        // Open Device
        dev->DeviceFD = VFS_Open( dev->Device, VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE );
diff --git a/Modules/Interfaces/EDI/Makefile b/Modules/Interfaces/EDI/Makefile
new file mode 100644 (file)
index 0000000..a93a8b7
--- /dev/null
@@ -0,0 +1,10 @@
+# 
+# EDI - Extensible Driver Interface
+# 
+# Acess Interface
+
+
+OBJ = main.o edi.o
+NAME = EDI
+
+-include ../Makefile.tpl
diff --git a/Modules/Interfaces/EDI/edi/acess-edi.h b/Modules/Interfaces/EDI/edi/acess-edi.h
new file mode 100644 (file)
index 0000000..4071388
--- /dev/null
@@ -0,0 +1,41 @@
+/*! \file acess-edi.h
+ * \brief Acess Specific EDI Objects
+ * 
+ * Contains documentation and information for
+ * - Timers
+ */
+
+/* Copyright (c)  2006  John Hodge
+ * Permission is granted to copy, distribute and/or modify this document
+ * under the terms of the GNU Free Documentation License, Version 1.2
+ * or any later version published by the Free Software Foundation;
+ * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ * Texts.  A copy of the license is included in the file entitled "COPYING". */
+
+#ifndef ACESS_EDI_H
+#define ACESS_EDI_H
+
+#include "edi_objects.h"
+
+/// \brief Name of Acess EDI Time Class
+#define        ACESS_TIMER_CLASS       "ACESSEDI-TIMER"
+
+#ifndef IMPLEMENTING_EDI
+/*! \brief int32_t ACESSEDI-TIMER.init_timer(uint32_t Delay, void (*Callback)(int), int Arg);
+ *
+ * Takes a timer pointer and intialises the timer object to fire after \a Delay ms
+ * When the timer fires, \a Callback is called with \a Arg passed to it.
+ */
+EDI_DEFVAR int32_t (*init_timer)(object_pointer port_object, uint32_t Delay, void (*fcn)(int), int arg);
+
+/*! \brief void ACESSEDI-TIMER.disable_timer();
+ * 
+ * Disables the timer and prevents it from firing
+ * After this has been called, the timer can then be initialised again.
+ */
+EDI_DEFVAR void (*disable_timer)(object_pointer port_object);
+
+
+#endif // defined(IMPLEMENTING_EDI)
+
+#endif
diff --git a/Modules/Interfaces/EDI/edi/edi.h b/Modules/Interfaces/EDI/edi/edi.h
new file mode 100644 (file)
index 0000000..273f7a3
--- /dev/null
@@ -0,0 +1,114 @@
+#ifndef EDI_H
+
+/* Copyright (c)  2006  Eli Gottlieb.
+ * Permission is granted to copy, distribute and/or modify this document
+ * under the terms of the GNU Free Documentation License, Version 1.2
+ * or any later version published by the Free Software Foundation;
+ * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ * Texts.  A copy of the license is included in the file entitled "COPYING". */
+
+#define EDI_H
+/*! \file edi.h
+ * \brief The unitive EDI header to include others, start EDI, and stop EDI.
+ *
+ * Data structures and algorithms this header represents:
+ *     DATA STRUCTURE: CLASS QUOTAS - The runtime and the driver have the right to set a quota on how many objects of a given class
+ * owned by that party the other may construct.  These quotas are kept internally by the driver or runtime, are optional and are
+ * exposed to the other party via the quota() function (for quotas of runtime-owned classes) and the k_quota() function pointer given
+ * to the runtime by the driver.
+ *
+ *     ALGORITHMS: INITIALIZATION AND SHUTDOWN - On initialization of the runtime's EDI environment for this driver it calls the
+ * driver's driver_init() routine (which must match driver_init_t) to initialize the driver with a list of EDI objects the runtime
+ * thinks the driver should run with.  The driver then initializes.  This can include calling edi_negotiate_resources() to try and
+ * obtain more or different objects.  Eventually driver_init() returns an edi_initialization_t structure containing its quota
+ * function and the list of classes belonging to the driver which the runtime can construct.  Either the driver or the runtime can
+ * shut down EDI by calling edi_shutdown(), which in turn calls the driver's driver_finish() routine.  On shutdown all objects, of
+ * classes belonging to both the runtime and driver, are destroyed. */
+
+#include "edi_objects.h"
+#include "edi_dma_streams.h"
+#include "edi_pthreads.h"
+#include "edi_port_io.h"
+#include "edi_memory_mapping.h"
+#include "edi_devices.h"
+#include "edi_interrupts.h"
+
+/*! \brief A pointer to a function the runtime can call if it fails to construct one of the driver's classes to find out what the
+ * runtime's quota is for that class.
+ *
+ * A pointer to a function which takes an edi_string_t as a parameter and returns in int32_t.  This function follows the same
+ * semantics as the quota() function, returning the number of objects of the given class that can be constructed, -1 for infinity or
+ * -2 for an erroneous class name.  It is used to tell the runtime the location of such a function in the driver so that the runtime
+ * can check quotas on driver-owned classes. */
+typedef int32_t (*k_quota_t)(edi_string_t resource_class);
+/*!\struct edi_initialization_t
+ * \brief Structure containing driver classes available to the runtime and the driver's quota function after the driver has initialized. 
+ *
+ * Structure containing driver classes available to runtime, the driver's quota function and the driver's name provided to the runtime
+ * after the driver has initialized.  driver_bus, vendor_id, and device_id are all optional fields which coders should consider
+ * supplementary information.  Kernels can require these fields if they so please, but doing so for devices which don't run on a Vendor
+ * ID/Product ID supporting bus is rather unwise. */
+typedef struct {
+       /*!\brief The number of driver classes in the driver_classes array. */
+       int32_t num_driver_classes;
+       /*!\brief An array of declarations of driver classes available to the runtime. 
+        *
+        * This array should not necessarily contain the entire list of EDI classes implemented by the driver.  Instead, it should
+        * contain a list of those classes which the driver has correctly initialized itself to provide instances of with full
+        * functionality. */
+       edi_class_declaration_t *driver_classes;
+       /*!\brief The driver's quota function. */
+       k_quota_t k_quota;
+       /*!\brief The driver's name. */
+       edi_string_t driver_name;
+       /*!\brief The bus of the device this driver wants to drive, if applicable.
+        *
+        * The driver does not have to supply this field, and can also supply "MULTIPLE BUSES" here to indicate that it drives devices
+        * on multiple buses. */
+       edi_string_t driver_bus;
+       /*!\brief The driver's vendor ID, if applicable.
+        *
+        * The driver does not need to supply this field, and should supply -1 to indicate that it does not wish to. */
+       int16_t vendor_id;
+       /*!\brief The driver's device ID, if applicable.
+        *
+        * The driver does not need to supply this field, but can supply it along with vendor_id.  If either vendor_id or this field are
+        * set to -1 the runtime should consider this field not supplied. */
+       int16_t driver_id;
+} edi_initialization_t;        
+/*!\brief A pointer to a driver's initialization function.
+ *
+ * The protocol for the driver's initialization function.  The runtime gives the driver a set of EDI objects representing the
+ * resources it thinks the driver should run with.  This function returns an edi_initialization_t structure containing declarations
+ * of the EDI classes the driver can make available to the runtime after initialization.  If any member of that structure contains 0
+ * or NULL, it is considered invalid and the runtime should destroy the driver without calling its driver_finish() routine. */
+typedef edi_initialization_t (*driver_init_t)(int32_t num_resources,edi_object_metadata_t *resources);
+/*!\brief Requests more resources from the runtime.  Can be called during driver initialization.
+ *
+ * Called to negotiate with the runtime for the right to create further EDI objects/obtain further resources owned by the runtime.
+ * When the driver calls this routine, the runtime decides whether to grant more resources.  If yes, this call returns true, and the
+ * driver can proceed to try and create the objects it desires, in addition to destroying EDI objects it doesn't want.  Otherwise,
+ * it returns false.
+ * The driver must deal with whatever value this routine returns. */
+bool edi_negotiate_resources();
+
+/*! \brief Returns the driver's quota of objects for a given runtime-owned class. 
+ *
+ * This function takes an edi_string_t with the name of a runtime-owned class in it and returns the number of objects of that class
+ * which drivers can construct, -1 for infinity, or -2 for an erroneous class name. */
+int32_t quota(edi_string_t resource_class);
+/*! \brief Sends a string to the operating systems debug output or logging facilities. */
+void edi_debug_write(uint32_t debug_string_length, char *debug_string);
+/*! \brief This call destroys all objects and shuts down the entire EDI environment of the driver. 
+ *
+ * This function shuts down EDI as described in INITIALIZATION AND SHUTDOWN above.  All objects are destroyed, EDI functions can no
+ * longer be successfully called, etc.  This function only succeeds when EDI has already been initialized, so it returns -1 when EDI
+ * hasn't been, 1 on success, or 0 for all other errors. */
+int32_t shutdown_edi(void);
+
+/*!\brief A pointer to the driver's finishing/shutdown function.
+ *
+ * The protocol for the driver's shutting down.  This function should do anything the driver wants done before it dies. */
+typedef void (*driver_finish_t)();
+
+#endif
diff --git a/Modules/Interfaces/EDI/edi/edi_devices.h b/Modules/Interfaces/EDI/edi/edi_devices.h
new file mode 100644 (file)
index 0000000..245e01f
--- /dev/null
@@ -0,0 +1,135 @@
+#ifndef EDI_DEVICES_H
+
+/* Copyright (c)  2006  Eli Gottlieb.
+ * Permission is granted to copy, distribute and/or modify this document
+ * under the terms of the GNU Free Documentation License, Version 1.2
+ * or any later version published by the Free Software Foundation;
+ * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ * Texts.  A copy of the license is included in the file entitled "COPYING". */
+
+/* Edited by thePowersGang (John Hodge) June 2009
+ * - Add #ifdef EDI_MAIN_FILE
+ */
+
+#define EDI_DEVICES_H
+
+/*! \file edi_devices.h
+ * \brief Declaration and description of simple classes for implementation by EDI drivers to represent hardware devices.
+ *
+ * Data structures and algorithms this header represents:
+ *
+ *     DATA STRUCTURE AND ALGORITHM: BASIC DEVICES - There are two functions, select() for waiting on devices and ioctl() for
+ * controlling them, common to many POSIX devices.  Implementations of EDI-CHARACTER-DEVICE or EDI-BLOCK-DEVICE may implement either of
+ * these or both, and users of such objects much query for the methods to see if they're supported.  Obviously, runtime or driver
+ * developers don't *need* to support these.
+ *
+ *     DATA STRUCTURE AND ALGORITHM: CHARACTER DEVICES - The class EDI-CHARACTER-DEVICE provides a very basic interface to character
+ * devices, which read and write streams of characters.  As such, this class only provides read() and write().  The calls attempt a
+ * likeness to POSIX.
+ *
+ *     DATA STRUCTURE AND ALGORITHM: BLOCK DEVICES - The class EDI-BLOCK-DEVICE provides a very basic interface to block devices, which
+ * can read(), write() and seek() to blocks of a specific size in an array of blocks with a specific size.  Its declarations and
+ * semantics should behave like those of most POSIX operating systems.
+ *
+ * Note that EDI runtimes should not implement these classes.  Their declarations are provided for drivers to implement. */
+
+#include "edi_objects.h"
+
+/* Methods common to all EDI device classes specified in this header. */
+
+/*!\brief EAGAIN returned by functions for block and character devices.
+ *
+ * Means that the amount of data the device has ready is less than count. */
+#define EAGAIN -1
+/*!\brief EBADOBJ returned by functions for block and character devices.
+ *
+ * Means that the object passed as the method's this point was not a valid object of the needed class. */
+#define EBADOBJ -2
+/*!\brief EINVAL returned by functions for block and character devices.
+ *
+ * Means that the method got passed invalid parameters. */
+#ifdef EINVAL
+# undef EINVAL
+#endif
+#define EINVAL -3
+
+/*!\brief select() type to wait until device is writable. */
+#define EDI_SELECT_WRITABLE 0
+/*!\brief select() type to wait until device is readable. */
+#define EDI_SELECT_READABLE 1
+
+/*!\brief Argument to seek().  Sets the block offset (ie: the "current block" index) to the given whence value. */
+#define EDI_SEEK_SET 0
+/*!\brief Argument to seek().  Sets the block offset (ie: the "current block" index) to its current value + whence. */
+#define EDI_SEEK_CURRENT 1
+
+#ifdef EDI_MAIN_FILE
+/*!\brief Arguments to EDI's basic select() function. */
+edi_variable_declaration_t select_arguments[2] = {{"pointer void","device",1},
+                                                {"unsigned int32_t","select_type",1}};
+/*!\brief Declaration of EDI's basic select() function. 
+ *
+ * Contrary to the POSIX version, this select() puts its error codes in its return value. */
+edi_function_declaration_t select_declaration = {"int32_t","edi_device_select",0,2,select_arguments,NULL};
+#else
+extern edi_function_declaration_t select_declaration;  // Declare for non main files
+#endif
+
+#ifdef EDI_MAIN_FILE
+/*!\brief Arguments to EDI's basic ioctl() function. */
+edi_variable_declaration_t ioctl_arguments[3] = {{"pointer void","device",1},{"int32_t","request",1},{"pointer void","argp",1}};
+/*!\brief Declaration of EDI's basic ioctl() function. 
+ *
+ * Contrary to the POSIX version, this ioctl() puts its error codes in its return value. */
+edi_function_declaration_t ioctl_declaration = {"int32_t","edi_device_ioctl",0,3,ioctl_arguments,NULL};
+#else
+extern edi_class_declaration_t ioctl_declaration;      // Declare for non main files
+#endif
+
+#ifdef EDI_MAIN_FILE
+/*!\brief Declaration of the arguments EDI-CHARACTER-DEVICE's read() and write() methods. */
+edi_variable_declaration_t chardev_read_write_arguments[3] = {{"pointer void","chardev",1},
+                                                             {"pointer void","buffer",1},
+                                                             {"unsigned int32_t","char_count",1}};
+/*!\brief Declarations of the methods of EDI-CHARACTER-DEVICE, read() and write().
+ *
+ * The code pointers of these function declarations are all given as NULL.  Driver developers implementing EDI-CHARACTER-DEVICE should
+ * fill in these entries with pointers to their own functions. */
+EDI_DEFVAR edi_function_declaration_t chardev_methods[2]= {{"int32_t","edi_chardev_read",0,3,chardev_read_write_arguments,NULL},
+                                               {"int32_t","edi_chardev_write",0,3,chardev_read_write_arguments,NULL}};
+/*!\brief Declaration of the EDI-CHARACTER-DEVICE class.
+ *
+ * Driver developers implementing this class should fill in their own values for constructor, destructor, and possibly even parent
+ * before passing the filled-in structure to the EDI runtime. */
+EDI_DEFVAR edi_class_declaration_t chardev_class = {"EDI-CHARACTER-DEVICE",0,2,chardev_methods,NULL,NULL,NULL};
+#else
+extern edi_class_declaration_t chardev_class;  // Declare for non main files
+#endif
+
+#ifdef EDI_MAIN_FILE
+/*!\brief Arguments to EDI-BLOCK-DEVICE's read() and write() methods. */
+edi_variable_declaration_t blockdev_read_write_arguments[3] = {{"pointer void","blockdev",1},
+                                                              {"pointer void","buffer",1},
+                                                              {"unsigned int32_t","blocks",1}};
+/*!\brief Arguments to EDI-BLOCK-DEVICE's seek() method. */
+edi_variable_declaration_t blockdev_seek_arguments[3] = {{"pointer void","blockdev",1},
+                                                        {"int32_t","offset",1},
+                                                        {"int32_t","whence",1}};
+/*!\brief Declaration of the methods of EDI-BLOCK-DEVICE, read(), write(), seek(), and get_block_size(). 
+ *
+ * The code pointers of these function declarations are all given as NULL.  Driver developers implementing EDI-BLOCK-DEVICE should fill
+ * these entries in with pointers to their own functions. */
+edi_function_declaration_t blockdev_methods[4] = {{"int32_t","edi_blockdev_read",0,3,blockdev_read_write_arguments,NULL},
+                                                 {"int32_t","edi_blockdev_write",0,3,blockdev_read_write_arguments,NULL},
+                                                 {"int32_t","edi_blockdev_seek",0,3,blockdev_seek_arguments,NULL},
+                                                 {"unsigned int32_t","edi_blockdev_get_block_size",0,0,NULL,NULL}};
+/*!\brief Declaration of the EDI-BLOCK-DEVICE class.
+ *
+ * Driver developers implementing this class should fill in their own values for constructor, destructor, and possibly even parent
+ * before passing the filled-in structure to the EDI runtime. */
+edi_class_declaration_t blockdev_class = {"EDI-BLOCK-DEVICE",0,4,blockdev_methods,NULL,NULL,NULL};
+#else
+extern edi_class_declaration_t blockdev_class; // Declare for non main files
+#endif
+
+#endif
diff --git a/Modules/Interfaces/EDI/edi/edi_dma_streams.h b/Modules/Interfaces/EDI/edi/edi_dma_streams.h
new file mode 100644 (file)
index 0000000..8ab80cc
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef EDI_DMA_STREAMS_H
+
+/* Copyright (c)  2006  Eli Gottlieb.
+ * Permission is granted to copy, distribute and/or modify this document
+ * under the terms of the GNU Free Documentation License, Version 1.2
+ * or any later version published by the Free Software Foundation;
+ * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ * Texts.  A copy of the license is included in the file entitled "COPYING". */
+
+#define EDI_DMA_STREAMS_H
+
+/*! \file edi_dma_streams.h 
+ * \brief EDI's stream subclass for handling Direct Memory Access hardware.
+ *
+ * Data structures and algorithms this header represents:
+ *
+ *     DATA STRUCTURE: DMA STREAMS - DMA streams are objects of the class EDI-STREAM-DMA used to pass data between a buffer of
+ * memory and the computer's DMA hardware.  It is the responsibility of the object to allocate memory for its stream memory buffer
+ * which can be used with DMA hardware and to program the DMA hardware for transmissions.  DMA streams can be bidirectional if the
+ * correct DMA mode is used. */
+
+#include "edi_objects.h"
+
+#define DMA_STREAM_CLASS       "EDI-STREAM-DMA"
+
+/*! \brief The name of the EDI DMA stream class.
+ *
+ * An edi_string_t with the class name "EDI-STREAM-DMA" in it. */
+#if defined(EDI_MAIN_FILE) || defined(IMPLEMENTING_EDI)
+const edi_string_t dma_stream_class = DMA_STREAM_CLASS;
+#else
+extern const edi_string_t dma_stream_class;
+#endif
+
+#ifndef IMPLEMENTING_EDI
+/*! \brief int32_t EDI-STREAM-DMA.init_dma_stream(unsigned int32_t channel,unsigned int32_t mode,unsigned int32_t buffer_pages);
+ *
+ * Pointer to the init_dma_stream() method of class EDI-STREAM-DMA, which initializes a DMA stream with a DMA channel, DMA mode, and
+ * the number of DMA-accessible memory pages to keep as a buffer.  It will only work once per stream object.  It's possible return
+ * values are 1 for sucess, -1 for invalid DMA channel, -2 for invalid DMA mode, -3 for inability to allocate enough buffer pages and
+ * 0 for all other errors. */
+EDI_DEFVAR  int32_t (*init_dma_stream)(object_pointer stream, uint32_t channel, uint32_t mode, uint32_t buffer_pages);
+/*! \brief int32_t EDI-STREAM-DMA.transmit(data_pointer *anchor,unsigned int32 num_bytes,bool sending);
+ *
+ * Pointer to the dma_stream_transmit() method of class EDI-STREAM-DMA, which transmits the given number of bytes of data through
+ * the DMA stream to/from the given anchor (either source or destination), in the given direction.  It returns 1 on success, -1 on
+ * an uninitialized or invalid DMA stream object, -2 when the anchor was NULL or otherwise invalid, -3 if the DMA stream can't
+ * transmit in the given direction, and 0 for all other errors. */
+EDI_DEFVAR int32_t (*dma_stream_transmit)(object_pointer stream, data_pointer anchor, uint32_t num_bytes, bool sending);
+#endif
+
+#endif
diff --git a/Modules/Interfaces/EDI/edi/edi_interrupts.h b/Modules/Interfaces/EDI/edi/edi_interrupts.h
new file mode 100644 (file)
index 0000000..ef2ffc9
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef EDI_INTERRUPTS_H
+
+/* Copyright (c)  2006  Eli Gottlieb.
+ * Permission is granted to copy, distribute and/or modify this document
+ * under the terms of the GNU Free Documentation License, Version 1.2
+ * or any later version published by the Free Software Foundation;
+ * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ * Texts.  A copy of the license is included in the file entitled "COPYING". */
+
+#define EDI_INTERRUPTS_H
+
+/*! \file edi_interrupts.h
+ * \brief Declaration and description of EDI's interrupt handling class.
+ *
+ * Data structures and algorithms this header represents:
+ *     DATA STRUCTURE AND ALGORITHM: INTERRUPT OBJECTS - The class EDI-INTERRUPT encapsulates the handling of machine interrupts.
+ * It is initialized with an interrupt number to handle and a handler routine to call when that interrupt occurs.  Only a couple of
+ * guarantees are made to the driver regarding the runtime's implementation of interrupt handling: 1) That the driver's handler is
+ * called for every time the interrupt associated with a valid and initialized interrupt object occurs, in the order of the
+ * occurences, 2) That the runtime handle the architecture-specific (general to the entire machine, not just this device)
+ * end-of-interrupt code when the driver is called without first returning from the machine interrupt.  Note that the runtime hands
+ * out interrupt numbers at its own discretion and policy. */
+
+#include "edi_objects.h"
+
+/*! \brief Macro constant containing the name of the interrupt class
+ */
+#define INTERRUPTS_CLASS       "EDI-INTERRUPT"
+/*! \brief The name of EDI's interrupt-handling class.
+ *
+ * An edi_string_t holding the name of the runtime-implemented interrupt object class.  It's value is "EDI-INTERRUPT". */
+#if defined(EDI_MAIN_FILE) || defined(IMPLEMENTING_EDI)
+const edi_string_t interrupts_class = INTERRUPTS_CLASS;
+#else
+extern const edi_string_t interrupts_class;
+#endif
+
+/*! \brief A pointer to an interrupt handling function.
+ *
+ * A pointer to a function called to handle interrupts.  Its unsigned int32_t parameter is the interrupt number that is being
+ * handled. */
+typedef void (*interrupt_handler_t)(uint32_t interrupt_number);
+
+#ifndef IMPLEMENTING_EDI
+/*! \brief Initializes an interrupt object with an interrupt number and a pointer to a handler function.
+ *
+ * A pointer to the init_interrupt() method of class EDI-INTERRUPT.  This method initializes a newly-created interrupt object with an
+ * interrupt number and a pointer to the driver's handler of type interrupt_handler_t.  It can only be called once per object, and
+ * returns 1 on success, fails with -1 when the interrupt number is invalid or unacceptable to the runtime, fails with -2 when the
+ * pointer to the driver's interrupt handler is invalid, and fails with -3 for all other errors. */
+EDI_DEFVAR int32_t (*init_interrupt)(object_pointer interrupt, uint32_t interrupt_number, interrupt_handler_t handler);
+/*! \brief Get this interrupt object's interrupt number. */
+EDI_DEFVAR uint32_t (*interrupt_get_irq)(object_pointer interrupt);
+/*! \brief Set a new handler for this interrupt object. */
+EDI_DEFVAR void (*interrupt_set_handler)(object_pointer interrupt, interrupt_handler_t handler);
+/*! \brief Return from this interrupt, letting the runtime run any necessary End-Of-Interrupt code.
+ *
+ * A pointer to the interrupt_return() method of class EDI-INTERRUPT.  This method returns from the interrupt designated by the
+ * calling interrupt object.  If there is a machine-wide end-of-interrupt procedure and the driver was called during the handling of
+ * the machine interrupt (as opposed to delaying the handling and letting the runtime EOI), the runtime runs it during this method.
+ * This method has no return value, since once it's called control leaves the calling thread. */
+EDI_DEFVAR void (*interrupt_return)(object_pointer interrupt);
+#endif
+
+#endif
diff --git a/Modules/Interfaces/EDI/edi/edi_memory_mapping.h b/Modules/Interfaces/EDI/edi/edi_memory_mapping.h
new file mode 100644 (file)
index 0000000..ba8dff3
--- /dev/null
@@ -0,0 +1,86 @@
+#ifndef EDI_MEMORY_MAPPING_H
+
+/* Copyright (c)  2006  Eli Gottlieb.
+ * Permission is granted to copy, distribute and/or modify this document
+ * under the terms of the GNU Free Documentation License, Version 1.2
+ * or any later version published by the Free Software Foundation;
+ * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ * Texts.  A copy of the license is included in the file entitled "COPYING". */
+
+#define EDI_MEMORY_MAPPING_H
+
+/*! \file edi_memory_mapping.h
+ * \brief Declaration and description of EDI's class for mapping physical pages into the driver's address space.
+ *
+ * Data structures and algorithms this header represents:
+ *     ALGORITHM: MEMORY MAPPINGS - Memory mapping objects of the class EDI-MEMORY-MAPPING are used to give virtual (driver-visible)
+ * addresses to sections of physical memory.  These can either be memory mappings belonging to hardware devices or plain RAM which
+ * the driver wants page-aligned.  A memory mapping object is initialized with the physical address for the memory mapping and the
+ * number of pages the mapping takes up, or simply the desired length of the a physically contiguous buffer in pages.  The class's
+ * two methods map the section of memory into and out of the driver's virtual address space. */
+
+#include "edi_objects.h"
+
+/*! \brief The name of EDI's memory mapping class.
+ *
+ * An edi_string_t with the name of the memory mapping class, "EDI-MEMORY-MAPPING". */
+#if defined(EDI_MAIN_FILE) || defined(IMPLEMENTING_EDI)
+const edi_string_t memory_mapping_class = "EDI-MEMORY-MAPPING";
+#else
+extern const edi_string_t memory_mapping_class;
+#endif
+
+/*! \brief Flag representing Strong Uncacheable caching method. */
+#define CACHING_STRONG_UNCACHEABLE 0
+/*! \brief Flag representing Uncacheable caching method. */
+#define CACHING_UNCACHEABLE 1
+/*! \brief Flag representing Write combining caching method. */
+#define CACHING_WRITE_COMBINING 2
+/*! \brief Flag representing Write Through caching method. */
+#define CACHING_WRITE_THROUGH 3
+/*! \brief Flag representing Write Back caching method. */
+#define CACHING_WRITE_BACK 3
+/*! \brief Flag representing Write Protected caching method. */
+#define CACHING_WRITE_PROTECTED 3
+
+#ifndef IMPLEMENTING_EDI
+/*! \brief Initialize an EDI-MEMORY-MAPPING object with a physical address range.
+ *
+ * This method takes the start_physical_address of a memory mapping and the number of pages in that mapping and uses these arguments
+ * to initialize an EDI-MEMORY-MAPPING object.  It can only be called once per object.  It returns 1 when successful, -1 when an
+ * invalid physical address is given (one that the runtime knows is neither a physical memory mapping belonging to a device nor
+ * normal RAM), -2 when the number of pages requested is bad (for the same reasons as the starting address can be bad), and 0 for
+ * all other errors. 
+ *
+ * Note that this method can't be invoked on an object which has already initialized via init_memory_mapping_with_pages(). */
+EDI_DEFVAR int32_t (*init_memory_mapping_with_address)(object_pointer mapping, data_pointer start_physical_address, uint32_t pages);
+/*! \brief Initialize an EDI-MEMORY-MAPPING object by requesting a number of new physical pages.
+ *
+ * This method takes a desired number of physical pages for a memory mapping, and uses that number to initialize an
+ * EDI-MEMORY-MAPPING object by creating a buffer of contiguous physical pages.  It can only be called once per object.  It returns
+ * 1 when successful, -1 when the request for pages cannot be fulfilled, and 0 for all other errors.
+ *
+ * Note that this method cannot be called if init_memory_mapping_with_address() has already been used on the given object. */
+EDI_DEFVAR int32_t (*init_memory_mapping_with_pages)(object_pointer mapping, uint32_t pages);
+/*! \brief Map the memory-mapping into this driver's visible address space.
+ *
+ * This asks the runtime to map a given memory mapping into the driver's virtual address space.  Its parameter is the address of a
+ * data_pointer to place the virtual address of the mapping into.  This method returns 1 on success, -1 on an invalid argument, -2
+ * for an uninitialized object, and 0 for all other errors. */
+EDI_DEFVAR int32_t (*map_in_mapping)(object_pointer mapping, data_pointer *address_mapped_to);
+/*! \brief Unmap the memory mapping from this driver's visible address space.
+ *
+ * This method tries to map the given memory mapping out of the driver's virtual address space.  It returns 1 for success, -1
+ * for an uninitialized memory mapping object, -2 if the mapping isn't mapped into the driver's address space already, and 0
+ * for all other errors. */
+EDI_DEFVAR int32_t (*map_out_mapping)(object_pointer mapping);
+
+/*! \brief Set the caching flags for a memory mapping. */
+EDI_DEFVAR void (*mapping_set_caching_method)(object_pointer mapping, uint32_t caching_method);
+/*! \brief Get the current caching method for a memory mapping. */
+EDI_DEFVAR uint32_t (*mapping_get_caching_method)(object_pointer mapping);
+/*! \brief Flush write-combining buffers on CPU to make sure changes to memory mapping actually get written.  Only applies to a Write Combining caching method (I think.).*/
+EDI_DEFVAR void (*flush_write_combining_mapping)(object_pointer mapping);
+#endif
+
+#endif
diff --git a/Modules/Interfaces/EDI/edi/edi_objects.h b/Modules/Interfaces/EDI/edi/edi_objects.h
new file mode 100644 (file)
index 0000000..0e47951
--- /dev/null
@@ -0,0 +1,257 @@
+#ifndef EDI_OBJECTS_H
+
+/* Copyright (c)  2006  Eli Gottlieb.
+ * Permission is granted to copy, distribute and/or modify this document
+ * under the terms of the GNU Free Documentation License, Version 1.2
+ * or any later version published by the Free Software Foundation;
+ * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ * Texts.  A copy of the license is included in the file entitled "COPYING". */
+
+#define EDI_OBJECTS_H
+
+/*! \file edi_objects.h
+ * \brief The header file for basic EDI types and the object system.
+ *
+ * This file contains declarations of EDI's primitive data types, as well as structures and functions for with the object system.
+ * It represents these data structures and algorithms:
+ * 
+ *     DATA STRUCTURE: THE CLASS LIST - EDI implementing runtime's must keep an internal list of classes implemented by the runtime
+ *     and separate lists of classes implemented by each driver.  Whoever implements a class is said to "own" that class.  The
+ *     internal format of this list is up to the runtime coders, but it must be possible to recreate the original list of
+ *     edi_class_declaration structures the driver declared to the runtime from it.  This list is declared to the runtime in an
+ *     initialization function in the header edi.h.  The object_class member of an edi_object_metadata structure must point to that
+ *     object's class's entry in this list.
+ *     
+ *     ALGORITHM AND DATA STRUCTURE: CLASSES AND INHERITANCE - Classes are described using edi_class_declaration_t structures and
+ *     follow very simple rules.  All data is private and EDI provides no way to access instance data, so there are no member
+ *     variable declarations.  However, if the data isn't memory-protected (for example, driver data on the driver heap) EDI allows
+ *     the possibility of pointer access to data, since runtime and driver coders could make use of that behavior.  Classes may have
+ *     one ancestor by declaring so in their class declaration structure, and if child methods are different then parent methods
+ *     the children always override their parents.  An EDI runtime must also be able to check the existence and ownership of a given
+ *     class given its name in an edi_string_t.
+ *     
+ *     ALGORITHM: OBJECT CREATION AND DESTRUCTION - An EDI runtime should be able to call the constructor of a named class, put the
+ *     resulting object_pointer into an edi_object_metadata_t and return that structure.  The runtime should also be able to call an
+ *     object's class's destructor when given a pointer to a valid edi_metadata_t for an already-existing object.  Data equivalent
+ *     to an edi_object_metadata_t should also be tracked by the runtime for every object in existence in case of sudden EDI shutdown
+ *     (see edi.h).
+ *
+ *     ALGORITHM: RUNTIME TYPE INFORMATION - When passed the data_pointer member of an edi_object_metadata_t to a valid object, an
+ *     EDI runtime must be able to return an edi_string_t containing the name of that object's class and to return function_pointers
+ *     to methods when the required information to find the correct method is given by calling a class's method getting function.*/
+
+/* If the EDI headers are linked with the standard C library, they use its type definitions.  Otherwise, equivalent definitions are
+ * made.*/
+#if __STDC_VERSION__ == 199901L
+# include <stdbool.h>
+# include <stdint.h>
+#else
+# ifndef NULL
+#  define      NULL    ((void*)0)
+# endif
+typedef unsigned char bool;
+# define true 1
+# define false 0
+typedef char int8_t;
+typedef short int16_t;
+typedef long int32_t;
+typedef long long int64_t;
+typedef unsigned char  uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long  uint32_t;
+typedef unsigned long long     uint64_t;
+#endif
+
+/*! \brief Define a variable in the header
+ */
+#ifdef EDI_MAIN_FILE
+# define EDI_DEFVAR
+#else
+# define EDI_DEFVAR    extern
+#endif
+
+/*! \brief A pointer to the in-memory instance of an object.
+ *
+ * This type is sized just like a general C pointer type (whatever*) for the target architecture.  It's passed as a first parameter
+ * to all methods, thus allowing EDI classes to be implemented as C++ classes and providing some protection from confusing objects
+ * with normal pointers.  Equivalent to a C++ this pointer or an Object Pascal Self argument. */
+typedef void *object_pointer;
+/*! \brief A basic pointer type pointing to arbitrary data in an arbitrary location. */
+typedef void *data_pointer;
+/*! \brief A basic function pointer type.
+ *
+ * A pointer to a piece of code which can be called and return to its caller, used to distinguish between pointers to code and
+ * pointers to data.  Its size is hardware-dependent. */
+typedef void (*function_pointer)(void);
+/*! \brief The length of an EDI string without its null character. */
+#define EDI_STRING_LENGTH 31
+/*! \brief A type representing a 31-character long string with a terminating NULL character at the end.  All of EDI uses this type
+ * for strings.
+ *
+ * A null-terminated string type which stores characters in int8s.  It allows for 31 characters in each string, with the final
+ * character being the NULL terminator.  Functions which use this type must check that its final character is NULL, a string which
+ * doesn't not have this property is invalid and insecure.  I (the author of EDI) know and understand that this form of a string
+ * suffers from C programmer's disease, but I can't use anything else without either making string use far buggier or dragging
+ * everyone onto a better language than C.  */
+typedef int8_t edi_string_t[0x20];
+/*! \brief A type representing a pointer form of #edi_string_t suitable for function returns
+ */
+typedef int8_t *edi_string_ptr_t;
+
+/*! \var EDI_BASE_TYPES
+ * \brief A constant array of edi_string_t's holding every available EDI primitive type. */
+/*! \var EDI_TYPE_MODIFIERS
+ * \brief A constant array of edi_string_t's holding available modifiers for EDI primitive types. */
+#ifdef IMPLEMENTING_EDI
+ const edi_string_t EDI_BASE_TYPES[9] = {"void","bool","int8_t","int16_t","int32_t","int64_t","function_pointer","intreg","edi_string_t"};
+ const edi_string_t EDI_TYPE_MODIFIERS[2] = {"pointer","unsigned"};
+#else
+ //extern const edi_string_t EDI_BASE_TYPES[9] = {"void","bool","int8_t","int16_t","int32_t","int64_t","function_pointer","intreg", "edi_string_t"};
+ //extern const edi_string_t EDI_TYPE_MODIFIERS[2] = {"pointer","unsigned"};
+ extern const edi_string_t EDI_BASE_TYPES[9];
+ extern const edi_string_t EDI_TYPE_MODIFIERS[2];
+#endif
+
+/*! \struct edi_object_metadata_t
+ * \brief A packed structure holding all data to identify an object to the EDI object system. */
+typedef struct {
+       /*! \brief Points to the instance data of the object represented by this structure.
+        *
+        * An object_pointer to the object this structure refers to.  The this pointer, so to speak. */
+       object_pointer object;
+       /*! \brief Points the internal record kept by the runtime describing the object's class.
+        *
+        * Points to wherever the runtime has stored the class data this object was built from.  The class data doesn't need to be
+        * readable to the driver, and so this pointer can point to an arbitrary runtime-reachable location. */
+       data_pointer object_class;
+} edi_object_metadata_t;
+
+/*! \struct edi_variable_declaration_t
+ * \brief The data structure used to describe a variable declaration to the EDI object system.
+ *
+ * The data structure used to describe a variable declaration to the EDI object system.  The context of the declaration depends on
+ * where the data structure appears, ie: alone, in a class declaration, in a parameter list, etc. */
+typedef struct {
+       /*! \brief The type of the declared variable. 
+        *
+        * The type of the variable, which must be a valid EDI primitive type as specified in the constant EDI_BASE_TYPES and
+        * possibly modified by a modifier specified in the constant EDI_TYPE_MODIFIERS. */
+       edi_string_t type;
+       /*! \brief The name of the declared variable. */
+       edi_string_t name;
+       /*! \brief Number of array entries if this variable is an array declaration. 
+        *
+        * An int32_t specifying the number of variables of 'type' in the array 'name'.  For a single variable this value should
+        * simply be set to 1, for values greater than 1 a packed array of contiguous variables is being declared, and a value of 0
+        * is invalid. */
+       int32_t array_length;
+} edi_variable_declaration_t;
+
+/*! \struct edi_function_declaration_t
+ * \brief The data structure used to declare a function to the EDI object system. */
+typedef struct {
+       /*! \brief The return type of the function.  The same type rules which govern variable definitions apply here. */
+       edi_string_t return_type;
+       /*! \brief The name of the declared function. */
+       edi_string_t name;
+       /*! \brief The version number of the function, used to tell different implementations of the same function apart. */
+       uint32_t version;
+       /*! \brief The number of arguments passed to the function.
+        *
+        * The number of entries in the member arguments that the object system should care about.  Caring about less misses
+        * parameters to functions, caring about more results in buffer overflows. */
+       uint32_t num_arguments;
+       /*! \brief An array of the declared function's arguments.
+        *
+        * A pointer to an array num_arguments long containing edi_variable_declaration_t's for each argument to the declared
+        * function.*/
+       edi_variable_declaration_t *arguments;
+       /*!\brief A pointer to the declared function's code in memory. */
+       function_pointer code;
+} edi_function_declaration_t;
+
+/*! \brief A pointer to a function for constructing instances of a class.
+ *
+ * A pointer to a function which takes no parameters and returns an object_pointer pointing to the newly made instance of a class.
+ * It is the constructor's responsibility to allocate memory for the new object.  Each EDI class needs one of these. */
+typedef object_pointer (*edi_constructor_t)(void);
+/*! \brief A pointer to a function for destroying instances of a class.
+ *
+ * A pointer to a function which takes an object_pointer as a parameter and returns void.  This is the destructor counterpart to a
+ * class's edi_constructor_t, it destroys the object pointed to by its parameter and frees the object's memory.  Every class must
+ * have one */
+typedef void (*edi_destructor_t)(object_pointer);
+
+/*! \brief Information the driver must give the runtime about its classes so EDI can construct them and call their methods.
+ *
+ * A structure used to declare a class to an EDI runtime so instances of it can be constructed by the EDI object system. */
+typedef struct {
+       /*! \brief The name of the class declared by the structure. */
+       edi_string_t name;
+       /*! \brief The version of the class.  This number is used to tell identically named but differently
+        * implemented classes apart.*/
+       uint32_t version;
+       /*! \brief The number of methods in the 'methods' function declaration array. */
+       uint32_t num_methods;
+       /*! \brief An array of edi_function_declaration_t declaring the methods of this class. */
+       edi_function_declaration_t *methods;
+       /*! \brief Allocates the memory for a new object of the declared class and constructs the object.  Absolutely required.*/
+       edi_constructor_t constructor;
+       /*! \brief Destroys the given object of the declared class and frees its memory. Absolutely required. */
+       edi_destructor_t destructor;
+       /*! \brief A pointer to another EDI class declaration structure specifying the declared class's parent class. 
+        *
+        * Points to a parent class declared in another class declaration.  It can be NULL to mean this class has no parent. */
+       struct edi_class_declaration_t *parent;
+} edi_class_declaration_t;
+
+/*! \brief Checks the existence of the named class.
+ *
+ * This checks for the existence on THE CLASS LIST of the class named by its edi_string_t parameter and returns a signed int32_t.  If
+ * the class isn't found (ie: it doesn't exist as far as EDI is concerned) -1 is returned, if the class is owned by the driver
+ * (implemented by the driver and declared to the runtime by the driver) 0, and if the class is owned by the runtime (implemented by
+ * the runtime) 1. */
+int32_t check_class_existence(edi_string_t class_name);
+/*! \brief Constructs an object of the named class and returns its object_pointer and a data_pointer to its class data.
+ *
+ * Given a valid class name in an edi_string_t this function constructs the specified class and returns an edi_metadata_t describing
+ * the new object as detailed in OBJECT CREATION AND DESTRUCTION.  If the construction fails it returns a structure full of NULL
+ * pointers. */
+edi_object_metadata_t construct_object(edi_string_t class_name);
+/*! \brief Destroys the given object using its class data.
+ *
+ * As specified in OBJECT CREATION AND DESTRUCTION this function should destroy an object when given its valid edi_metadata_t.  The
+ * destruction is accomplished by calling the class's destructor. */
+void destroy_object(edi_object_metadata_t object);
+/*! \brief Obtains a function pointer to a named method of a given class. 
+ *
+ * When given a valid data_pointer object_class from an edi_object_metadata_t and an edi_string_t representing the name of the
+ * desired method retrieves a function_pointer to the method's machine code in memory.  If the desired method isn't found, NULL is
+ * returned. */
+function_pointer get_method_by_name(data_pointer object_class,edi_string_t method_name);
+/*! \brief Obtains a function pointer to a method given by a declaration of the given class if the class's method matches the
+ * declaration. 
+ *
+ * Works just like get_method_by_name(), but by giving an edi_function_declaration_t for the desired method instead of just its name.
+ * Performs detailed checking against THE CLASS LIST to make sure that the method returned exactly matches the declaration passed
+ * in. */
+function_pointer get_method_by_declaration(data_pointer object_class,edi_function_declaration_t declaration);
+
+/* Runtime typing information. */
+/*! \brief Returns the name of the class specified by a pointer to class data. 
+ *
+ * Given the data_pointer to an object's class data as stored in an edi_object_metadata_t retrieves the name of the object's class
+ * and returns it in an edi_string_t. */
+edi_string_ptr_t get_object_class(data_pointer object_class);
+/*! \brief Returns the name of a class's parent class.
+ *
+ * When given an edi_string_t with a class name in it, returns another edi_string_t containing the name of the class's parent, or an
+ * empty string. */
+edi_string_ptr_t get_class_parent(edi_string_t some_class);
+/*! \brief Returns the internal class data of a named class (if it exists) or NULL.
+ *
+ * When given an edi_string_t with a valid class name in it, returns a pointer to the runtime's internal class data for that class.
+ * Otherwise, it returns NULL. */
+data_pointer get_internal_class(edi_string_t some_class);
+
+#endif 
diff --git a/Modules/Interfaces/EDI/edi/edi_port_io.h b/Modules/Interfaces/EDI/edi/edi_port_io.h
new file mode 100644 (file)
index 0000000..a2a1773
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef EDI_PORT_IO_H
+
+/* Copyright (c)  2006  Eli Gottlieb.
+ * Permission is granted to copy, distribute and/or modify this document
+ * under the terms of the GNU Free Documentation License, Version 1.2
+ * or any later version published by the Free Software Foundation;
+ * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ * Texts.  A copy of the license is included in the file entitled "COPYING". */
+
+/* Modified by thePowersGang (John Hodge)
+ * - Surround variable definitions with an #ifdef IMPLEMENTING_EDI
+ */
+
+#define EDI_PORT_IO_H
+
+/*! \file edi_port_io.h
+ * \brief Declaration and description of EDI's port I/O class.
+ *
+ * Data structures and algorithms this header represents:
+ *
+ *     DATA STRUCTURE AND ALGORITHM: PORT I/O OBJECTS - A class named "EDI-IO-PORT" is defined as an encapsulation of the port I/O
+ * used on some machine architectures.  Each object of this class represents a single I/O port which can be read from and written to
+ * in various sizes.  Each port can be held by one object only at a time. */
+
+#include "edi_objects.h"
+
+/*! \brief Macro to create methods for reading from ports.
+ *
+ * This macro creates four similar methods, differing in the size of the type they read from the I/O port held by the object.  Their
+ * parameter is a pointer to the output type, which is filled with the value read from the I/O port.  They return 1 for success, -1
+ * for an uninitialized I/O port object, and 0 for other errors. */
+#define port_read_method(type,name) int32_t (*name)(object_pointer port_object, type *out)
+/*! \brief Macro to create methods for writing to ports.
+ *
+ * This macro creates four more similar methods, differing in the size of the type they write to the I/O port held by the object.
+ * Their parameter is the value to write to the port.  They return 1 for success, -1 for an uninitialized I/O port object and 0 for
+ * other errors. */
+#define port_write_method(type,name) int32_t (*name)(object_pointer port_object, type in)
+
+/*! \brief Name of EDI I/O port class. (Constant)
+ *
+ * A CPP constant with the value of #io_port_class */
+#define        IO_PORT_CLASS   "EDI-IO-PORT"
+/*! \brief Name of EDI I/O port class.
+ *
+ * An edi_string_t containing the class name "EDI-IO-PORT". */
+#if defined(EDI_MAIN_FILE) || defined(IMPLEMENTING_EDI)
+const edi_string_t io_port_class = IO_PORT_CLASS;
+#else
+extern const edi_string_t io_port_class;
+#endif
+
+#ifndef IMPLEMENTING_EDI
+/*! \brief int32_t EDI-IO-PORT.init_io_port(unsigned int16_t port);
+ *
+ * This method takes an unsigned int16_t representing a particular I/O port and initializes the invoked EDI-IO-PORT object with it.
+ * The method returns 1 if successful, -1 if the I/O port could not be obtained for the object, and 0 for all other errors. */
+EDI_DEFVAR int32_t (*init_io_port)(object_pointer port_object, uint16_t port);
+/*! \brief Get the port number from a port object. */
+EDI_DEFVAR uint16_t (*get_port_number)(object_pointer port);
+/*! \brief Method created by port_read_method() in order to read bytes (int8s) from I/O ports. */
+EDI_DEFVAR int32_t (*read_byte_io_port)(object_pointer port_object, int8_t *out);
+/*! \brief Method created by port_read_method() in order to read words (int16s) from I/O ports. */
+EDI_DEFVAR int32_t (*read_word_io_port)(object_pointer port_object, int16_t *out);
+/*! \brief Method created by port_read_method() in order to read longwords (int32s) from I/O ports. */
+EDI_DEFVAR int32_t (*read_long_io_port)(object_pointer port_object, int32_t *out);
+/*! \brief Method created by port_read_method() in order to read long longwords (int64s) from I/O ports. */
+EDI_DEFVAR int32_t (*read_longlong_io_port)(object_pointer port_object,int64_t *out);
+/*! \brief Method of EDI-IO-PORT to read long strings of data from I/O ports.
+ *
+ * Reads arbitrarily long strings of data from the given I/O port.  Returns 1 for success, -1 for an uninitialized port object, -2
+ * for a bad pointer to the destination buffer, and 0 for all other errors. */
+EDI_DEFVAR int32_t (*read_string_io_port)(object_pointer port_object, uint32_t data_length, uint8_t *out);
+/*! \brief Method created by port_write_method() in order to write bytes (int8s) to I/O ports. */
+EDI_DEFVAR int32_t (*write_byte_io_port)(object_pointer port_object, int8_t in);
+/*! \brief Method created by port_write_method() in order to write words (int16s) to I/O ports. */
+EDI_DEFVAR int32_t (*write_word_io_port)(object_pointer port_object, int16_t in);
+/*! \brief Method created by port_write_method() in order to write longwords (int32s) to I/O ports. */
+EDI_DEFVAR int32_t (*write_long_io_port)(object_pointer port_object, int32_t in);
+/*! \brief Method created by port_write_method() in order to write long longwords (int64s) to I/O ports. */
+EDI_DEFVAR int32_t (*write_longlong_io_port)(object_pointer port_object, int64_t in);
+/*! \brief Method of EDI-IO-PORT to write long strings of data to I/O ports.
+ *
+ * Writes arbitrarily long strings of data to the given I/O port.  Returns 1 for success, -1 for an uninitialized port object, -2
+ * for a bad pointer to the source buffer, and 0 for all other errors. */
+EDI_DEFVAR int32_t (*write_string_io_port)(object_pointer port_object, uint32_t data_length, uint8_t *in);
+
+#endif // defined(IMPLEMENTING_EDI)
+
+#endif
diff --git a/Modules/Interfaces/EDI/edi/edi_pthreads.h b/Modules/Interfaces/EDI/edi/edi_pthreads.h
new file mode 100644 (file)
index 0000000..c21fa75
--- /dev/null
@@ -0,0 +1,175 @@
+#ifndef EDI_PTHREADS
+
+/* Copyright (c)  2006  Eli Gottlieb.
+ * Permission is granted to copy, distribute and/or modify this document
+ * under the terms of the GNU Free Documentation License, Version 1.2
+ * or any later version published by the Free Software Foundation;
+ * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ * Texts.  A copy of the license is included in the file entitled "COPYING". */
+
+#define EDI_PTHREADS
+/*!\file edi_pthreads.h
+ * \brief A basic subset of POSIX Threads functionality, providing threading and thread synchronization.
+ *
+ * A very basic POSIX Threads interface.  Note that pthreads are not a class, because none of these calls really gels with
+ * object-oriented programming.  Also, if drivers aren't processes or threads under the implementing operating system a small
+ * threading system must be implemented in-runtime just to multiplex the pthreads of EDI drivers.  Sorry about that.
+ *
+ * Data structures and algorithms this header represents:
+ *
+ *     ALGORITHM AND DATA STRUCTURE: POSIX Threading - The runtime must provide enough of a POSIX threading interface to implement
+ * the calls described here.  The actual multithreading must be performed by the runtime, and the runtime can implement that
+ * multithreading however it likes as long as the given POSIX Threads subset works.  There is, however, a caveat: since the runtime
+ * calls the driver like it would a library, the driver must perceive all calls made to it by the runtime as running under one thread.
+ * From this thread the driver can create others.  Such behavior is a quirk of EDI, and does not come from the POSIX standard.
+ * However, it is necessary to provide the driver with a thread for its own main codepaths.  For further details on a given POSIX
+ * Threading routine, consult its Unix manual page. */
+
+#include "edi_objects.h"
+
+/* Placeholder type definitions.  Users of the PThreads interface only ever need to define pointers to these types. */
+/*!\brief Opaque POSIX Threading thread attribute type. */
+typedef void pthread_attr_t;
+/*!\brief Opaque POSIX Threading mutex (mutual exclusion semaphore) type. */
+typedef void pthread_mutex_t;
+/*!\brief Opaque POSIX Threading mutex attribute type. */
+typedef void pthread_mutex_attr_t;
+
+/*!\struct sched_param
+ * \brief POSIX Threading scheduler parameters for a thread. */
+typedef struct {
+       /*!\brief The priority of the thread. */
+       int32_t sched_priority;
+} sched_param;
+
+/*!\brief POSIX Threading thread identifier. */
+typedef uint32_t pthread_t;
+/*!\brief POSIX Threading thread function type.
+ *
+ * A function pointer to a thread function, with the required signature of a thread function.  A thread function takes one untyped
+ * pointer as an argument and returns an untyped pointer.  Such a function is a thread's main routine: it's started with the thread,
+ * and the thread exits if it returns. */
+typedef void *(*pthread_function_t)(void*);
+
+/*!\brief Insufficient resources. */
+#define EAGAIN -1
+/*!\brief Invalid parameter. */
+#define EINVAL -2
+/*!\brief Permission denied. */
+#define EPERM -3
+/*!\brief Operation not supported. */
+#define ENOTSUP -4
+/*!\brief Priority scheduling for POSIX/multiple schedulers is not implemented. */
+#define ENOSYS -5
+/*!\brief Out of memory. */
+#define ENOMEM -6
+/*!\brief Deadlock.  Crap. */
+#define EDEADLK -7
+/*!\brief Busy.  Mutex already locked. */
+#define EBUSY -8
+
+/*!\brief Scheduling policy for regular, non-realtime scheduling.  The default. */
+#define SCHED_OTHER 0
+/*!\brief Real-time, first-in first-out scheduling policy.  Requires special (superuser, where such a thing exists) permissions. */
+#define SCHED_FIFO 1
+/*!\brief Real-time, round-robin scheduling policy.  Requires special (superuser, where such a thing exists) permissions. */
+#define SCHED_RR 0
+
+/*!\brief Creates a new thread with the given attributes, thread function and arguments, giving back the thread ID of the new
+ * thread.
+ *
+ * pthread_create() creates a new thread of control that executes concurrently with the calling thread.  The new thread applies the
+ * function start_routine, passing it arg as its argument.  The attr argument specifies thread attributes to apply to the new thread;
+ * it can also be NULL for the default thread attributes (joinable with default scheduling policy).  On success this function returns
+ * 0 and places the identifier of the new thread into thread_id.  On an error, pthread_create() can return EAGAIN if insufficient
+ * runtime resources are available to create the requested thread, EINVAL a value specified by attributes is invalid, or EPERM if the
+ * caller doesn't have permissions to set the given attributes.
+ *
+ * For further information: man 3 pthread_create */
+int32_t pthread_create(pthread_t *thread_id, const pthread_attr_t *attributes, pthread_function_t thread_function, void *arguments);
+/*!\brief Terminates the execution of the calling thread.  The thread's exit code with by status, and this routine never returns. */
+void pthread_exit(void *status);
+/*!\brief Returns the thread identifier of the calling thread. */
+pthread_t pthread_self();
+/*!\brief Compares two thread identifiers.
+ *
+ * Determines of the given two thread identifiers refer to the same thread.  If so, returns non-zero.  Otherwise, 0 is returned. */
+int32_t pthread_equal(pthread_t thread1, pthread_t thread2);
+/*!\brief Used by the calling thread to relinquish use of the processor.  The thread then waits in the run queue to be scheduled
+ * again. */
+void pthread_yield();
+
+/*!\brief Gets the scheduling policy of the given attributes.
+ *
+ * Places the scheduling policy for attributes into policy.  Returns 0 on success, EINVAL if attributes was invalid, and ENOSYS if
+ * priority scheduling/multiple scheduler support is not implemented. */
+int32_t pthread_attr_getschedpolicy(const pthread_attr_t *attributes, int32_t *policy);
+/*!\brief Sets the scheduling policy of the given attributes.
+ *
+ * Requests a switch of scheduling policy to policy for the given attributes.  Can return 0 for success, EINVAL if the given policy
+ * is not one of SCHED_OTHER, SCHED_FIFO or SCHED_RR or ENOTSUP if policy is either SCHED_FIFO or SCHED_RR and the driver is not
+ * running with correct privileges. */
+int32_t pthread_attr_setschedpolicy(pthread_attr_t *attributes, int32_t policy);
+
+/*!\brief Gets the scheduling paramaters (priority) from the given attributes.
+ *
+ * On success, stores scheduling parameters in param from attributes, and returns 0.  Otherwise, returns non-zero error code, such
+ * as EINVAL if the attributes object is invalid. */
+int32_t pthread_attr_getschedparam(const pthread_attr_t *attributes, sched_param *param);
+/*!\brief Sets the scheduling parameters (priority) of the given attributes.
+ *
+ * Requests that the runtime set the scheduling parameters (priority) of attributes from param. Returns 0 for success, EINVAL for an
+ * invalid attributes object, ENOSYS when multiple schedulers/priority scheduling is not implemented, and ENOTSUP when the value of
+ * param isn't supported/allowed. */
+int32_t pthread_attr_setschedparam(pthread_attr_t *attributes, const sched_param *param);
+
+/*!\brief The thread obtains its scheduling properties explicitly from its attributes structure. */
+#define PTHREAD_EXPLICIT_SCHED 1
+/*!\brief The thread inherits its scheduling properties from its parent thread. */
+#define PTHREAD_INHERIT_SCHED 0
+
+/*!\brief Returns the inheritsched attribute of the given attributes.
+ *
+ * On success, returns 0 and places the inheritsched attribute from attributes into inherit.  This attribute specifies where the
+ * thread's scheduling properites shall come from, and can be set to PTHREAD_EXPLICIT_SCHED or PTHREAD_INHERIT_SCHED.  On failure it
+ * returns EINVAL if attributes was invalid or ENOSYS if multiple schedulers/priority scheduling isn't implemented. */
+int32_t pthread_attr_getinheritsched(const pthread_attr_t *attributes, int32_t *inherit);
+/*!\brief Sets the inheritsched attribute of the given attributes.
+ *
+ * On success, places inherit into the inheritsched attribute of attributes and returns 0.  inherit must either contain
+ * PTHREAD_EXPLICIT_SCHED or PTHREAD_INHERIT_SCHED.  On failure, this routine returns EINVAL if attributes is invalid, ENOSYS when
+ * multiple schedulers/priority scheduling isn't implemented, and ENOSUP if the inheritsched attribute isn't supported. */
+int32_t pthread_attr_setinheritsched(pthread_attr_t *attributes, int32_t inherit);
+
+/*!\brief Creates a new POSIX Threads mutex, which will initially be unlocked.
+ *
+ * Creates a new mutex with the given attributes.  If attributes is NULL, the default attributes will be used.  The mutex starts out
+ * unlocked.  On success, the new mutex resides in the mutex structure pointed to by mutex, and this routine routines 0.  On failure,
+ * it returns EAGAIN if the system lacked sufficient non-memory resources to initialize the mutex, EBUSY if the given mutex is
+ * already initialized and in use, EINVAL if either parameter is invalid, and ENOMEM if the system lacks the memory for a new
+ * mutex.  Note: All EDI mutexes are created with the default attributes, and are of type PTHREAD_MUTEX_ERRORCHECK.  This means
+ * undefined behavior can never result from an badly placed function call. */
+int32_t pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutex_attr_t *attributes);
+/*!\brief Locks the given mutex.
+ *
+ * Locks the given mutex.  If the mutex is already locked, blocks the calling thread until it can acquire the lock.  When this
+ * routine returns successfully, it will return 0 and the calling thread will own the lock of the mutex.  If the call fails, it can
+ * return EINVAL when mutex is invalid or EDEADLK if the calling thread already owns the mutex. */
+int32_t pthread_mutex_lock(pthread_mutex_t *mutex);
+/*!\brief Unlocks the given mutex.
+ *
+ * Unlocks the given mutex, returning 0 on success.  On failure, it can return EINVAL when mutex is invalid or EPERM when the
+ * calling thread doesn't own the mutex. */
+int32_t pthread_mutex_unlock(pthread_mutex_t *mutex);
+/*!\brief Tries to lock the given mutex, returning immediately even if the mutex is already locked.
+ *
+ * Attempts to lock the given mutex, but returns immediately if it can't acquire a lock.  Returns 0 when it has acquired a lock,
+ * EBUSY if the mutex is already locked, or EINVAL if mutex is invalid. */
+int32_t pthread_mutex_trylock(pthread_mutex_t *mutex);
+/*!\brief Destroys the given mutex, or at least the internal structure of it. 
+ *
+ * Deletes the given mutex, making mutex invalid until it should be initialized by pthread_mutex_init().  Returns 0 on success,
+ * EINVAL when mutex is invalid, or EBUSY when mutex is locked or referenced by another thread. */
+int32_t pthread_mutex_destroy (pthread_mutex_t *mutex);
+
+#endif
diff --git a/Modules/Interfaces/EDI/edi/helpers.h b/Modules/Interfaces/EDI/edi/helpers.h
new file mode 100644 (file)
index 0000000..d7bc138
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef HELPERS_H
+
+#define HELPERS_H
+
+#include <edi.h>
+
+// Locally Defined
+bool edi_string_equal(edi_string_t x,edi_string_t y);
+bool descends_from(data_pointer object_class,edi_string_t desired_class);
+data_pointer get_actual_class(edi_string_t ancestor,int32_t num_objects,edi_object_metadata_t *objects);
+
+// Local Copy/set
+void *memcpyd(void *dest, void *src, unsigned int count);
+
+// Implementation Defined Common functions
+void *memcpy(void *dest, void *src, unsigned int count);
+void *memmove(void *dest, void *src, unsigned int count);
+void *realloc(void *ptr, unsigned int size);
+
+#endif
diff --git a/Modules/Interfaces/EDI/edi_int.inc.c b/Modules/Interfaces/EDI/edi_int.inc.c
new file mode 100644 (file)
index 0000000..0ab3359
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * AcessOS EDI Interface
+ * - IRQ Class
+ * 
+ * By John Hodge (thePowersGang)
+ * 
+ * This file has been released into the public domain.
+ * You are free to use it as you wish.
+ */
+#include "edi/edi.h"
+
+// === TYPES ===
+typedef struct {
+       uint16_t        State;  // 0: Unallocated, 1: Allocated, 2: Initialised, (Bit 0x8000 set if in heap)
+       uint16_t        Num;
+       interrupt_handler_t     Handler;
+} tEdiIRQ;
+
+// === PROTOTYPES ===
+void EDI_Int_IRQ_Handler(tRegs *Regs);
+
+// === GLOBALS ===
+tEdiIRQ        gEdi_IRQObjects[16];
+
+// === FUNCTIONS ===
+/**
+ * \fn object_pointer Edi_Int_IRQ_Construct(void)
+ * \brief Creates a new IRQ Object
+ * \return     Pointer to object
+ */
+object_pointer Edi_Int_IRQ_Construct(void)
+{
+        int    i;
+       // Search for a free irq
+       for( i = 0; i < 16; i ++ )
+       {
+               if(gEdi_IRQObjects[i].State)    continue;
+               gEdi_IRQObjects[i].State = 1;
+               gEdi_IRQObjects[i].Num = 0;
+               gEdi_IRQObjects[i].Handler = NULL;
+               return &gEdi_IRQObjects[i];
+       }
+       return NULL;
+}
+
+/**
+ * \fn void Edi_Int_IRQ_Destruct(object_pointer Object)
+ * \brief Destruct an IRQ Object
+ * \param Object       Object to destroy
+ */
+void Edi_Int_IRQ_Destruct(object_pointer Object)
+{
+       tEdiIRQ *obj;
+       
+       VALIDATE_PTR(Object,);
+       obj = GET_DATA(Object);
+       
+       if( !obj->State )       return;
+       
+       if( obj->Handler )
+               irq_uninstall_handler( obj->Num );
+       
+       if( obj->State & 0x8000 ) {     // If in heap, free
+               free(Object);
+       } else {        // Otherwise, mark as unallocated
+               obj->State = 0;
+       }
+}
+
+/**
+ * \fn int32_t Edi_Int_IRQ_InitInt(object_pointer Object, uint16_t Num, interrupt_handler_t Handler)
+ * \brief Initialises an IRQ
+ * \param Object       Object Pointer (this)
+ * \param Num  IRQ Number to use
+ * \param Handler      Callback for IRQ
+ */
+int32_t        Edi_Int_IRQ_InitInt(object_pointer Object, uint16_t Num, interrupt_handler_t Handler)
+{
+       tEdiIRQ *obj;
+       
+       //LogF("Edi_Int_IRQ_InitInt: (Object=0x%x, Num=%i, Handler=0x%x)\n", Object, Num, Handler);
+       
+       VALIDATE_PTR(Object,0);
+       obj = GET_DATA(Object);
+       
+       if( !obj->State )       return 0;
+       
+       if(Num > 15)    return 0;
+       
+       // Install the IRQ if a handler is passed
+       if(Handler) {
+               if( !irq_install_handler(Num, Edi_Int_IRQ_Handler) )
+                       return 0;
+               obj->Handler = Handler;
+       }
+       
+       obj->Num = Num;
+       obj->State &= ~0x3FFF;
+       obj->State |= 2;        // Set initialised flag
+       return 1;
+}
+
+/**
+ * \fn uint16_t Edi_Int_IRQ_GetInt(object_pointer Object)
+ * \brief Returns the irq number associated with the object
+ * \param Object       IRQ Object to get number from
+ * \return IRQ Number
+ */
+uint16_t Edi_Int_IRQ_GetInt(object_pointer Object)
+{
+       tEdiIRQ *obj;
+       
+       VALIDATE_PTR(Object,0);
+       obj = GET_DATA(Object);
+       
+       if( !obj->State )       return 0;
+       return obj->Num;
+}
+
+/**
+ * \fn void EDI_Int_IRQ_SetHandler(object_pointer Object, interrupt_handler_t Handler)
+ * \brief Set the IRQ handler for an IRQ object
+ * \param Object       IRQ Object to alter
+ * \param Handler      Function to use as handler
+ */
+void EDI_Int_IRQ_SetHandler(object_pointer Object, interrupt_handler_t Handler)
+{
+       tEdiIRQ *obj;
+       
+       // Get Data Pointer
+       VALIDATE_PTR(Object,);
+       obj = GET_DATA(Object);
+       
+       // Sanity Check arguments
+       if( !obj->State )       return ;
+       
+       // Only register the mediator if it is not already
+       if( Handler && !obj->Handler )
+               if( !irq_install_handler(obj->Num, Edi_Int_IRQ_Handler) )
+                       return ;
+       obj->Handler = Handler;
+}
+
+/**
+ * \fn void EDI_Int_IRQ_Return(object_pointer Object)
+ * \brief Return from interrupt
+ * \param Object       IRQ Object
+ * \note Due to the structure of acess interrupts, this is a dummy
+ */
+void EDI_Int_IRQ_Return(object_pointer Object)
+{
+}
+
+/**
+ * \fn void Edi_Int_IRQ_Handler(struct regs *Regs)
+ * \brief EDI IRQ Handler - Calls the handler 
+ * \param Regs Register state at IRQ call
+ */
+void Edi_Int_IRQ_Handler(struct regs *Regs)
+{
+        int    i;
+       for( i = 0; i < 16; i ++ )
+       {
+               if(!gEdi_IRQObjects[i].State)   continue;       // Unused, Skip
+               if(gEdi_IRQObjects[i].Num != Regs->int_no)      continue;       // Another IRQ, Skip
+               if(!gEdi_IRQObjects[i].Handler) continue;       // No Handler, Skip
+               gEdi_IRQObjects[i].Handler( Regs->int_no );     // Call Handler
+               return;
+       }
+}
+
+
+// === CLASS DECLARATION ===
+static edi_function_declaration_t      scEdi_Int_Functions_IRQ[] = {
+               {"int32_t", "init_interrupt", 1, 3, NULL, //scEdi_Int_Variables_IO[0],
+                       (function_pointer)Edi_Int_IRQ_InitInt
+                       },
+               {"uint32_t", "interrupt_get_irq", 1, 1, NULL, //scEdi_Int_Variables_IO[1],
+                       (function_pointer)Edi_Int_IRQ_GetInt
+                       },
+               {"void", "interrupt_set_handler", 1, 2, NULL, //scEdi_Int_Variables_IO[2],
+                       (function_pointer)Edi_Int_IRQ_GetInt
+                       },
+               {"void", "interrupt_return", 1, 1, NULL, //scEdi_Int_Variables_IO[3],
+                       (function_pointer)Edi_Int_IRQ_GetInt
+                       }
+       };
+static edi_class_declaration_t scEdi_Int_Class_IRQ = 
+       {
+               INTERRUPTS_CLASS, 1, 12,
+               scEdi_Int_Functions_IRQ,
+               Edi_Int_IRQ_Construct,
+               Edi_Int_IRQ_Destruct,
+               NULL
+       };
diff --git a/Modules/Interfaces/EDI/edi_io.inc.c b/Modules/Interfaces/EDI/edi_io.inc.c
new file mode 100644 (file)
index 0000000..8a6ef22
--- /dev/null
@@ -0,0 +1,391 @@
+/*
+ * AcessOS EDI Interface
+ * - IO Port Class
+ * 
+ * By John Hodge (thePowersGang)
+ * 
+ * This file has been released into the public domain.
+ * You are free to use it as you wish.
+ */
+#include "edi/edi.h"
+
+// === TYPES ===
+typedef struct {
+       uint16_t        State;  // 0: Unallocated, 1: Allocated, 2: Initialised, (Bit 0x8000 set if in heap)
+       uint16_t        Num;
+} tEdiPort;
+
+// === GLOBALS ===
+#define        NUM_PREALLOC_PORTS      128
+tEdiPort       gEdi_PortObjects[NUM_PREALLOC_PORTS];
+
+// === FUNCTIONS ===
+/**
+ * \fn object_pointer Edi_Int_IO_Construct(void)
+ * \brief Creates a new IO Port Object
+ * \return     Pointer to object
+ */
+object_pointer Edi_Int_IO_Construct(void)
+{
+       tEdiPort        *ret;
+        int    i;
+       // Search for a free preallocated port
+       for( i = 0; i < NUM_PREALLOC_PORTS; i ++ )
+       {
+               if(gEdi_PortObjects[i].State)   continue;
+               gEdi_PortObjects[i].State = 1;
+               gEdi_PortObjects[i].Num = 0;
+               return &gEdi_PortObjects[i];
+       }
+       // Else, use heap space
+       ret = malloc( sizeof(tEdiPort) );
+       ret->State = 0x8001;
+       ret->Num = 0;
+       return ret;
+}
+
+/**
+ * \fn void Edi_Int_IO_Destruct(object_pointer Object)
+ * \brief Destruct an IO Port Object
+ * \param Object       Object to destroy
+ */
+void Edi_Int_IO_Destruct(object_pointer Object)
+{
+       tEdiPort        *obj;
+       // Get Data Pointer
+       VALIDATE_PTR(Object,);
+       obj = GET_DATA(Object);
+       
+       if(obj->State & 0x8000) {       // If in heap, free
+               free(Object);
+       } else {        // Otherwise, mark as unallocated
+               obj->State = 0;
+       }
+}
+
+/**
+ * \fn int32_t Edi_Int_IO_InitPort(object_pointer Object, uint16_t Port)
+ * \brief Initialises an IO Port
+ * \param Object       Object Pointer (this)
+ * \param Port Port Number to use
+ */
+int32_t        Edi_Int_IO_InitPort(object_pointer Object, uint16_t Port)
+{
+       tEdiPort        *obj;
+       // Get Data Pointer
+       VALIDATE_PTR(Object, 0);
+       obj = GET_DATA(Object);
+       
+       if( !obj->State )       return 0;
+       obj->Num = Port;
+       obj->State &= ~0x3FFF;
+       obj->State |= 2;        // Set initialised flag
+       return 1;
+}
+
+/**
+ * \fn uint16_t Edi_Int_IO_GetPortNum(object_pointer Object)
+ * \brief Returns the port number associated with the object
+ * \param Object       Port Object to get number from
+ * \return Port Number
+ */
+uint16_t Edi_Int_IO_GetPortNum(object_pointer Object)
+{
+       tEdiPort        *obj;
+       // Get Data Pointer
+       VALIDATE_PTR(Object, 0);
+       obj = GET_DATA(Object);
+       // Check if valid
+       if( !obj->State )       return 0;
+       // Return Port No
+       return obj->Num;
+}
+
+/**
+ * \fn int32_t Edi_Int_IO_ReadByte(object_pointer Object, uint8_t *out)
+ * \brief Read a byte from an IO port
+ * \param Object       Port Object
+ * \param out  Pointer to put read data
+ */
+int32_t Edi_Int_IO_ReadByte(object_pointer Object, uint8_t *out)
+{
+       tEdiPort        *obj;
+       // Get Data Pointer
+       VALIDATE_PTR(Object, 0);
+       obj = GET_DATA(Object);
+       
+       if( !obj->State )       return 0;
+       if( obj->State & 1 )    return -1;      // Unintialised
+       
+       __asm__ __volatile__ ( "inb %%dx, %%al" : "=a" (*out) : "d" ( obj->Num ) );
+       
+       return 1;
+}
+
+/**
+ * \fn int32_t Edi_Int_IO_ReadWord(object_pointer Object, uint16_t *out)
+ * \brief Read a word from an IO port
+ * \param Object       Port Object
+ * \param out  Pointer to put read data
+ */
+int32_t Edi_Int_IO_ReadWord(object_pointer Object, uint16_t *out)
+{
+       
+       tEdiPort        *obj;
+       // Get Data Pointer
+       VALIDATE_PTR(Object, 0);
+       obj = GET_DATA(Object);
+       if( !obj->State )       return 0;
+       if( obj->State & 1 )    return -1;      // Unintialised
+       
+       __asm__ __volatile__ ( "inw %%dx, %%ax" : "=a" (*out) : "d" ( obj->Num ) );
+       
+       return 1;
+}
+
+/**
+ * \fn int32_t Edi_Int_IO_ReadDWord(object_pointer Object, uint32_t *out)
+ * \brief Read a double word from an IO port
+ * \param Object       Port Object
+ * \param out  Pointer to put read data
+ */
+int32_t Edi_Int_IO_ReadDWord(object_pointer Object, uint32_t *out)
+{
+       
+       tEdiPort        *obj;
+       // Get Data Pointer
+       VALIDATE_PTR(Object, 0);
+       obj = GET_DATA(Object);
+       if( !obj->State )       return 0;
+       if( obj->State & 1 )    return -1;      // Unintialised
+       
+       __asm__ __volatile__ ( "inl %%dx, %%eax" : "=a" (*out) : "d" ( obj->Num ) );
+       
+       return 1;
+}
+
+/**
+ * \fn int32_t Edi_Int_IO_ReadQWord(object_pointer Object, uint64_t *out)
+ * \brief Read a quad word from an IO port
+ * \param Object       Port Object
+ * \param out  Pointer to put read data
+ */
+int32_t Edi_Int_IO_ReadQWord(object_pointer Object, uint64_t *out)
+{
+       uint32_t        *out32 = (uint32_t*)out;
+       tEdiPort        *obj;
+       // Get Data Pointer
+       VALIDATE_PTR(Object, 0);
+       obj = GET_DATA(Object);
+       if( !obj->State )       return 0;
+       if( obj->State & 1 )    return -1;      // Unintialised
+       
+       __asm__ __volatile__ ( "inl %%dx, %%eax" : "=a" (*out32) : "d" ( obj->Num ) );
+       __asm__ __volatile__ ( "inl %%dx, %%eax" : "=a" (*(out32+1)) : "d" ( obj->Num+4 ) );
+       
+       return 1;
+}
+
+/**
+ * \fn int32_t Edi_Int_IO_ReadString(object_pointer Object, uint32_t Length, uint8_t *out)
+ * \brief Read a byte from an IO port
+ * \param Object       Port Object
+ * \param Length       Number of bytes to read
+ * \param out  Pointer to put read data
+ */
+int32_t Edi_Int_IO_ReadString(object_pointer Object, uint32_t Length, uint8_t *out)
+{
+       tEdiPort        *obj;
+       // Get Data Pointer
+       VALIDATE_PTR(Object, 0);
+       obj = GET_DATA(Object);
+       if( !obj->State )       return 0;
+       if( obj->State & 1 )    return -1;      // Unintialised
+       
+       __asm__ __volatile__ ( "rep insb" : : "c" (Length), "D" (out), "d" ( obj->Num ) );
+       
+       return 1;
+}
+
+/**
+ * \fn int32_t Edi_Int_IO_WriteByte(object_pointer Object, uint8_t in)
+ * \brief Write a byte from an IO port
+ * \param Object       Port Object
+ * \param in   Data to write
+ */
+int32_t Edi_Int_IO_WriteByte(object_pointer Object, uint8_t in)
+{
+       tEdiPort        *obj;
+       // Get Data Pointer
+       VALIDATE_PTR(Object, 0);
+       obj = GET_DATA(Object);
+       if( !obj->State )       return 0;
+       if( obj->State & 1 )    return -1;      // Unintialised
+       
+       __asm__ __volatile__ ( "outb %%al, %%dx" : : "a" (in), "d" ( obj->Num ) );
+       
+       return 1;
+}
+
+/**
+ * \fn int32_t Edi_Int_IO_WriteWord(object_pointer Object, uint16_t in)
+ * \brief Write a word from an IO port
+ * \param Object       Port Object
+ * \param in   Data to write
+ */
+int32_t Edi_Int_IO_WriteWord(object_pointer Object, uint16_t in)
+{
+       tEdiPort        *obj;
+       // Get Data Pointer
+       VALIDATE_PTR(Object, 0);
+       obj = GET_DATA(Object);
+       if( !obj->State )       return 0;
+       if( obj->State & 1 )    return -1;      // Unintialised
+       
+       __asm__ __volatile__ ( "outw %%ax, %%dx" : : "a" (in), "d" ( obj->Num ) );
+       
+       return 1;
+}
+
+/**
+ * \fn int32_t Edi_Int_IO_WriteDWord(object_pointer Object, uint32_t in)
+ * \brief Write a double word from an IO port
+ * \param Object       Port Object
+ * \param in   Data to write
+ */
+int32_t Edi_Int_IO_WriteDWord(object_pointer Object, uint32_t in)
+{
+       tEdiPort        *obj;
+       // Get Data Pointer
+       VALIDATE_PTR(Object, 0);
+       obj = GET_DATA(Object);
+       if( !obj->State )       return 0;
+       if( obj->State & 1 )    return -1;      // Unintialised
+       
+       __asm__ __volatile__ ( "outl %%eax, %%dx" : : "a" (in), "d" ( obj->Num ) );
+       
+       return 1;
+}
+
+/**
+ * \fn int32_t Edi_Int_IO_WriteQWord(object_pointer Object, uint64_t in)
+ * \brief Write a quad word from an IO port
+ * \param Object       Port Object
+ * \param in   Data to write
+ */
+int32_t Edi_Int_IO_WriteQWord(object_pointer Object, uint64_t in)
+{
+       uint32_t        *in32 = (uint32_t*)&in;
+       tEdiPort        *obj;
+       // Get Data Pointer
+       VALIDATE_PTR(Object, 0);
+       obj = GET_DATA(Object);
+       if( !obj->State )       return 0;
+       if( obj->State & 1 )    return -1;      // Unintialised
+       
+       __asm__ __volatile__ ( "outl %%eax, %%dx" : : "a" (*in32), "d" ( obj->Num ) );
+       __asm__ __volatile__ ( "outl %%eax, %%dx" : : "a" (*(in32+1)), "d" ( obj->Num+4 ) );
+       
+       return 1;
+}
+
+/**
+ * \fn int32_t Edi_Int_IO_WriteString(object_pointer Object, uint32_t Length, uint8_t *in)
+ * \brief Read a byte from an IO port
+ * \param Object       Port Object
+ * \param Length       Number of bytes to write
+ * \param in   Pointer to of data to write
+ */
+int32_t Edi_Int_IO_WriteString(object_pointer Object, uint32_t Length, uint8_t *in)
+{
+       tEdiPort        *obj;
+       // Get Data Pointer
+       VALIDATE_PTR(Object, 0);
+       obj = GET_DATA(Object);
+       if( !obj->State )       return 0;
+       if( obj->State & 1 )    return -1;      // Unintialised
+       
+       __asm__ __volatile__ ( "rep outsb" : : "c" (Length), "D" (in), "d" ( obj->Num ) );
+       
+       return 1;
+}
+
+// === CLASS DECLARATION ===
+/*static edi_variable_declaration_t    *scEdi_Int_Variables_IO[] = {
+       {
+               {"pointer", "port_object", 0},
+               {"uint16_t", "port", 0}
+       },
+       {
+               {"pointer", "port_object", 0}
+       },
+       {
+               {"pointer", "port_object", 0},
+               {"pointer int8_t", "out", 0}
+       }
+};*/
+static edi_function_declaration_t      scEdi_Int_Functions_IO[] = {
+               {"int32_t", "init_io_port", 1, 2, NULL, //scEdi_Int_Variables_IO[0],
+                       (function_pointer)Edi_Int_IO_InitPort
+                       },
+               {"uint16_t", "get_port_number", 1, 1, NULL, //scEdi_Int_Variables_IO[1],
+                       (function_pointer)Edi_Int_IO_GetPortNum
+                       },
+               {"int32_t", "read_byte_io_port", 1, 2, NULL, //scEdi_Int_Variables_IO[2],
+                       (function_pointer)Edi_Int_IO_ReadByte
+                       },
+               {"int32_t", "read_word_io_port", 1, 2, NULL/*{
+                               {"pointer", "port_object", 0},
+                               {"pointer int16_t", "out", 0}
+                       }*/,
+                       (function_pointer)Edi_Int_IO_ReadWord
+                       },
+               {"int32_t", "read_long_io_port", 1, 2, NULL/*{
+                               {"pointer", "port_object", 0},
+                               {"pointer int32_t", "out", 0}
+                       }*/,
+                       (function_pointer)Edi_Int_IO_ReadDWord
+                       },
+               {"int32_t", "read_longlong_io_port", 1, 2, NULL/*{
+                               {"pointer", "port_object", 0},
+                               {"pointer int64_t", "out", 0}
+                       }*/,
+                       (function_pointer)Edi_Int_IO_ReadQWord
+                       },
+               {"int32_t", "read_string_io_port", 1, 3, NULL/*{
+                               {"pointer", "port_object", 0},
+                               {"int32_T", "data_length", 0},
+                               {"pointer int64_t", "out", 0}
+                       }*/,
+                       (function_pointer)Edi_Int_IO_ReadString
+                       },
+                       
+               {"int32_t", "write_byte_io_port", 1, 2, NULL/*{
+                               {"pointer", "port_object", 0},
+                               {"int8_t", "in", 0}
+                       }*/,
+                       (function_pointer)Edi_Int_IO_WriteByte},
+               {"int32_t", "write_word_io_port", 1, 2, NULL/*{
+                               {"pointer", "port_object", 0},
+                               {"int16_t", "in", 0}
+                       }*/,
+                       (function_pointer)Edi_Int_IO_WriteWord},
+               {"int32_t", "write_long_io_port", 1, 2, NULL/*{
+                               {"pointer", "port_object", 0},
+                               {"int32_t", "in", 0}
+                       }*/,
+                       (function_pointer)Edi_Int_IO_WriteDWord},
+               {"int32_t", "write_longlong_io_port", 1, 2, NULL/*{
+                               {"pointer", "port_object", 0},
+                               {"int64_t", "in", 0}
+                       }*/,
+                       (function_pointer)Edi_Int_IO_WriteQWord}
+       };
+static edi_class_declaration_t scEdi_Int_Class_IO = 
+       {
+               IO_PORT_CLASS, 1, 12,
+               scEdi_Int_Functions_IO,
+               Edi_Int_IO_Construct,
+               Edi_Int_IO_Destruct,
+               NULL
+       };
diff --git a/Modules/Interfaces/EDI/main.c b/Modules/Interfaces/EDI/main.c
new file mode 100644 (file)
index 0000000..c3d0272
--- /dev/null
@@ -0,0 +1,496 @@
+/*
+ * Acess2 EDI Layer
+ */
+#define DEBUG  0
+#define VERSION        ((0<<8)|1)
+#include <acess.h>
+#include <modules.h>
+#include <fs_devfs.h>
+#define        IMPLEMENTING_EDI        1
+#include "edi/edi.h"
+
+#define        VALIDATE_PTR(_ptr,_err) do{if(!(_ptr))return _err; }while(0)
+#define        GET_DATA(_ptr)  (Object)
+
+#include "edi_io.inc.c"
+#include "edi_int.inc.c"
+
+// === STRUCTURES ===
+typedef struct sAcessEdiDriver {
+       struct sAcessEdiDriver  *Next;
+       tDevFS_Driver   Driver;
+        int    FileCount;
+       struct {
+               char    *Name;
+               tVFS_Node       Node;
+       }       *Files;
+       edi_object_metadata_t   *Objects;
+       edi_initialization_t    Init;
+       driver_finish_t Finish;
+} tAcessEdiDriver;
+
+// === PROTOTYPES ===
+ int   EDI_Install(char **Arguments);
+ int   EDI_DetectDriver(void *Base);
+ int   EDI_LoadDriver(void *Base);
+vfs_node *EDI_FS_ReadDir(vfs_node *Node, int Pos);
+vfs_node *EDI_FS_FindDir(vfs_node *Node, char *Name);
+ int   EDI_FS_CharRead(vfs_node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
+ int   EDI_FS_CharWrite(vfs_node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
+ int   EDI_FS_IOCtl(vfs_node *Node, int Id, void *Data);
+data_pointer EDI_GetInternalClass(edi_string_t ClassName);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, VERSION, EDI, EDI_Install, NULL, NULL);
+tModuleLoader  gEDI_Loader = {
+       NULL, "EDI", EDI_DetectDriver, EDI_LoadDriver, NULL
+};
+tSpinlock      glEDI_Drivers;
+tAcessEdiDriver        *gEdi_Drivers = NULL;
+edi_class_declaration_t        *gcEdi_IntClasses[] = {
+       &scEdi_Int_Class_IO, &scEdi_Int_Class_IRQ
+};
+#define        NUM_INT_CLASSES (sizeof(gcEdi_IntClasses)/sizeof(gcEdi_IntClasses[0]))
+char *csCharNumbers[] = {"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9"};
+char *csBlockNumbers[] = {"blk0", "blk1", "blk2", "blk3", "blk4", "blk5", "blk6", "blk7", "blk8", "blk9"};
+
+// === CODE ===
+/**
+ * \fn int EDI_Install(char **Arguments)
+ * \brief Stub intialisation routine
+ */
+int EDI_Install(char **Arguments)
+{
+       Module_RegisterLoader( &gEDI_Loader );
+       return 1;
+}
+
+/**
+ * \brief Detects if a driver should be loaded by the EDI subsystem
+ */
+int EDI_DetectDriver(void *Base)
+{
+       if( Binary_FindSymbol(BASE, "driver_init", NULL) == 0 )
+               return 0;
+       
+       return 1;
+}
+
+/**
+ * \fn int Edi_LoadDriver(void *Base)
+ * \brief Load an EDI Driver from a loaded binary
+ * \param Base Binary Handle
+ * \return 0 on success, non zero on error
+ */
+int EDI_LoadDriver(void *Base)
+{
+       driver_init_t   init;
+       driver_finish_t finish;
+       tAcessEdiDriver *info;
+        int    i, j;
+        int    devfsId;
+       edi_class_declaration_t *classes;
+
+       ENTER("pBase", Base);
+       
+       // Get Functions
+       if( !Binary_FindSymbol(Base, "driver_init", (Uint*)&init)
+       ||      !Binary_FindSymbol(Base, "driver_finish", (Uint*)&finish) )
+       {
+               Warning("[EDI  ] Driver %p does not provide both `driver_init` and `driver_finish`\n", Base);
+               Binary_Unload(Base);
+               return 0;
+       }
+       
+       // Allocate Driver Information
+       info = malloc( sizeof(tAcessEdiDriver) );
+       info->Finish = finish;
+       
+       // Initialise Driver
+       info->Init = init( 0, NULL );   // TODO: Implement Resources
+       
+       LOG("info->Init.driver_name = '%s'", info->Init.driver_name);
+       LOG("info->Init.num_driver_classes = %i", info->Init.num_driver_classes);
+       
+       // Count mappable classes
+       classes = info->Init.driver_classes;
+       info->FileCount = 0;
+       info->Objects = NULL;
+       for( i = 0, j = 0; i < info->Init.num_driver_classes; i++ )
+       {
+               if( strncmp(classes[i].name, "EDI-CHARACTER-DEVICE", 32) == 0 )
+               {
+                       data_pointer    *obj;
+                       // Initialise Object Instances
+                       for( ; (obj = classes[i].constructor()); j++ ) {
+                               LOG("%i - Constructed '%s'", j, classes[i].name);
+                               info->FileCount ++;
+                               info->Objects = realloc(info->Objects, sizeof(*info->Objects)*info->FileCount);
+                               info->Objects[j].object = obj;
+                               info->Objects[j].object_class = &classes[i];
+                       }
+               }
+               else
+                       LOG("%i - %s", i, classes[i].name);
+       }
+       
+       if(info->FileCount)
+       {
+                int    iNumChar = 0;
+               // Create VFS Nodes
+               info->Files = malloc( info->FileCount * sizeof(*info->Files) );
+               memset(info->Files, 0, info->FileCount * sizeof(*info->Files));
+               j = 0;
+               for( j = 0; j < info->FileCount; j++ )
+               {
+                       classes = info->Objects[j].object_class;
+                       if( strncmp(classes->name, "EDI-CHARACTER-DEVICE", 32) == 0 )
+                       {
+                               LOG("%i - %s", j, csCharNumbers[iNumChar]);
+                               info->Files[j].Name = csCharNumbers[iNumChar];
+                               info->Files[j].Node.NumACLs = 1;
+                               info->Files[j].Node.ACLs = &gVFS_ACL_EveryoneRW;
+                               info->Files[j].Node.ImplPtr = &info->Objects[j];
+                               info->Files[j].Node.Read = EDI_FS_CharRead;
+                               info->Files[j].Node.Write = EDI_FS_CharWrite;
+                               info->Files[j].Node.IOCtl = EDI_FS_IOCtl;
+                               info->Files[j].Node.CTime =
+                                       info->Files[j].Node.MTime =
+                                       info->Files[j].Node.ATime = now();
+                               
+                               iNumChar ++;
+                               continue;
+                       }
+               }
+               
+               // Create DevFS Driver
+               info->Driver.ioctl = EDI_FS_IOCtl;
+               memsetda(&info->Driver.rootNode, 0, sizeof(vfs_node) / 4);
+               info->Driver.Name = info->Init.driver_name;
+               info->Driver.RootNode.Flags = VFS_FFLAG_DIRECTORY;
+               info->Driver.RootNode.NumACLs = 1;
+               info->Driver.RootNode.ACLs = &gVFS_ACL_EveryoneRX;
+               info->Driver.RootNode.Length = info->FileCount;
+               info->Driver.RootNode.ImplPtr = info;
+               info->Driver.RootNode.ReadDir = EDI_FS_ReadDir;
+               info->Driver.RootNode.FindDir = EDI_FS_FindDir;
+               info->Driver.RootNode.IOCtl = EDI_FS_IOCtl;
+               
+               // Register
+               devfsId = dev_addDevice( &info->Driver );
+               if(devfsId == -1) {
+                       free(info->Files);      // Free Files
+                       info->Finish(); // Clean up driver
+                       free(info);             // Free info structure
+                       Binary_Unload(iDriverBase);     // Unload library
+                       return -3;      // Return error
+               }
+       }
+       
+       // Append to loaded list;
+       LOCK(&glEDI_Drivers);
+       info->Next = gEDI_Drivers;
+       gEDI_Drivers = info;
+       RELEASE(&glEDI_Drivers);
+       
+       LogF("[EDI ] Loaded Driver '%s' (%s)\n", info->Init.driver_name, Path);
+       LEAVE('i', 1);
+       return 1;
+}
+
+// --- Filesystem Interaction ---
+/**
+ * \brief Read from a drivers class list
+ * \param Node Driver's Root Node
+ * \param Pos  Index of file to get
+ */
+char *EDI_FS_ReadDir(tVFS_Node *Node, int Pos)
+{
+       tAcessEdiDriver *info;
+       
+       // Sanity Check
+       if(!Node)       return NULL;
+       
+       // Get Information Structure
+       info = (void *) Node->ImplPtr;
+       if(!info)       return NULL;
+       
+       // Check Position
+       if(Pos < 0)     return NULL;
+       if(Pos >= info->FileCount)      return NULL;
+       
+       return strdup( info->Files[Pos].Name );
+}
+
+/**
+ * \fn tVFS_Node *EDI_FS_FindDir(tVFS_Node *Node, char *Name)
+ * \brief Find a named file in a driver
+ * \param Node Driver's Root Node
+ * \param Name Name of file to find
+ */
+tVFS_Node *EDI_FS_FindDir(tVFS_Node *Node, char *Name)
+{
+       tAcessEdiDriver *info;
+        int    i;
+       
+       // Sanity Check
+       if(!Node)       return NULL;
+       if(!Name)       return NULL;
+       
+       // Get Information Structure
+       info = (void *) Node->ImplPtr;
+       if(!info)       return NULL;
+       
+       for( i = 0; i < info->FileCount; i++ )
+       {
+               if(strcmp(info->Files[i].name, Name) == 0)
+                       return &info->Files[i].Node;
+       }
+       
+       return NULL;
+}
+
+/**
+ * \fn Uint64 EDI_FS_CharRead(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+ * \brief Read from an EDI Character Device
+ * \param Node File Node
+ * \param Offset       Offset into file (ignored)
+ * \param Length       Number of characters to read
+ * \param Buffer       Destination for data
+ * \return     Number of characters read
+ */
+Uint64 EDI_FS_CharRead(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+{
+       edi_object_metadata_t   *meta;
+       edi_class_declaration_t *class;
+       
+       // Sanity Check
+       if(!Node || !Buffer)    return 0;
+       if(Length <= 0) return 0;
+       // Get Object Metadata
+       meta = (void *) Node->ImplPtr;
+       if(!meta)       return 0;
+       
+       // Get Class
+       class = meta->object_class;
+       if(!class)      return 0;
+       
+       // Read from object
+       if( ((tAnyFunction) class->methods[0].code)( meta->object, Buffer, Length ))
+               return Length;
+
+       return 0;
+}
+
+/**
+ * \fn Uint64 EDI_FS_CharWrite(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+ * \brief Write to an EDI Character Device
+ * \param Node File Node
+ * \param Offset       Offset into file (ignored)
+ * \param Length       Number of characters to write
+ * \param Buffer       Source for data
+ * \return     Number of characters written
+ */
+Uint64 EDI_FS_CharWrite(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+{
+       edi_object_metadata_t   *meta;
+       edi_class_declaration_t *class;
+       
+       // Sanity Check
+       if(!Node || !Buffer)    return 0;
+       if(Length <= 0) return 0;
+       // Get Object Metadata
+       meta = (void *) Node->ImplPtr;
+       if(!meta)       return 0;
+       
+       // Get Class
+       class = meta->object_class;
+       if(!class)      return 0;
+       
+       // Write to object
+       if( ((tAnyFunction) class->methods[1].code)( meta->object, Buffer, Length ))
+               return Length;
+
+       return 0;
+}
+
+/**
+ * \fn int EDI_FS_IOCtl(tVFS_Node *Node, int Id, void *Data)
+ * \brief Perfom an IOCtl call on the object
+ */
+int EDI_FS_IOCtl(tVFS_Node *Node, int Id, void *Data)
+{
+       return 0;
+}
+
+// --- EDI Functions ---
+/**
+ * \fn data_pointer EDI_GetDefinedClass(edi_string_t ClassName)
+ * \brief Gets the structure of a driver defined class
+ * \param ClassName    Name of class to find
+ * \return Class definition or NULL
+ */
+data_pointer EDI_GetDefinedClass(edi_string_t ClassName)
+{
+        int    i;
+       tAcessEdiDriver *drv;
+       edi_class_declaration_t *classes;
+       
+       for(drv = gEdi_Drivers;
+               drv;
+               drv = drv->Next )
+       {
+               classes = drv->Init.driver_classes;
+               for( i = 0; i < drv->Init.num_driver_classes; i++ )
+               {
+                       if( strncmp(classes[i].name, ClassName, 32) == 0 )
+                               return &classes[i];
+               }
+       }
+       return NULL;
+}
+
+/**
+ * \fn int32_t EDI_CheckClassExistence(edi_string_t ClassName)
+ * \brief Checks if a class exists
+ * \param ClassName    Name of class
+ * \return 1 if the class exists, -1 otherwise
+ */
+int32_t EDI_CheckClassExistence(edi_string_t ClassName)
+{
+       //LogF("check_class_existence: (ClassName='%s')\n", ClassName);
+       if(EDI_GetInternalClass(ClassName))
+               return 1;
+               
+       if(EDI_GetDefinedClass(ClassName))      // Driver Defined
+               return 1;
+       
+       return -1;
+}
+
+/**
+ * \fn edi_object_metadata_t EDI_ConstructObject(edi_string_t ClassName)
+ * \brief Construct an instance of an class (an object)
+ * \param ClassName    Name of the class to construct
+ */
+edi_object_metadata_t EDI_ConstructObject(edi_string_t ClassName)
+{
+       edi_object_metadata_t   ret = {0, 0};
+       edi_class_declaration_t *class;
+       
+       //LogF("EDI_ConstructObject: (ClassName='%s')\n", ClassName);
+       
+       // Get class definition
+       if( !(class = EDI_GetInternalClass(ClassName)) )        // Internal
+               if( !(class = EDI_GetDefinedClass(ClassName)) ) // Driver Defined
+                       return ret;             // Return ERROR
+       
+       // Initialise
+       ret.object = class->constructor();
+       if( !ret.object )
+               return ret;     // Return ERROR
+       
+       // Set declaration pointer
+       ret.object_class = class;
+       
+       //LogF("EDI_ConstructObject: RETURN {0x%x,0x%x}\n", ret.object, ret.object_class);
+       return ret;
+}
+
+/**
+ * \fn void EDI_DestroyObject(edi_object_metadata_t Object)
+ * \brief Destroy an instance of a class
+ * \param Object       Object to destroy
+ */
+void EDI_DestroyObject(edi_object_metadata_t Object)
+{
+       if( !Object.object )    return;
+       if( !Object.object_class )      return;
+       
+       ((edi_class_declaration_t*)(Object.object_class))->destructor( &Object );
+}
+
+/**
+ * \fn function_pointer EDI_GetMethodByName(data_pointer ObjectClass, edi_string_t MethodName)
+ * \brief Get a method of a class by it's name
+ * \param ObjectClass  Pointer to a ::edi_object_metadata_t of the object
+ * \param MethodName   Name of the desired method
+ * \return Function address or NULL
+ */
+function_pointer EDI_GetMethodByName(data_pointer ObjectClass, edi_string_t MethodName)
+{
+       edi_class_declaration_t *dec = ObjectClass;
+        int    i;
+       
+       //LogF("get_method_by_name: (ObjectClass=0x%x, MethodName='%s')\n", ObjectClass, MethodName);
+       
+       if(!ObjectClass)        return NULL;
+       
+       for(i = 0; i < dec->num_methods; i++)
+       {
+               if(strncmp(MethodName, dec->methods[i].name, 32) == 0)
+                       return dec->methods[i].code;
+       }
+       return NULL;
+}
+
+#if 0
+function_pointer get_method_by_declaration(data_pointer Class, edi_function_declaration_t Declaration);
+#endif
+
+/**
+ * \fn edi_string_ptr_t EDI_GetClassParent(edi_string_t ClassName)
+ * \brief Get the parent of the named class
+ * \todo Implement
+ */
+edi_string_ptr_t EDI_GetClassParent(edi_string_t ClassName)
+{
+       WarningEx("EDI", "`get_class_parent` is unimplemented");
+       return NULL;
+}
+
+/**
+ * \fn data_pointer EDI_GetInternalClass(edi_string_t ClassName)
+ * \brief Get a builtin class
+ * \param ClassName    Name of class to find
+ * \return Pointer to the ::edi_class_declaration_t of the class
+ */
+data_pointer EDI_GetInternalClass(edi_string_t ClassName)
+{
+        int    i;
+       //LogF("get_internal_class: (ClassName='%s')\n", ClassName);
+       for( i = 0; i < NUM_INT_CLASSES; i++ )
+       {
+               if( strncmp( gcEdi_IntClasses[i]->name, ClassName, 32 ) == 0 ) {
+                       return gcEdi_IntClasses[i];
+               }
+       }
+       //LogF("get_internal_class: RETURN NULL\n");
+       return NULL;
+}
+
+/**
+ * \fn edi_string_ptr_t EDI_GetObjectClass(data_pointer Object)
+ * \brief Get the name of the object of \a Object
+ * \param Object       Object to get name of
+ * \return Pointer to the class name
+ */
+edi_string_ptr_t EDI_GetObjectClass(data_pointer ObjectClass)
+{
+       edi_object_metadata_t   *Metadata = ObjectClass;
+       // Sanity Check
+       if(!ObjectClass)        return NULL;
+       if(!(edi_class_declaration_t*) Metadata->object_class)  return NULL;
+       
+       // Return Class Name
+       return ((edi_class_declaration_t*) Metadata->object_class)->name;
+}
+
+// === EXPORTS ===
+EXPORTAS(EDI_CheckClassExistence, check_class_existence);
+EXPORTAS(EDI_ConstructObject, construct_object);
+EXPORTAS(EDI_DestroyObject, destroy_object);
+EXPORTAS(EDI_GetMethodByName, get_method_by_name);
+EXPORTAS(EDI_GetClassParent, get_class_parent);
+EXPORTAS(EDI_GetInternalClass, get_internal_class);
+EXPORTAS(EDI_GetObjectClass, get_object_class);
diff --git a/Usermode/Applications/axwin2_src/Shell_src/Makefile b/Usermode/Applications/axwin2_src/Shell_src/Makefile
new file mode 100644 (file)
index 0000000..18c4ab1
--- /dev/null
@@ -0,0 +1,12 @@
+# Project: Acess GUI Default Shell
+
+-include ../../Makefile.cfg
+
+CPPFLAGS += -I../include
+LDFLAGS += -laxwin2
+
+DIR = Apps/AxWin/1.0
+BIN = ../Shell
+OBJ = main.o
+
+-include ../../Makefile.tpl
diff --git a/Usermode/Applications/axwin2_src/Shell_src/main.c b/Usermode/Applications/axwin2_src/Shell_src/main.c
new file mode 100644 (file)
index 0000000..b357dea
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Acess2 GUI Shell
+ * - By John Hodge (thePowersGang)
+ */
+#include <axwin/axwin.h>
+
+// === PROTOTYPES ===
+ int   main(int argc, char *argv[]);
+ int   Menubar_HandleMessage(tAxWin_Message *Message);
+
+// === GLOBALS ===
+tAxWin_Handle  ghMenubarWindow;
+
+// === CODE ===
+int main(int argc, char *argv[])
+{      
+       // Create Window
+       ghMenubarWindow = AxWin_CreateWindow(0, 0, -1, -1, WINFLAG_NOBORDER, Menubar_HandleMessage);
+       
+       AxWin_MessageLoop();
+       
+       return 0;
+}
+
+/**
+ */
+int Menubar_HandleMessage(tAxWin_Message *Message)
+{
+       return 0;
+}
index 0b3e8fc..13379fa 100644 (file)
@@ -9,6 +9,9 @@
 #include <stdio.h>
 #include <stdint.h>
 
+#include "wm.h"
+
+// === GLOBALS ===
 extern char    *gsTerminalDevice;
 extern char    *gsMouseDevice;
 
diff --git a/Usermode/Applications/axwin2_src/WM/wm.h b/Usermode/Applications/axwin2_src/WM/wm.h
new file mode 100644 (file)
index 0000000..e7b6bee
--- /dev/null
@@ -0,0 +1,34 @@
+
+#ifndef _WM_H_
+#define _WM_H_
+
+typedef struct sElement
+{
+       struct sElement *NextSibling;
+       
+       short   CachedX;
+       short   CachedY;
+       short   CachedW;
+       short   CachedH;
+       
+       struct sElement *FirstChild;
+}      tElement;
+
+typedef struct sTab
+{
+       char    *Name;
+       
+       tElement        *RootElement;
+}      tTab;
+
+typedef struct sApplication
+{
+       pid_t   PID;
+       
+        int    nTabs;
+       tTab    *Tabs;
+       
+       char    Name[];
+}      tApplication;
+
+#endif
index 1cff6d9..ba78838 100644 (file)
@@ -70,6 +70,13 @@ void DumpInterfaces(int DumpAll)
                type = ioctl(fd, 4, NULL);
                
                printf("%s:\t", filename);
+               {
+                       int len = ioctl(fd, ioctl(fd, 3, "get_device"), NULL);
+                       char *buf = malloc(len+1);
+                       ioctl(fd, ioctl(fd, 3, "get_device"), buf);
+                       printf("'%s'\t", buf);
+                       free(buf);
+               }
                switch(type)
                {
                case 0:
diff --git a/Usermode/Libraries/Makefile.tpl b/Usermode/Libraries/Makefile.tpl
new file mode 100644 (file)
index 0000000..709aaac
--- /dev/null
@@ -0,0 +1,18 @@
+# Acess 2 SQLite 3 Library
+#
+
+.PHONY: all clean install
+
+all: $(BIN)
+
+clean:
+       $(RM) $(BIN) $(OBJ)
+
+install: $(BIN)
+       $(xCP) $(BIN) $(DISTROOT)/Libs/
+
+$(BIN): $(OBJ)
+       $(LD) $(LDFLAGS) -o $(BIN) $(OBJ)
+
+%.o: %.c
+       $(CC) $(CFLAGS) -o $@ -c $<
diff --git a/Usermode/Libraries/libaxwin2.so_src/Makefile b/Usermode/Libraries/libaxwin2.so_src/Makefile
new file mode 100644 (file)
index 0000000..5529140
--- /dev/null
@@ -0,0 +1,13 @@
+# Acess 2 - AxWin GUI Library
+#
+
+include ../Makefile.cfg
+
+CPPFLAGS +=
+CFLAGS   += -Wall
+LDFLAGS  += -lc -soname libaxwin2.so
+
+OBJ = main.o messages.o windows.o
+BIN = ../libaxwin2.so
+
+include ../Makefile.tpl
diff --git a/Usermode/Libraries/libaxwin2.so_src/common.h b/Usermode/Libraries/libaxwin2.so_src/common.h
new file mode 100644 (file)
index 0000000..28d2839
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * AxWin Window Manager Interface Library
+ * By John Hodge (thePowersGang)
+ * This file is published under the terms of the Acess Licence. See the
+ * file COPYING for details.
+ * 
+ * common.h - Internal Variable and Constant definitions
+ */
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+// === Includes ===
+#include <acess/sys.h>
+#include <axwin/axwin.h>
+#include <stdlib.h>
+
+// === Constants ===
+enum eAxWin_Modes
+{
+       AXWIN_MODE_IPC
+};
+
+// === Variables ===
+extern int     giAxWin_Mode;
+
+#endif
diff --git a/Usermode/Libraries/libaxwin2.so_src/main.c b/Usermode/Libraries/libaxwin2.so_src/main.c
new file mode 100644 (file)
index 0000000..1a12561
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * AxWin Window Manager Interface Library
+ * By John Hodge (thePowersGang)
+ * This file is published under the terms of the Acess Licence. See the
+ * file COPYING for details.
+ * 
+ * main.c - Library Initialisation
+ */
+#include "common.h"
+
+// === GLOBALS ===
+ int   giAxWin_Mode = 0;
+
+// === CODE ===
+int SoMain()
+{
+       return 0;
+}
diff --git a/Usermode/Libraries/libaxwin2.so_src/messages.c b/Usermode/Libraries/libaxwin2.so_src/messages.c
new file mode 100644 (file)
index 0000000..d0fc5da
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * AxWin Window Manager Interface Library
+ * By John Hodge (thePowersGang)
+ * This file is published under the terms of the Acess Licence. See the
+ * file COPYING for details.
+ * 
+ * messages.c - Message Handling
+ */
+#include "common.h"
+
+// === PROTOTYPES ===
+ int   AxWin_MessageLoop();
+tAxWin_Message *AxWin_WaitForMessage();
+ int   AxWin_HandleMessage(tAxWin_Message *Message);
+
+// === CODE ===
+/**
+ * \brief Loop forever, checking and waiting for messages
+ */
+int AxWin_MessageLoop()
+{
+       tAxWin_Message  *msg;
+        int    ret;
+       for(;;)
+       {
+               msg = AxWin_WaitForMessage();
+               ret = AxWin_HandleMessage(msg);
+               
+               if(ret < 0)     return 0;
+       }
+       return 0;
+}
+
+/**
+ * \brief Wait for a message
+ */
+tAxWin_Message *AxWin_WaitForMessage()
+{
+        int    length;
+       pid_t   src;
+       tAxWin_Message  *ret;
+       
+       switch( giAxWin_Mode )
+       {
+       case AXWIN_MODE_IPC:
+               while( (length = SysGetMessage(&src, NULL)) == 0 )      sleep();
+               ret = malloc(length);
+               SysGetMessage(NULL, ret);
+               break;
+       default:
+               break;
+       }
+       return 0;
+}
+
+/**
+ * \brief Handles a recieved message
+ */
+int AxWin_HandleMessage(tAxWin_Message *Message)
+{
+       switch(Message->ID)
+       {
+       default:        return 0;
+       }
+}
diff --git a/Usermode/Libraries/libaxwin2.so_src/windows.c b/Usermode/Libraries/libaxwin2.so_src/windows.c
new file mode 100644 (file)
index 0000000..a37bfbb
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * AxWin Window Manager Interface Library
+ * By John Hodge (thePowersGang)
+ * This file is published under the terms of the Acess Licence. See the
+ * file COPYING for details.
+ * 
+ * window.c - Window Control
+ */
+#include "common.h"
+
+// === TYPES & STRUCTURES ===
+struct sAxWin_Window
+{
+       struct sAxWin_Window    *Next;
+       uint32_t        WmHandle;
+       tAxWin_MessageCallback  Callback;
+};
+
+// === PROTOTYPES ===
+tAxWin_Handle  AxWin_CreateWindow(
+       int16_t X, int16_t Y, int16_t W, int16_t H,
+       uint32_t Flags, tAxWin_MessageCallback *Callback
+       );
+
+// === GLOBALS ===
+//mutex_t      glProcessWindows;
+tAxWin_Window  *gProcessWindows;
+
+// === CODE ===
+tAxWin_Handle  AxWin_CreateWindow(
+       int16_t X, int16_t Y,
+       int16_t W, int16_t H,
+       uint32_t Flags, tAxWin_MessageCallback *Callback)
+{
+       tAxWin_Message  req;
+       tAxWin_Message  *msg;
+       tAxWin_Window   *win;
+       
+       req.ID = MSG_SREQ_NEWWINDOW;
+       req.Size = 1 + sizeof(struct sAxWin_SReq_NewWindow)/4;
+       req.SReq_NewWindow.X = X;
+       req.SReq_NewWindow.Y = Y;
+       req.SReq_NewWindow.W = W;
+       req.SReq_NewWindow.H = H;
+       req.SReq_NewWindow.Flags = Flags;
+       
+       AxWin_SendMessage(&msg);
+       
+       for(;;)
+       {
+               msg = AxWin_WaitForMessage();
+               
+               if(msg.ID == MSG_SRSP_WINDOW)
+                       break;
+               
+               AxWin_HandleMessage(msg);
+               free(msg);
+       }
+       
+       win = malloc(sizeof(tAxWin_Window));
+       win->WmHandle = msg->SRsp_Window.Handle;
+       win->Callback = Callback;
+       
+       //mutex_acquire(glProcessWindows);
+       win->Next = gProcessWindows;
+       gProcessWindows = win;
+       //mutex_release(glProcessWindows);
+       
+       return 0;
+}
diff --git a/Usermode/include/axwin/axwin.h b/Usermode/include/axwin/axwin.h
new file mode 100644 (file)
index 0000000..ee160b8
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * \file axwin.h
+ * \author John Hodge (thePowersGang)
+ * \brief AxWin Core functions
+ */
+#ifndef _AXWIN_AXWIN_H
+#define _AXWIN_AXWIN_H
+
+// === Core Types ===
+typedef unsigned int   tAxWin_Handle;
+
+// === Messaging ===
+#include "messages.h"
+extern int     AxWin_MessageLoop();
+
+// === Window Control ===
+/**
+ * \brief Window Type
+ * \note Opaque Type
+ */
+typedef struct sAxWin_Window   tAxWin_Window;
+
+typedef int    tAxWin_MessageCallback(tAxWin_Message *);
+
+/**
+ * \brief Window Flags
+ * \{
+ */
+#define WINFLAG_NOBORDER       0x100
+/**
+ * \}
+ */
+extern tAxWin_Window   AxWin_CreateWindow(
+               int16_t X, int16_t Y, int16_t W, int16_t H,
+               uint32_t Flags, tAxWin_MessageCallback *Callback);
+
+#endif
index e4ed1fe..b27583e 100644 (file)
@@ -18,10 +18,23 @@ enum eAxWin_Messages
        // Server Requests
        MSG_SREQ_PING,
        // - Windows
-       MSG_SREQ_NEWWINDOW,     // (short x, y, w, h, uint32_t flags)
-       MSG_SREQ_GETFLAGS,      MSG_SREQ_SETFLAGS,
-       MSG_SREQ_GETRECT,       MSG_SREQ_SETRECT,
+       MSG_SREQ_REGISTER,      // bool (char[] Name) - Registers this PID with the Window Manager
+       
+       MSG_SREQ_ADDTAB,        // ELEMENT (char[] Name) - Adds a tab to the window
+       MSG_SREQ_DELTAB,        // void (TAB Tab)       - Closes a tab
+       
+       MSG_SREQ_NEWDIALOG,     // ELEMENT (ELEMENT Parent, char[] Name)        - Creates a dialog
+       MSG_SREQ_DELDIALOG,     // void (ELEMENT Dialog)        - Closes a dialog
+       
+       MSG_SREQ_SETNAME,       // void (ELEMENT Element, char[] Name)
+       MSG_SREQ_GETNAME,       // char[] (ELEMENT Element)
+       
+       // - Builtin Elements
+       MSG_SREQ_INSERT,        // void (ELEMENT Parent, eAxWin_Controls Type, u32 Flags)
+       
        // - Drawing
+       //  All drawing functions take an ELEMENT as their first parameter.
+       //  This must be either a Tab, Dialog or Canvas control
        MSG_SREQ_SETCOL,
        MSG_SREQ_PSET,
        MSG_SREQ_LINE,  MSG_SREQ_CURVE,
@@ -30,9 +43,7 @@ enum eAxWin_Messages
        MSG_SREQ_SETFONT,       MSG_SREQ_PUTTEXT,
        
        // Server Responses
-       MSG_SRSP_PONG,
-       MSG_SRSP_WINDOW,        // Returns the new window ID
-       MSG_SRSP_IMG,   // Returns the image ID
+       MSG_SRSP_RETURN,        // {int RequestID, void[] Return Value} - Returns a value from a server request
        
        NUM_MSG
 };

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