ecere,ecereCOM: support Emscriptem platform. add new Emscripten interface driver.
authorRejean Loyer <redj@ecere.com>
Wed, 9 Dec 2015 22:31:28 +0000 (17:31 -0500)
committerJerome St-Louis <jerome@ecere.com>
Thu, 28 Jul 2016 22:22:37 +0000 (18:22 -0400)
 - <NOTE> had to move GetDisplayDriver and GetDisplaySystem to end of Display.ec file due to compiler issue
 - #if !defined(__EMSCRIPTEN__) out:
    - dynamic loading
    - thread/mutex/semaphore and Condition class
    - file monitoring
    - png/jpeg/gif
    - X driver
    - NCurses driver
    - dcom
 - add emscripten_main_loop_callback in GuiApplication.ec
 - use of glfw and a bit of tweaking in the OpenGL driver

34 files changed:
ecere/ecere.epj
ecere/ecereCOM.epj
ecere/src/com/String.ec
ecere/src/com/containers/Array.ec
ecere/src/com/containers/Map.ec
ecere/src/com/instance.c
ecere/src/com/instance.ec
ecere/src/gfx/Display.ec
ecere/src/gfx/DisplaySystem.ec
ecere/src/gfx/bitmaps/GIFFormat.ec
ecere/src/gfx/bitmaps/PNGFormat.ec
ecere/src/gfx/drivers/NCursesDisplayDriver.ec
ecere/src/gfx/drivers/XDisplayDriver.ec
ecere/src/gfx/fontRendering.ec
ecere/src/gui/Desktop3D.ec
ecere/src/gui/GuiApplication.ec
ecere/src/gui/Window.ec
ecere/src/gui/drivers/EmscriptenInterface.ec [new file with mode: 0644]
ecere/src/gui/drivers/NCursesInterface.ec
ecere/src/gui/drivers/XInterface.ec
ecere/src/gui/skins/WindowsSkin.ec
ecere/src/net/dcom.ec
ecere/src/sys/Condition.ec
ecere/src/sys/EARArchive.ec
ecere/src/sys/FileMonitor.ec
ecere/src/sys/GlobalAppSettings.ec
ecere/src/sys/JSON.ec
ecere/src/sys/Mutex.ec
ecere/src/sys/Semaphore.ec
ecere/src/sys/System.ec
ecere/src/sys/Thread.ec
ecere/src/sys/i18n.ec
samples/guiAndGfx/HelloForm/helloForm.ec
samples/guiAndGfx/HelloForm/helloForm.epj

index c4b175c..8a3dbea 100644 (file)
@@ -480,6 +480,18 @@ if distributed with the Ecere SDK Windows installer.
             ],
             "FastMath" : true
          }
+      },
+      {
+         "Name" : "Emscripten",
+         "Options" : {
+            "Debug" : true,
+            "PreprocessorDefinitions" : [
+               "ECERE_STATIC",
+               "NOBLENDING"
+            ],
+            "TargetType" : "StaticLibrary",
+            "TargetFileName" : "ecereStatic"
+         }
       }
    ],
    "Files" : [
@@ -740,6 +752,12 @@ if distributed with the Ecere SDK Windows installer.
                                  "Options" : {
                                     "ExcludeFromBuild" : true
                                  }
+                              },
+                              {
+                                 "Name" : "Emscripten",
+                                 "Options" : {
+                                    "ExcludeFromBuild" : true
+                                 }
                               }
                            ]
                         },
@@ -762,6 +780,12 @@ if distributed with the Ecere SDK Windows installer.
                                        }
                                     }
                                  ]
+                              },
+                              {
+                                 "Name" : "Emscripten",
+                                 "Options" : {
+                                    "ExcludeFromBuild" : true
+                                 }
                               }
                            ]
                         },
@@ -776,7 +800,17 @@ if distributed with the Ecere SDK Windows installer.
                               }
                            ]
                         },
-                        "PNGFormat.ec",
+                        {
+                           "FileName" : "PNGFormat.ec",
+                           "Configurations" : [
+                              {
+                                 "Name" : "Emscripten",
+                                 "Options" : {
+                                    "ExcludeFromBuild" : true
+                                 }
+                              }
+                           ]
+                        },
                         {
                            "FileName" : "RGBFormat.ec",
                            "Configurations" : [
@@ -802,6 +836,12 @@ if distributed with the Ecere SDK Windows installer.
                                        }
                                     }
                                  ]
+                              },
+                              {
+                                 "Name" : "Emscripten",
+                                 "Options" : {
+                                    "ExcludeFromBuild" : true
+                                 }
                               }
                            ]
                         }
@@ -2223,6 +2263,17 @@ if distributed with the Ecere SDK Windows installer.
                                  }
                               }
                            ]
+                        },
+                        {
+                           "FileName" : "EmscriptenInterface.ec",
+                           "Configurations" : [
+                              {
+                                 "Name" : "Emscripten",
+                                 "Options" : {
+                                    "ExcludeFromBuild" : false
+                                 }
+                              }
+                           ]
                         }
                      ],
                      "Options" : {
@@ -2418,6 +2469,12 @@ if distributed with the Ecere SDK Windows installer.
                            }
                         }
                      ]
+                  },
+                  {
+                     "Name" : "Emscripten",
+                     "Options" : {
+                        "ExcludeFromBuild" : true
+                     }
                   }
                ]
             },
index 1e6bf37..46aea46 100644 (file)
             ],
             "TargetType" : "StaticLibrary",
             "TargetFileName" : "ecereCOMStatic",
-            "TargetDirectory" : "ecereCOMStatic",
             "ObjectsDirectory" : "ecereCOMStatic",
             "Libraries" : [
 
             ],
             "FastMath" : true
          }
