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
import "CocoaInterface"
#endif
-#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__)
+#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
import "XInterface"
#endif
bool processAll;
+#if !defined(__EMSCRIPTEN__)
Mutex waitMutex {};
+#endif
bool waiting;
+#if !defined(__EMSCRIPTEN__)
Mutex lockMutex {};
+#endif
Window interimWindow;
bool caretEnabled;
{
SystemCursor c;
+#if !defined(__EMSCRIPTEN__)
mainThread = GetCurrentThreadID();
+#endif
if(!guiApp)
guiApp = this;
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;
}
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();
Network_Terminate();
#endif
+#if !defined(__EMSCRIPTEN__)
delete globalSystem.eventSemaphore;
delete globalSystem.fileMonitorMutex;
delete globalSystem.fileMonitorThread;
+#endif
UnapplySkin(class(Window));
errorLevel = 2;
+#if !defined(__EMSCRIPTEN__)
lockMutex.Wait();
+#endif
/*#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__)
if(xGlobalDisplay)
XLockDisplay(xGlobalDisplay);
desktop.caption = appName;
*&desktop.visible = true;
desktop.position = Point { };
+#if !defined(__EMSCRIPTEN__)
desktop.mutex = Mutex { };
+#endif
desktop.created = true;
}
else
defaultDriver = "OpenGL";
}
+ #elif defined(__EMSCRIPTEN__)
+ {
+ if(driver)
+ defaultDriver = driver;
+ else
+ defaultDriver = "OpenGL";
+ }
#else
if((this.isGUIApp & 1) && !textMode)
{
}
}
+#ifdef __EMSCRIPTEN__
+ emscripten_set_main_loop(emscripten_main_loop_callback, 1/*60*/, 1);
+#endif
+
if(desktop)
{
int terminated = 0;
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;
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
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
{
if(fullScreenMode && desktop.display)
{
+#if !defined(__EMSCRIPTEN__)
desktop.mutex.Wait();
+#endif
if(desktop.active)
{
desktop.display.Lock(true);
desktop.display.Unlock();
}
+#if !defined(__EMSCRIPTEN__)
desktop.mutex.Release();
+#endif
}
else
{
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);
usleep(1000000);
*/
}
+#if !defined(__EMSCRIPTEN__)
if(window.mutex) window.mutex.Release();
+#endif
}
}
}
void WaitEvent(void)
{
+#if !defined(__EMSCRIPTEN__)
globalSystem.eventSemaphore.Wait();
+#endif
}
#if !defined(ECERE_VANILLA) && !defined(ECERE_NONET)
void SignalEvent(void)
{
+#if !defined(__EMSCRIPTEN__)
globalSystem.eventSemaphore.Release();
+#endif
}
// TODO: Might want to make this private with simpler public version?
bool ProcessFileNotifications()
{
+#if !defined(__EMSCRIPTEN__)
bool activity = false;
FileMonitor monitor, next;
static int reentrant = 0;
// 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)
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
{
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