+      },
+      {
+         "Name" : "Emscripten",
+         "Options" : {
+            "Optimization" : "Size",
+            "PreprocessorDefinitions" : [
+               "ECERE_STATIC",
+               "ECERE_COM_ONLY"
+            ],
+            "TargetType" : "StaticLibrary",
+            "TargetFileName" : "ecereCOMStatic"
+         }
       }
    ],
    "Files" : [
index 2cf8487..0f1c6fe 100644 (file)
@@ -10,7 +10,7 @@ default:
 #include <stdlib.h>
 #include <stdarg.h>
 #if !defined(ECERE_BOOTSTRAP) // quick fix for now
-#if defined(__WIN32__)
+#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
 #define WIN32_LEAN_AND_MEAN
 #define String _String
 #include <windows.h>
index 705b541..b27c325 100644 (file)
@@ -1,5 +1,6 @@
 namespace com;
 
+import "instance"
 import "Container"
 
 #ifdef _DEBUG
index 3cd9bf4..57c6400 100644 (file)
@@ -1,6 +1,8 @@
 namespace com;
 
+#if !defined(_DEBUG) || defined(MEMINFO)
 import "instance"  // TOFIX: This is required to build Debug on Ubuntu 10.04, GCC 4.4.3
+#endif
 import "CustomAVLTree"
 
 default:
index df9f68b..1d63806 100644 (file)
@@ -24,7 +24,7 @@
 #undef bool
 #endif
 
-#if defined(__WIN32__)
+#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
 #define WIN32_LEAN_AND_MEAN
 #define UNICODE
 #include <windows.h>
@@ -54,14 +54,14 @@ typedef unsigned long long uint64;
 __declspec(dllexport) int isblank(int c) { return c == '\t' || c == ' '; }
 #endif
 
-#if defined(__WIN32__)
+#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
 intptr_t stdinHandle, stdoutHandle;
 int osfStdin, osfStdout;
 FILE * fStdIn, * fStdOut;
 #endif
 
 FILE *eC_stdin(void)  {
-#if defined(__WIN32__)
+#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
    if(!fStdIn)
    {
       stdinHandle = (intptr_t)GetStdHandle(STD_INPUT_HANDLE);
@@ -137,7 +137,7 @@ extern struct __ecereNameSpace__ecere__com__Instance * __thisModule;
 
 typedef enum { unknown, win32, tux, apple } Platform;
 
-#if defined(__WIN32__)
+#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
 Platform runtimePlatform = win32;
 #elif defined(__APPLE__)
 Platform runtimePlatform = apple;
@@ -190,7 +190,7 @@ static bool DualPipe_GetLine(FILE * p, char *s, int max)
 
 bool Instance_LocateModule(const char * name, char * fileName)
 {
-#if defined(__WIN32__)
+#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
    HMODULE hModule = null;
    if(name && name[0])
    {
@@ -248,7 +248,7 @@ bool Instance_LocateModule(const char * name, char * fileName)
    }
 #elif defined(__unix__)
    //File f = FileOpen("/proc/self/maps", read);
-   FILE * f;
+   FILE * f = null;
    char exeName[MAX_FILENAME];
    exeName[0] = 0;
 #if defined(__linux__)
@@ -325,7 +325,7 @@ bool Instance_LocateModule(const char * name, char * fileName)
       }
       fclose(f);
    }
-#if !defined(ECERE_NOFILE) && !defined(__linux__)
+#if !defined(ECERE_NOFILE) && !defined(__linux__) && !defined(__EMSCRIPTEN__)
    if(name && name[0])
    {
       // Couldn't locate libraries with /proc/curmap/map, attempt with ldd
@@ -404,11 +404,11 @@ bool Instance_LocateModule(const char * name, char * fileName)
 
 void Instance_COM_Initialize(int argc, char ** argv, char ** parsedCommand, int * argcPtr, const char *** argvPtr)
 {
-#if !defined(__WIN32__) && !defined(ECERE_BOOTSTRAP)
+#if !defined(__WIN32__) && !defined(__EMSCRIPTEN__) && !defined(ECERE_BOOTSTRAP)
    // Disable stdout buffering on Unix
    setvbuf(stdout, null, _IONBF, 0);
 #endif
-#if defined(__WIN32__)
+#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
    *parsedCommand = UTF16toUTF8(GetCommandLineW());
    *argvPtr = eSystem_New0(sizeof(char *) * 512);
    *argcPtr = Tokenize(*parsedCommand, 512,(void*)(char **)(*argvPtr), forArgsPassing);
@@ -454,7 +454,7 @@ void * Instance_Module_Load(const char * libLocation, const char * name, void **
    *Load = null;
    *Unload = null;
 
-#if defined(__WIN32__)
+#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
    strcpy(fileName, name);
    GetExtension(fileName, extension);
    if(!extension[0])
@@ -491,7 +491,9 @@ void * Instance_Module_Load(const char * libLocation, const char * name, void **
       strcat(fileName, ".so");
 #endif
 
+#if !defined(__EMSCRIPTEN__)
    library = dlopen(fileName, RTLD_LAZY);
+#endif
    while(!library && attempts < sizeof(paths)/sizeof(paths[0]))
    {
       if(paths[attempts])
@@ -514,15 +516,19 @@ void * Instance_Module_Load(const char * libLocation, const char * name, void **
 #else
          strcat(fileName, ".so");
 #endif
+#if !defined(__EMSCRIPTEN__)
       library = dlopen(fileName, RTLD_LAZY);
+#endif
    }
 
    if(library)
    {
       *Load = dlsym(library, "__ecereDll_Load");
       *Unload = dlsym(library, "__ecereDll_Unload");
+#if !defined(__EMSCRIPTEN__)
       if(!*Load)
          dlclose(library);
+#endif
    }
 #elif defined(__APPLE__)
    if(libLocation || strchr(name, '/'))
@@ -565,10 +571,10 @@ void * Instance_Module_Load(const char * libLocation, const char * name, void **
 
 void Instance_Module_Free(void * library)
 {
-#if defined(__WIN32__)
+#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
    if(library)
       FreeLibrary(library);
-#elif defined(__unix__) || defined(__APPLE__)
+#elif (defined(__unix__) || defined(__APPLE__)) && !defined(__EMSCRIPTEN__)
    if(library)
       dlclose(library);
 #endif
index f1d80a3..c3627b0 100644 (file)
@@ -20,9 +20,11 @@ import "dataTypes"
 
 #undef __BLOCKS__
 
+#if !defined(__EMSCRIPTEN__)
 #if !defined(ECERE_BOOTSTRAP)
 import "Mutex"
 #endif
+#endif
 
 // #define MEMINFO
 /*
@@ -43,7 +45,9 @@ import "Mutex"
 #endif
 
 #ifdef MEMINFO
+#if !defined(__EMSCRIPTEN__)
 import "Thread"
+#endif
 static define MAX_MEMORY_LOC = 40;
 static define MAX_STACK_FRAMES = 1000;
 
@@ -190,7 +194,9 @@ public dllexport void MemoryGuard_PushLoc(const char * loc)
 {
 #ifdef MEMINFO
    MemStack stack;
+#if !defined(__EMSCRIPTEN__)
    memMutex.Wait();
+#endif
    stack = (MemStack)memStacks.Find(GetCurrentThreadID());
    if(!stack)
    {
@@ -200,22 +206,28 @@ public dllexport void MemoryGuard_PushLoc(const char * loc)
    }
    if(stack.pos < MAX_STACK_FRAMES)
       stack.frames[stack.pos++] = loc;
+#if !defined(__EMSCRIPTEN__)
    memMutex.Release();
 #endif
+#endif
 }
 
 public dllexport void MemoryGuard_PopLoc()
 {
 #ifdef MEMINFO
    MemStack stack;
+#if !defined(__EMSCRIPTEN__)
    memMutex.Wait();
+#endif
    stack = (MemStack)memStacks.Find(GetCurrentThreadID());
    if(stack && stack.pos > 0)
    {
       stack.pos--;
    }
+#if !defined(__EMSCRIPTEN__)
    memMutex.Release();
 #endif
+#endif
 }
 
 #ifdef ECERE_STATIC
@@ -714,9 +726,11 @@ static uint TOTAL_MEM = 0;
 static uint OUTSIDE_MEM = 0;
 #endif
 
+#if !defined(__EMSCRIPTEN__)
 #if !defined(ECERE_BOOTSTRAP)
 static Mutex memMutex { };
 #endif
+#endif
 
 private class MemBlock : struct
 {
@@ -5936,7 +5950,7 @@ static int64 GetEnumSize(Class _class)
 #define strnicmp strncasecmp
 #endif
 
-#if defined(ECERE_BOOTSTRAP) || (defined(__GNUC__) && !defined(__DJGPP__) && !defined(__WIN32__))
+#if defined(ECERE_BOOTSTRAP) || (defined(__GNUC__) && !defined(__DJGPP__) && !defined(__WIN32__) && !defined(__EMSCRIPTEN__))
 #undef strlwr
 #undef strupr
 default dllexport char * strlwr(char *string)
index b90c597..7b0e991 100644 (file)
@@ -84,7 +84,9 @@ public class FontFlags
 
 __attribute__((unused)) static void DummyFunction()
 {
+#if !defined(__EMSCRIPTEN__)
    Mutex { };
+#endif
 }
 
 public class DisplayDriver
@@ -215,27 +217,6 @@ public:
 public enum Alignment { left, right, center };
 public enum ClearType { colorBuffer, depthBuffer, colorAndDepth };
 
-subclass(DisplayDriver) GetDisplayDriver(const char * driverName)
-{
-   if(driverName)
-   {
-      OldLink link;
-      for(link = class(DisplayDriver).derivatives.first; link; link = link.next)
-      {
-         subclass(DisplayDriver) displayDriver = link.data;
-         if(displayDriver && displayDriver.name && !strcmp(displayDriver.name, driverName))
-            return displayDriver;
-      }
-   }
-   return null;
-}
-
-DisplaySystem GetDisplaySystem(const char * driverName)
-{
-   subclass(DisplayDriver) displayDriver = GetDisplayDriver(driverName);
-   return displayDriver ? displayDriver.displaySystem : null;
-}
-
 define textCellW = 8;
 define textCellH = 16;
 
@@ -592,7 +573,9 @@ public:
       result = displaySystem && displaySystem.Lock();
       if(result && render)
       {
+#if !defined(__EMSCRIPTEN__)
          mutex.Wait();
+#endif
 
          if(!current)
             result = displaySystem.driver.Lock(this);
@@ -618,7 +601,9 @@ public:
          */
          if(!current && displaySystem)
             displaySystem.driver.Unlock(this);
+#if !defined(__EMSCRIPTEN__)
          mutex.Release();
+#endif
       }
       if(displaySystem)
          displaySystem.Unlock();
@@ -1331,7 +1316,9 @@ private:
    DisplaySystem displaySystem;
    void * window;
 
+#if !defined(__EMSCRIPTEN__)
    Mutex mutex { };
+#endif
    int current;
 
 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
@@ -2115,3 +2102,25 @@ public int BestColorMatch(ColorAlpha * palette, int start, int end, Color rgb)
    }
    return best;
 }
+
+// had to move this here due to compiler ordering issue for "get property" symbol
+subclass(DisplayDriver) GetDisplayDriver(const char * driverName)
+{
+   if(driverName)
+   {
+      OldLink link;
+      for(link = class(DisplayDriver).derivatives.first; link; link = link.next)
+      {
+         subclass(DisplayDriver) displayDriver = link.data;
+         if(displayDriver && displayDriver.name && !strcmp(displayDriver.name, driverName))
+            return displayDriver;
+      }
+   }
+   return null;
+}
+
+DisplaySystem GetDisplaySystem(const char * driverName)
+{
+   subclass(DisplayDriver) displayDriver = GetDisplayDriver(driverName);
+   return displayDriver ? displayDriver.displaySystem : null;
+}
index 2456012..114e3dc 100644 (file)
@@ -1,6 +1,8 @@
 namespace gfx;
 
+#if !defined(__EMSCRIPTEN__)
 import "Mutex"
+#endif
 import "Display"
 
 const String printingDocumentName;
@@ -188,7 +190,9 @@ public:
    bool Lock()
    {
       bool result = false;
+#if !defined(__EMSCRIPTEN__)
       mutex.Wait();
+#endif
 
       if(!current)
          result = driver.LockSystem(this);
@@ -204,7 +208,9 @@ public:
       if(!current)
          driver.UnlockSystem(this);
 
+#if !defined(__EMSCRIPTEN__)
       mutex.Release();
+#endif
    }
 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
    // --- Materials List Management ---
@@ -350,5 +356,7 @@ private:
 
    void * driverData;
    int current;
+#if !defined(__EMSCRIPTEN__)
    Mutex mutex { };
+#endif
 };
index 9d81af9..681692d 100644 (file)
@@ -1,9 +1,11 @@
 namespace gfx::bitmaps;
 
-#include "gif_lib.h"
-
 import "Display"
 
+#if !defined(__EMSCRIPTEN__)
+
+#include "gif_lib.h"
+
 static int ReadData(GifFileType * gifFile, GifByteType * bytes, int size)
 {
    File f = gifFile->UserData;
@@ -129,3 +131,5 @@ class GIFFormat : BitmapFormat
       return result;
    }
 }
+
+#endif // !defined(__EMSCRIPTEN__)
index 22de51a..95e596e 100644 (file)
@@ -2,6 +2,8 @@ namespace gfx::bitmaps;
 
 import "Display"
 
+#if !defined(__EMSCRIPTEN__)
+
 #define uint _uint
 #include "png.h"
 #undef uint
@@ -307,3 +309,5 @@ class PNGFormat : BitmapFormat
       return result;
    }
 }
+
+#endif // !defined(__EMSCRIPTEN__)
index 6051b6b..2dcc45f 100644 (file)
@@ -4,7 +4,7 @@ import "instance"
 
 #undef __BLOCKS__
 
-#if (defined(__unix__) || defined(__APPLE__)) && !defined(__DOS__)
+#if (defined(__unix__) || defined(__APPLE__)) && !defined(__DOS__) && !defined(__EMSCRIPTEN__)
 
 #include <curses.h>
 
index b18503c..1ec9a01 100644 (file)
@@ -5,7 +5,7 @@ namespace gfx::drivers;
 
 import "instance"
 
-#if (defined(__unix__) || defined(__APPLE__)) && !defined(ECERE_MINIGLX)
+#if (defined(__unix__) || defined(__APPLE__)) && !defined(ECERE_MINIGLX) && !defined(__EMSCRIPTEN__)
 
 default:
 
@@ -25,8 +25,10 @@ default:
 
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
+#if !defined(__EMSCRIPTEN__)
 #include <X11/extensions/shape.h>
 #include <X11/extensions/Xrender.h>
+#endif
 #include <X11/extensions/XShm.h>
 #include <sys/ipc.h>
 #include <sys/shm.h>
index 29d6340..64399ce 100644 (file)
@@ -6,6 +6,8 @@ import "fontManagement"
 #define ECERE_NOTRUETYPE
 #endif
 
+#define _Noreturn
+
 #undef __BLOCKS__
 #define uint _uint
 #define strlen _strlen
index d9e273e..45085a8 100644 (file)
@@ -54,7 +54,9 @@ static bool Window3D_Setup(Window window, bool positionChildren)
          window.display.driverData = virtualDesktop.display.driverData;
          window.display.current = virtualDesktop.display.current;
 
+#if !defined(__EMSCRIPTEN__)
          window.display.mutex = null;
+#endif
          window.ComputeAnchors(window.stateAnchor, window.stateSizeAnchor, &x,&y,&w,&h);
          virtualDesktop.display.Lock(false);
          window.windowHandle = Setup3DWindow(window, w, h);
index 87fe462..bb7fd95 100644 (file)
@@ -1,6 +1,14 @@
 namespace gui;
 
-#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__)
+#ifdef __EMSCRIPTEN__
+#include <emscripten.h>
+#endif
+
+#ifdef __EMSCRIPTEN__
+#include <emscripten.h>
+#endif
+
+#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
 #define property _property
 #define new _new
 #define class _class
@@ -77,7 +85,7 @@ import "network"
 import "CocoaInterface"
 #endif
 
-#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__)
+#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
 import "XInterface"
 #endif
 
@@ -160,9 +168,13 @@ public class GuiApplication : Application
 
    bool processAll;
 
+#if !defined(__EMSCRIPTEN__)
    Mutex waitMutex {};
+#endif
    bool waiting;
+#if !defined(__EMSCRIPTEN__)
    Mutex lockMutex {};
+#endif
 
    Window interimWindow;
    bool caretEnabled;
@@ -179,7 +191,9 @@ public class GuiApplication : Application
    {
       SystemCursor c;
 
+#if !defined(__EMSCRIPTEN__)
       mainThread = GetCurrentThreadID();
+#endif
       if(!guiApp)
          guiApp = this;
 
@@ -194,9 +208,11 @@ public class GuiApplication : Application
       for(c = 0; c<SystemCursor::enumSize; c++)
          systemCursors[c] = Cursor { systemCursor = c; };
 
+#if !defined(__EMSCRIPTEN__)
       globalSystem.eventSemaphore = Semaphore { };
       globalSystem.fileMonitorMutex = Mutex { };
       globalSystem.fileMonitors.offset = (uint)(uintptr)&((FileMonitor)0).prev;
+#endif
       return true;
    }
 
@@ -209,12 +225,12 @@ public class GuiApplication : Application
       delete desktop;
       customCursors.Clear();
 
-#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__)
+#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
       if(xGlobalDisplay)
          XUnlockDisplay(xGlobalDisplay);
 #endif
 
-#if !defined(__ANDROID__)
+#if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
       // Because destruction of app won't be from main thread
       if(guiApplicationInitialized)
          lockMutex.Release();
@@ -238,9 +254,11 @@ public class GuiApplication : Application
       Network_Terminate();
 #endif
 
+#if !defined(__EMSCRIPTEN__)
       delete globalSystem.eventSemaphore;
       delete globalSystem.fileMonitorMutex;
       delete globalSystem.fileMonitorThread;
+#endif
 
       UnapplySkin(class(Window));
 
@@ -552,7 +570,9 @@ public class GuiApplication : Application
 
          errorLevel = 2;
 
+#if !defined(__EMSCRIPTEN__)
          lockMutex.Wait();
+#endif
 /*#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__)
          if(xGlobalDisplay)
             XLockDisplay(xGlobalDisplay);
@@ -572,7 +592,9 @@ public class GuiApplication : Application
             desktop.caption = appName;
             *&desktop.visible = true;
             desktop.position = Point { };
+#if !defined(__EMSCRIPTEN__)
             desktop.mutex = Mutex { };
+#endif
             desktop.created = true;
          }
 
@@ -599,6 +621,13 @@ public class GuiApplication : Application
             else
                defaultDriver = "OpenGL";
          }
+   #elif defined(__EMSCRIPTEN__)
+         {
+            if(driver)
+               defaultDriver = driver;
+            else
+               defaultDriver = "OpenGL";
+         }
    #else
          if((this.isGUIApp & 1) && !textMode)
          {
@@ -677,6 +706,10 @@ public:
             }
          }
 
+#ifdef __EMSCRIPTEN__
+      emscripten_set_main_loop(emscripten_main_loop_callback, 1/*60*/, 1);
+#endif
+
          if(desktop)
          {
             int terminated = 0;
@@ -703,16 +736,22 @@ public:
                      break;
                if(!child) break;
 
+#if !defined(__EMSCRIPTEN__)
                for(window = desktop.children.first; window; window = window.next)
                   if(window.mutex) window.mutex.Wait();
+#endif
                UpdateDisplay();
+#if !defined(__EMSCRIPTEN__)
                for(window = desktop.children.first; window; window = window.next)
                   if(window.mutex) window.mutex.Release();
+#endif
                wait = !ProcessInput(true);
+#if !defined(__EMSCRIPTEN__)
 #ifdef _DEBUG
                if(lockMutex.owningThread != GetCurrentThreadID())
                   PrintLn("WARNING: ProcessInput returned unlocked GUI!");
 #endif
+#endif
                if(!Cycle(wait))
                   wait = false;
 
@@ -720,15 +759,17 @@ public:
                   Wait();
                else
                {
-#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__)
+#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
                   if(xGlobalDisplay)
                      XUnlockDisplay(xGlobalDisplay);
 #endif
 
+#if !defined(__EMSCRIPTEN__)
                   lockMutex.Release();
                   lockMutex.Wait();
+#endif
 
-#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__)
+#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
                   if(xGlobalDisplay)
                      XLockDisplay(xGlobalDisplay);
 #endif
@@ -747,23 +788,27 @@ public:
 
    void Wait(void)
    {
-#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__)
+#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
       if(xGlobalDisplay)
          XUnlockDisplay(xGlobalDisplay);
 #endif
 
+#if !defined(__EMSCRIPTEN__)
       lockMutex.Release();
 
       waitMutex.Wait();
+#endif
       waiting = true;
       if(interfaceDriver)
          interfaceDriver.Wait();
       waiting = false;
+#if !defined(__EMSCRIPTEN__)
       waitMutex.Release();
 
       lockMutex.Wait();
+#endif
 
-#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__)
+#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
       if(xGlobalDisplay)
          XLockDisplay(xGlobalDisplay);
 #endif
@@ -814,7 +859,9 @@ public:
       {
          if(fullScreenMode && desktop.display)
          {
+#if !defined(__EMSCRIPTEN__)
             desktop.mutex.Wait();
+#endif
             if(desktop.active)
             {
                desktop.display.Lock(true);
@@ -836,7 +883,9 @@ public:
 
                desktop.display.Unlock();
             }
+#if !defined(__EMSCRIPTEN__)
             desktop.mutex.Release();
+#endif
          }
          else
          {
@@ -844,7 +893,9 @@ public:
 
             for(window = desktop.children.first; window; window = window.next)
             {
+#if !defined(__EMSCRIPTEN__)
                if(window.mutex) window.mutex.Wait();
+#endif
                if(window.visible && window.dirty)
                {
                   // Logf("Updating %s\n", window.name);
@@ -867,7 +918,9 @@ public:
                   usleep(1000000);
                   */
                }
+#if !defined(__EMSCRIPTEN__)
                if(window.mutex) window.mutex.Release();
+#endif
             }
          }
       }
@@ -875,7 +928,9 @@ public:
 
    void WaitEvent(void)
    {
+#if !defined(__EMSCRIPTEN__)
       globalSystem.eventSemaphore.Wait();
+#endif
    }
 
 #if !defined(ECERE_VANILLA) && !defined(ECERE_NONET)
@@ -1090,7 +1145,9 @@ public:
 
    void SignalEvent(void)
    {
+#if !defined(__EMSCRIPTEN__)
       globalSystem.eventSemaphore.Release();
+#endif
    }
 
    // TODO: Might want to make this private with simpler public version?
@@ -1282,6 +1339,7 @@ public:
 
    bool ProcessFileNotifications()
    {
+#if !defined(__EMSCRIPTEN__)
       bool activity = false;
       FileMonitor monitor, next;
       static int reentrant = 0;
@@ -1347,24 +1405,31 @@ public:
       // printf("[%d] Releasing in ProcessFileNotifications fileMonitor Mutex %x...\n", (int)GetCurrentThreadID(), globalSystem.fileMonitorMutex);
       globalSystem.fileMonitorMutex.Release();
       return activity;
+#else
+      return false;
+#endif
    }
 
    void Lock(void)
    {
+#if !defined(__EMSCRIPTEN__)
       lockMutex.Wait();
-#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__)
+#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
       if(xGlobalDisplay)
          XLockDisplay(xGlobalDisplay);
 #endif
+#endif
    }
 
    void Unlock(void)
    {
-#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__)
+#if !defined(__EMSCRIPTEN__)
+#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
       if(xGlobalDisplay)
          XUnlockDisplay(xGlobalDisplay);
 #endif
       lockMutex.Release();
+#endif
    }
 
    Cursor GetCursor(SystemCursor cursor)
@@ -1395,7 +1460,9 @@ public:
          return (const char *)(this ? appName : null);
       }
    };
+#if !defined(__EMSCRIPTEN__)
    property Semaphore semaphore { get { return globalSystem.eventSemaphore; } };
+#endif
    property bool alwaysEmptyInput{ set { processAll = value; } get { return processAll; } };
    property bool fullScreen
    {
@@ -1463,3 +1530,12 @@ public:
       set { timerResolution = value; if(interfaceDriver) interfaceDriver.SetTimerResolution(value); }
    };
 };
+
+#ifdef __EMSCRIPTEN__
+private void emscripten_main_loop_callback()
+{
+   guiApp.ProcessInput(false);
+   guiApp.Cycle(false);
+   guiApp.UpdateDisplay();
+}
+#endif
index 5ec7889..c7b3927 100644 (file)
@@ -581,6 +581,7 @@ private:
       OldLink slave;
       ResPtr ptr;
 
+#if !defined(__EMSCRIPTEN__)
       if(fileMonitor)
       {
          int i, lockCount = guiApp.lockMutex.lockCount;
@@ -590,6 +591,7 @@ private:
          for(i = 0; i < lockCount; i++)
             guiApp.lockMutex.Wait();
       }
+#endif
 
       if(parent)
       {
@@ -674,7 +676,9 @@ private:
       delete statusBar;
 
       OnDestroyed();
+#if !defined(__EMSCRIPTEN__)
       delete mutex;
+#endif
       delete icon;
 
       if(((subclass(Window))_class).pureVTbl)
@@ -1881,7 +1885,9 @@ private:
                   child.display.width = display.width;
                   child.display.height = display.height;
                   child.display.driverData = display.driverData;
+#if !defined(__EMSCRIPTEN__)
                   child.display.mutex = null;
+#endif
                }
             }
          }
@@ -6055,7 +6061,9 @@ private:
       {
          if(guiApp.fullScreenMode && guiApp.desktop.display)
          {
+#if !defined(__EMSCRIPTEN__)
             guiApp.desktop.mutex.Wait();
+#endif
             guiApp.desktop.display.Lock(true);
 
             Update(extent);
@@ -6079,12 +6087,16 @@ private:
             }
 
             guiApp.desktop.display.Unlock();
+#if !defined(__EMSCRIPTEN__)
             guiApp.desktop.mutex.Release();
+#endif
          }
          else
          {
             Window rootWindow = this.rootWindow;
+#if !defined(__EMSCRIPTEN__)
             rootWindow.mutex.Wait();
+#endif
             display.Lock(true);
 
             Update(extent);
@@ -6092,7 +6104,9 @@ private:
                guiApp.SignalEvent();
             else
             {
+#if !defined(__EMSCRIPTEN__)
                guiApp.waitMutex.Wait();
+#endif
                guiApp.interfaceDriver.Lock(rootWindow);
                if(!rootWindow.style.hidden && rootWindow.dirty)
                {
@@ -6104,10 +6118,14 @@ private:
                   rootWindow.dirty = false;
                }
                guiApp.interfaceDriver.Unlock(rootWindow);
+#if !defined(__EMSCRIPTEN__)
                guiApp.waitMutex.Release();
+#endif
             }
             display.Unlock();
+#if !defined(__EMSCRIPTEN__)
             rootWindow.mutex.Release();
+#endif
          }
       }
    }
@@ -6240,6 +6258,7 @@ private:
 
    void SetupFileMonitor()
    {
+#if !defined(__EMSCRIPTEN__)
       if(!fileMonitor)
       {
          fileMonitor = FileMonitor
@@ -6258,6 +6277,7 @@ private:
          };
          incref fileMonitor;
       }
+#endif
    }
 
 public:
@@ -6308,8 +6328,10 @@ public:
                }
          }
 
+#if !defined(__EMSCRIPTEN__)
          if(parent == guiApp.desktop && !mutex)
             mutex = Mutex {};
+#endif
 
          if(style.isDocument)
          {
@@ -7539,7 +7561,9 @@ public:
       SetupFileMonitor();
       if(fileName)
       {
+#if !defined(__EMSCRIPTEN__)
          fileMonitor.fileName = null;
+#endif
          saving = true;
 
          if(OnSaveFile(fileName))
@@ -7547,7 +7571,9 @@ public:
             //if(OnFileModified != Window::OnFileModified)
             {
                saving = false;
+#if !defined(__EMSCRIPTEN__)
                fileMonitor.fileName = fileName;
+#endif
             }
             return true;
          }
@@ -7582,7 +7608,9 @@ public:
             sprintf(filePath, "Untitled %d", documentID);
             fileDialog.filePath = filePath;
          }
+#if !defined(__EMSCRIPTEN__)
          fileMonitor.fileName = null;
+#endif
 
          fileDialog.type = save;
          fileDialog.text = $"Save As";
@@ -7619,11 +7647,13 @@ public:
                break;
             }
          }
+#if !defined(__EMSCRIPTEN__)
          //if(OnFileModified != Window::OnFileModified && fileName)
          {
             if(fileName)
                fileMonitor.fileName = fileName;
          }
+#endif
          delete fileDialog;
       }
       return (bool)result; // Actually returning result from Yes/NoCancel message box
@@ -9453,8 +9483,10 @@ public:
             UpdateCaption();
 
          // if(style.isDocument)
+#if !defined(__EMSCRIPTEN__)
          if(!saving)
             fileMonitor.fileName = value;
+#endif
       }
       get { return fileName; }
    };
@@ -9796,10 +9828,14 @@ private:
    int numIcons;
    int positionID;
 
+#if !defined(__EMSCRIPTEN__)
    Mutex mutex;
+#endif
    WindowState lastState;
 
+#if !defined(__EMSCRIPTEN__)
    FileMonitor fileMonitor;
+#endif
 
    FontResource setFont, systemFont;
    FontResource usedFont;
diff --git a/ecere/src/gui/drivers/EmscriptenInterface.ec b/ecere/src/gui/drivers/EmscriptenInterface.ec
new file mode 100644 (file)
index 0000000..9df8751
--- /dev/null
@@ -0,0 +1,287 @@
+namespace gui::drivers;
+
+#ifdef BUILDING_ECERE_COM
+import "Window"
+import "Interface"
+#else
+#ifdef ECERE_STATIC
+public import static "ecere"
+#else
+public import "ecere"
+#endif
+#endif
+
+#ifdef __EMSCRIPTEN__
+
+#include <stdio.h>
+
+// source file line number printf (sflnprintf)
+#define sflnprintf(format,...) printf("%s:% 5d: " format, __FILE__, __LINE__, ##__VA_ARGS__)
+
+#define property _property
+#define uint _uint
+
+//#include <GLES2/gl2.h>
+#include <GL/glfw.h>
+#include <emscripten/emscripten.h>
+
+#undef property
+#undef uint
+
+
+class EmscriptenInterface : Interface
+{
+   class_property(name) = "Emscripten";
+
+
+   // --- User Interface System ---
+
+   bool ::Initialize()
+   {
+      sflnprintf("class(EmscriptenInterface) ::Initialize [STUB!]\n");
+      guiApp.desktop.ExternalPosition(0,0, 640, 480);
+      return true;
+   }
+
+   void ::Terminate()
+   {
+      sflnprintf("class(EmscriptenInterface) ::Terminate [STUB!]\n");
+   }
+
+   bool ::ProcessInput(bool processAll)
+   {
+      sflnprintf("class(EmscriptenInterface) ::ProcessInput [STUB!]\n");
+      return false;
+   }
+
+   void ::Wait()
+   {
+      sflnprintf("class(EmscriptenInterface) ::Wait [STUB!]\n");
+   }
+
+   void ::Lock(Window window)
+   {
+      sflnprintf("class(EmscriptenInterface) ::Lock [STUB!]\n");
+   }
+
+   void ::Unlock(Window window)
+   {
+      sflnprintf("class(EmscriptenInterface) ::Unlock [STUB!]\n");
+   }
+
+   void ::SetTimerResolution(uint hertz)
+   {
+      sflnprintf("class(EmscriptenInterface) ::SetTimerResolution [STUB!] Implement high resolution timer here\n");
+   }
+
+   const char ** ::GraphicsDrivers(int * numDrivers)
+   {
+      //sflnprintf("class(EmscriptenInterface) ::GraphicsDrivers [STUB!]\n");
+      static const char *graphicsDrivers[] = { "OpenGL" };
+      *numDrivers = sizeof(graphicsDrivers) / sizeof(char *);
+      return (const char **)graphicsDrivers;
+      return null;
+   }
+
+   void ::EnsureFullScreen(bool * fullScreen)
+   {
+      sflnprintf("class(EmscriptenInterface) ::EnsureFullScreen [STUB!]\n");
+      *fullScreen = true;
+   }
+
+   void ::GetCurrentMode(bool * fullScreen, Resolution * resolution, PixelFormat * colorDepth, int * refreshRate)
+   {
+      sflnprintf("class(EmscriptenInterface) ::GetCurrentMode [STUB!]\n");
+   }
+
+   bool ::ScreenMode(bool fullScreen, Resolution resolution, PixelFormat colorDepth, int refreshRate, bool * textMode)
+   {
+      sflnprintf("class(EmscriptenInterface) ::ScreenMode [STUB!]\n");
+      return true;
+   }
+
+
+   // --- Window Creation ---
+
+   void * ::CreateRootWindow(Window window)
+   {
+      sflnprintf("class(EmscriptenInterface) ::CreateRootWindow [STUB!]\n");
+      return null;
+   }
+
+   void ::DestroyRootWindow(Window window)
+   {
+      sflnprintf("class(EmscriptenInterface) ::DestroyRootWindow [STUB!]\n");
+   }
+
+
+   // --- Window manipulation ---
+
+   void ::SetRootWindowCaption(Window window, const char * name)
+   {
+      sflnprintf("class(EmscriptenInterface) ::SetRootWindowCaption [STUB!]\n");
+   }
+
+   void ::PositionRootWindow(Window window, int x, int y, int w, int h, bool move, bool resize)
+   {
+      sflnprintf("class(EmscriptenInterface) ::Stub [STUB!]\n");
+   }
+
+   void ::OffsetWindow(Window window, int * x, int * y)
+   {
+      sflnprintf("class(EmscriptenInterface) ::OffsetWindow [STUB!]\n");
+   }
+
+   void ::UpdateRootWindow(Window window)
+   {
+      sflnprintf("class(EmscriptenInterface) ::UpdateRootWindow [STUB!]\n");
+   }
+
+   void ::SetRootWindowState(Window window, WindowState state, bool visible)
+   {
+      sflnprintf("class(EmscriptenInterface) ::SetRootWindowState [STUB!]\n");
+   }
+
+   void ::ActivateRootWindow(Window window)
+   {
+      sflnprintf("class(EmscriptenInterface) ::ActivateRootWindow [STUB!]\n");
+   }
+
+   void ::OrderRootWindow(Window window, bool topMost)
+   {
+      sflnprintf("class(EmscriptenInterface) ::OrderRootWindow [STUB!]\n");
+   }
+
+   void ::SetRootWindowColor(Window window)
+   {
+      sflnprintf("class(EmscriptenInterface) ::SetRootWindowColor [STUB!]\n");
+   }
+
+   void ::FlashRootWindow(Window window)
+   {
+      sflnprintf("class(EmscriptenInterface) ::FlashRootWindow [STUB!]\n");
+   }
+
+
+   // --- Mouse-based window movement ---
+
+   void ::StartMoving(Window window, int x, int y, bool fromKeyBoard)
+   {
+      sflnprintf("class(EmscriptenInterface) ::StartMoving [STUB!]\n");
+   }
+
+   void ::StopMoving(Window window)
+   {
+      sflnprintf("class(EmscriptenInterface) ::StopMoving [STUB!]\n");
+   }
+
+
+   // --- Mouse manipulation ---
+
+   void ::GetMousePosition(int *x, int *y)
+   {
+      sflnprintf("class(EmscriptenInterface) ::GetMousePosition [STUB!]\n");
+   }
+
+   void ::SetMousePosition(int x, int y)
+   {
+      sflnprintf("class(EmscriptenInterface) ::SetMousePosition [STUB!]\n");
+   }
+
+   void ::SetMouseRange(Window window, Box box)
+   {
+      sflnprintf("class(EmscriptenInterface) ::SetMouseRange [STUB!]\n");
+   }
+
+   void ::SetMouseCapture(Window window)
+   {
+      sflnprintf("class(EmscriptenInterface) ::SetMouseCapture [STUB!]\n");
+   }
+
+
+   // --- Mouse cursor ---
+
+   void ::SetMouseCursor(Window window, SystemCursor cursor)
+   {
+      sflnprintf("class(EmscriptenInterface) ::SetMouseCursor [STUB!]\n");
+   }
+
+
+   // --- Caret manipulation ---
+
+   void ::SetCaret(int caretX, int caretY, int size)
+   {
+      sflnprintf("class(EmscriptenInterface) ::SetCaret [STUB!]\n");
+   }
+
+
+   // --- Clipboard manipulation ---
+
+   void ::ClearClipboard()
+   {
+      sflnprintf("class(EmscriptenInterface) ::ClearClipboard [STUB!]\n");
+   }
+
+   bool ::AllocateClipboard(ClipBoard clipBoard, uint size)
+   {
+      sflnprintf("class(EmscriptenInterface) ::AllocateClipboard [STUB!]\n");
+      return false;
+   }
+
+   bool ::SaveClipboard(ClipBoard clipBoard)
+   {
+      sflnprintf("class(EmscriptenInterface) ::SaveClipboard [STUB!]\n");
+      return false;
+   }
+
+   bool ::LoadClipboard(ClipBoard clipBoard)
+   {
+      sflnprintf("class(EmscriptenInterface) ::LoadClipboard [STUB!]\n");
+      return false;
+   }
+
+   void ::UnloadClipboard(ClipBoard clipBoard)
+   {
+      sflnprintf("class(EmscriptenInterface) ::UnloadClipboard [STUB!]\n");
+   }
+
+
+   // --- State based input ---
+
+   bool ::AcquireInput(Window window, bool state)
+   {
+      sflnprintf("class(EmscriptenInterface) ::AcquireInput [STUB!]\n");
+      return false;
+   }
+
+   bool ::GetMouseState(MouseButtons * buttons, int * x, int * y)
+   {
+      sflnprintf("class(EmscriptenInterface) ::GetMouseState [STUB!]\n");
+      return false;
+   }
+
+   bool ::GetJoystickState(int device, Joystick joystick)
+   {
+      sflnprintf("class(EmscriptenInterface) ::GetJoystickState [STUB!]\n");
+      return false;
+   }
+
+   bool ::GetKeyState(Key key)
+   {
+      sflnprintf("class(EmscriptenInterface) ::GetKeyState [STUB!]\n");
+      return false;
+   }
+
+   bool ::SetIcon(Window window, BitmapResource icon)
+   {
+      sflnprintf("class(EmscriptenInterface) ::SetIcon [STUB!]\n");
+      return false;
+   }
+
+   void ::GetScreenArea(Window window, Box box)
+   {
+      sflnprintf("class(EmscriptenInterface) ::GetScreenArea [STUB!]\n");
+   }
+}
+
+#endif
index 67a2254..a20a7cf 100644 (file)
@@ -2,7 +2,7 @@ namespace gui::drivers;
 
 import "instance"
 
-#if (defined(__unix__) || defined(__APPLE__)) && !defined(__DOS__)
+#if (defined(__unix__) || defined(__APPLE__)) && !defined(__DOS__) && !defined(__EMSCRIPTEN__)
 
 #undef __BLOCKS__
 #define DBLCLICK_DELAY  0.3  // seconds
index 8ae03a3..428677f 100644 (file)
@@ -5,7 +5,7 @@ import "instance"
 import "OpenGLDisplayDriver"
 #endif
 
-#if (defined(__unix__) || defined(__APPLE__)) && !defined(ECERE_MINIGLX)
+#if (defined(__unix__) || defined(__APPLE__)) && !defined(ECERE_MINIGLX) && !defined(__EMSCRIPTEN__)
 
 #undef __BLOCKS__
 default:
@@ -50,16 +50,24 @@ typedef int X11Bool;
 
 #include <X11/Xatom.h>
 #include <X11/Xlib.h>
+#if !defined(__EMSCRIPTEN__)
 #include <X11/Xresource.h>
+#endif
 #include <X11/Xutil.h>
 #include <X11/XKBlib.h>
 #include <X11/keysym.h>
 #include <X11/cursorfont.h>
 #include <fcntl.h>
 #if !defined(ECERE_NO3D) && !defined(ECERE_NOGL) //&& !defined(__ODROID__)
+#if defined(__EMSCRIPTEN__)
+#include <GL/glfw.h>
+#else
 #include <GL/glx.h>
 #endif
+#endif
+#if !defined(__EMSCRIPTEN__)
 #include <X11/extensions/Xrender.h>
+#endif
 #include <X11/extensions/XShm.h>
 
 #undef Bool
index 4c3c395..eab0746 100644 (file)
@@ -198,7 +198,7 @@ public class WindowsSkin_Window : Window
          // PrintLn(_class.name, " is at l = ", rcWindow.left, ", r = ", rcWindow.right);
 #else
          Box widths = { 0 };
-#if !defined(__ANDROID__)
+#if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
          XGetBorderWidths(this, widths);
 #endif
          *w += widths.left + widths.right;
@@ -285,7 +285,7 @@ public class WindowsSkin_Window : Window
          *y += client00.y - rcWindow.top;
 #else
          Box widths = { 0 };
-#if !defined(__ANDROID__)
+#if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
          XGetBorderWidths(this, widths);
 #endif
          *x += widths.left;
index 455b810..3603854 100644 (file)
@@ -38,6 +38,8 @@ typedef struct in_addr IN_ADDR;
 import "network"
 import "List"
 
+#if !defined(__EMSCRIPTEN__)
+
 // SERVER
 
 static enum DCOMPacketType
@@ -812,3 +814,5 @@ public:
       sendingOut = false;
    }
 }
+
+#endif // !defined(__EMSCRIPTEN__)
index b9366f2..23a6c8c 100644 (file)
@@ -1,8 +1,14 @@
 #if defined(BUILDING_ECERE_COM)
+#if !defined(__EMSCRIPTEN__)
 import "Semaphore"
 #else
 import "ecere"
 #endif
+#else
+import "ecere"
+#endif
+
+#if !defined(__EMSCRIPTEN__)
 
 public class Condition : struct
 {
@@ -56,3 +62,5 @@ public:
       mutex.Wait();
    }
 }
+
+#endif // !defined(__EMSCRIPTEN__)
index 6b59c2e..9e867db 100644 (file)
@@ -1200,7 +1200,7 @@ class EARArchiveDir : ArchiveDir
       return true;
    }
 };
-#endif
+#endif // !defined(ECERE_NOARCHIVE) && !defined(ECERE_VANILLA)
 
 // Directory Description for file listing
 class EARDir : struct
@@ -1694,7 +1694,7 @@ class EARFileSystem : FileSystem
       }
       return result;
    }
-#endif
+#endif // !defined(ECERE_NOARCHIVE) && !defined(ECERE_VANILLA)
    bool ::QuerySize(const char * archive, FileSize * size)
    {
       bool result = false;
index a6dde40..7ea5966 100644 (file)
@@ -2,6 +2,8 @@ namespace sys;
 
 import "System"
 
+#if !defined(__EMSCRIPTEN__)
+
 public class FileChange
 {
 public:
@@ -431,3 +433,5 @@ static class MonitorThread : Thread
       return 0;
    }
 }
+
+#endif // !defined(__EMSCRIPTEN__)
index 4bb261c..192e836 100644 (file)
@@ -146,6 +146,7 @@ private:
    SettingsLocationType readType;
    SettingsLocationType writeType;
 
+#if !defined(__EMSCRIPTEN__)
    FileMonitor settingsMonitor
    {
       this, fileChange = { modified = true };
@@ -156,6 +157,7 @@ private:
          return true;
       }
    };
+#endif
    File f;
    bool locked;
 
@@ -380,7 +382,9 @@ public:
       SettingsLocationType type = readType;
       if(!f)
       {
+#if !defined(__EMSCRIPTEN__)
          settingsMonitor.StopMonitoring();
+#endif
 
          if(settingsFilePath)
             FileOpenTryRead(type);
@@ -475,7 +479,9 @@ public:
       {
          locked = false;
 
+#if !defined(__EMSCRIPTEN__)
          settingsMonitor.StopMonitoring();
+#endif
 
          if(settingsFilePath)
             // Don't auto delete settingsFilePath because only want to try another path if we were using a global path
@@ -544,7 +550,9 @@ public:
    {
       if(f)
       {
+#if !defined(__EMSCRIPTEN__)
          settingsMonitor.StopMonitoring();
+#endif
          f.Unlock(0,0,true);
          locked = false;
          delete f;
@@ -556,8 +564,10 @@ public:
       Close();
       if(settingsFilePath && OnAskReloadSettings != GlobalSettings::OnAskReloadSettings)
       {
+#if !defined(__EMSCRIPTEN__)
          settingsMonitor.fileName = settingsFilePath;
          settingsMonitor.StartMonitoring();
+#endif
       }
    }
 }
index 592a840..98cf0e5 100644 (file)
@@ -1,5 +1,6 @@
 namespace sys;
 
+import "instance"
 import "System"
 import "Array"
 
index ea4606a..ba212df 100644 (file)
@@ -14,7 +14,7 @@ namespace sys;
 #define uint _uint
 #define set _set
 #define String _String
-#if defined(__WIN32__)
+#if defined(__WIN32__) && !defined(__EMSCRIPTEN__)
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #else
@@ -38,6 +38,8 @@ public int64 GetCurrentThreadID()
 
 public class Mutex : struct
 {
+#if !defined(__EMSCRIPTEN__)
+
 //   class_fixed
 #if defined(__WIN32__)
 #ifdef _DEBUG
@@ -48,6 +50,7 @@ public class Mutex : struct
 #else
    pthread_mutex_t mutex;
 #endif
+#endif
 
 #ifdef _DEBUG
    int64 owningThread;
@@ -56,6 +59,7 @@ public class Mutex : struct
 
    Mutex()
    {
+#if !defined(__EMSCRIPTEN__)
 #if defined(__WIN32__)
 #ifdef _DEBUG
       mutex = CreateMutex(null, FALSE, null);
@@ -76,6 +80,8 @@ public class Mutex : struct
       pthread_mutex_init(&mutex, &attr);
       pthread_mutexattr_destroy(&attr);
 #endif
+#endif
+
       lockCount = 0;
 #ifdef _DEBUG
       owningThread = 0;
@@ -85,6 +91,7 @@ public class Mutex : struct
 
    ~Mutex()
    {
+#if !defined(__EMSCRIPTEN__)
 #if defined(__WIN32__)
 #ifdef _DEBUG
       CloseHandle(mutex);
@@ -94,6 +101,7 @@ public class Mutex : struct
 #else
       pthread_mutex_destroy(&mutex);
 #endif
+#endif
    }
 
 public:
@@ -101,6 +109,7 @@ public:
    {
       if(this)
       {
+#if !defined(__EMSCRIPTEN__)
          /*
          if(this == globalSystem.fileMonitorMutex)
             printf("[%d] Waiting on Mutex %x\n", (int)GetCurrentThreadID(), this);
@@ -125,6 +134,8 @@ public:
 #endif
 #endif
 
+#endif
+
 #ifdef _DEBUG
          owningThread = GetCurrentThreadID();
 #endif
@@ -136,6 +147,7 @@ public:
    {
       if(this)
       {
+#if !defined(__EMSCRIPTEN__)
          /*
          if(this == globalSystem.fileMonitorMutex)
             printf("[%d] Releasing Mutex %x\n", (int)GetCurrentThreadID(), this);
@@ -169,6 +181,8 @@ public:
          pthread_mutex_unlock(&mutex);
 #endif
 #endif
+#endif
+
 #ifdef _DEBUG
          if(lockCount < 0)
             PrintLn("WARNING: lockCount < 0");
index 44c692c..b7e5c7c 100644 (file)
@@ -26,6 +26,8 @@ import "System"
 
 public class Semaphore : struct
 {
+#if !defined(__EMSCRIPTEN__)
+
 #if defined(__WIN32__)
    HANDLE handle;
 #elif defined(__APPLE__)
@@ -35,11 +37,13 @@ public class Semaphore : struct
 #else
    sem_t semaphore;
 #endif
+#endif
 
    int initCount, maxCount;
 
    Semaphore()
    {
+#if !defined(__EMSCRIPTEN__)
 #if defined(__WIN32__)
       handle = CreateSemaphore(null, 0, 1, null);
 #elif defined(__APPLE__)
@@ -47,12 +51,14 @@ public class Semaphore : struct
 #else
       sem_init(&semaphore, 0, 0);
 #endif
+#endif
       maxCount = 1;
       initCount = 0;
    }
 
    ~Semaphore()
    {
+#if !defined(__EMSCRIPTEN__)
 #if defined(__WIN32__)
       if(handle) CloseHandle(handle);
 #elif defined(__APPLE__)
@@ -60,12 +66,14 @@ public class Semaphore : struct
 #else
       sem_destroy(&semaphore);
 #endif
+#endif
    }
 
 public:
    bool TryWait(void)
    {
       bool result;
+#if !defined(__EMSCRIPTEN__)
 #if defined(__WIN32__)
       result = WaitForSingleObject(handle, 0) != WAIT_TIMEOUT;
 #elif defined(__APPLE__)
@@ -84,11 +92,13 @@ public:
 #else
       result = sem_trywait(&semaphore) != EAGAIN;
 #endif
+#endif
       return result;
    }
 
    void Wait(void)
    {
+#if !defined(__EMSCRIPTEN__)
 #if defined(__WIN32__)
       if(WaitForSingleObject(handle, INFINITE /*2000*/) == WAIT_TIMEOUT)
          PrintLn("Semaphore not released?");
@@ -108,10 +118,12 @@ public:
       sem_wait(&semaphore);
 #endif
 #endif
+#endif
    }
 
    void Release(void)
    {
+#if !defined(__EMSCRIPTEN__)
 #if defined(__WIN32__)
       ReleaseSemaphore(handle, 1, null);
 #elif defined(__APPLE__)
@@ -125,12 +137,14 @@ public:
       if(count < maxCount)
          sem_post(&semaphore);
 #endif
+#endif
    }
 
    property int initCount
    {
       set
       {
+#if !defined(__EMSCRIPTEN__)
 #if defined(__WIN32__)
          if(handle) CloseHandle(handle);
          handle = CreateSemaphore(null, initCount, value, null);
@@ -142,6 +156,7 @@ public:
          sem_destroy(&semaphore);
          sem_init(&semaphore, 0, initCount);
 #endif
+#endif
          initCount = value;
       }
       get { return initCount; }
@@ -150,10 +165,12 @@ public:
    {
       set
       {
+#if !defined(__EMSCRIPTEN__)
 #if defined(__WIN32__)
          if(handle) CloseHandle(handle);
          handle = CreateSemaphore(null, value, maxCount, null);
 #endif
+#endif
          maxCount = value;
       }
       get { return maxCount; }
index 1f168a0..1b7bcd8 100644 (file)
@@ -64,10 +64,12 @@ private:
 #if !defined(ECERE_BOOTSTRAP)
 import "units"
 import "Time"
+#if !defined(__EMSCRIPTEN__)
 import "Mutex"
 import "Semaphore"
 import "FileMonitor"
 import "Thread"
+#endif
 import "Archive"
 import "EARArchive"
 import "Date"
@@ -488,14 +490,18 @@ private struct System
    ErrorLevel errorLevel;
 
 #ifndef ECERE_BOOTSTRAP
+#if !defined(__EMSCRIPTEN__)
    Semaphore eventSemaphore;
+#endif
 
    //FileSystem fileSystems;
 
    // File Monitor
    OldList fileMonitors;
+#if !defined(__EMSCRIPTEN__)
    Mutex fileMonitorMutex;
    Thread fileMonitorThread;
+#endif
    bool systemTerminate;
 #endif
 };
index 2495455..ae2478b 100644 (file)
@@ -49,7 +49,7 @@ public class Thread
 #if defined(__WIN32__)
    HANDLE handle;
    uint id;
-#else
+#elif !defined(__EMSCRIPTEN__)
    pthread_t id;
    bool dontDetach;
    Semaphore sem { };
@@ -58,6 +58,7 @@ public class Thread
    uint returnCode;
    bool started;
 
+#if !defined(__EMSCRIPTEN__)
 #if defined(__WIN32__)
    uint ThreadCallBack()
 #else
@@ -82,6 +83,7 @@ public class Thread
       return (void *)(uintptr_t)returnCode;
 #endif
    }
+#endif
 
 public:
    virtual uint Main(void);
@@ -91,11 +93,12 @@ public:
       incref this;
       if(!started)
       {
-#if !defined(__WIN32__)
+#if !defined(__WIN32__) && !defined(__EMSCRIPTEN__)
          sem.TryWait();
 #endif
          started = true;
          // printf("Creating %s thread\n", _class.name);
+#if !defined(__EMSCRIPTEN__)
 #if defined(__WIN32__)
          if(!handle)
          {
@@ -112,13 +115,15 @@ public:
             error = pthread_create(&id, null /*&attr*/, ThreadCallBack, this);
             if(error)
                printf("Error %d creating a thread\n", error);
-          }
+         }
+#endif
 #endif
       }
    }
 
    void Kill()
    {
+#if !defined(__EMSCRIPTEN__)
 #if defined(__WIN32__)
       if(handle)
       {
@@ -129,6 +134,7 @@ public:
       if(started)
          pthread_kill(id, SIGQUIT);
 #endif
+#endif
       if(started)
       {
          started = false;
@@ -138,6 +144,7 @@ public:
 
    void Wait()
    {
+#if !defined(__EMSCRIPTEN__)
 #if defined(__WIN32__)
       if(WaitForSingleObject(handle, INFINITE /*2000*/) == WAIT_TIMEOUT)
          PrintLn("Thread not returning?\n");
@@ -150,10 +157,12 @@ public:
       if(started)
          sem.Wait();
 #endif
+#endif
    }
 
    void SetPriority(ThreadPriority priority)
    {
+#if !defined(__EMSCRIPTEN__)
 #if defined(__WIN32__)
       SetThreadPriority(handle, priority);
 #else
@@ -164,7 +173,9 @@ public:
       pthread_setschedparam(id, policy, &param);
       */
 #endif
+#endif
    }
 
    property bool created { get { return started; } };
 }
+
index 26ad8ff..9df3ac7 100644 (file)
@@ -1,3 +1,4 @@
+import "instance"
 #ifndef ECERE_NOFILE
 import "File"
 #endif
@@ -23,7 +24,7 @@ static Map<const String, Map<const String, const String>> moduleMaps { };
 
 public dllexport void LoadTranslatedStrings(const String moduleName, const char * name)
 {
-#ifndef ECERE_NOFILE
+#if !defined(ECERE_NOFILE) && !defined(__EMSCRIPTEN__)
    File f;
    char fileName[MAX_LOCATION];
 
index 3f2dbf2..69793fc 100644 (file)
@@ -1,4 +1,4 @@
-import "ecere"
+import IMPORT_STATIC "ecere"
 
 class HelloForm : Window
 {
index 07266b4..744b797 100644 (file)
@@ -15,6 +15,9 @@
          "Name" : "Debug",
          "Options" : {
             "Debug" : true,
+            "PreprocessorDefinitions" : [
+               "IMPORT_STATIC="
+            ],
             "FastMath" : false
          }
       },
          "Options" : {
             "Debug" : true,
             "MemoryGuard" : true,
+            "PreprocessorDefinitions" : [
+               "IMPORT_STATIC="
+            ],
             "Console" : true,
             "FastMath" : false
          }
+      },
+      {
+         "Name" : "Emscripten",
+         "Options" : {
+            "Debug" : true,
+            "PreprocessorDefinitions" : [
+               "IMPORT_STATIC=static"
+            ],
+            "Libraries" : [
+               "ecereStatic",
+               "freetype",
+               "z"
+            ],
+            "LibraryDirs" : [
+               "../../../ecere/obj/emscripten.linux.emscripten.x32"
+            ]
+         }
       }
    ],
    "Files" : [