3 #if defined(__unix__) || defined(__APPLE__)
4 #define property _property
9 #define Window X11Window
10 #define Cursor X11Cursor
12 #define Display X11Display
14 #define KeyCode X11KeyCode
15 #define Picture X11Picture
17 #include <X11/Xutil.h>
34 #if !defined(ECERE_VANILLA) && !defined(ECERE_NONET)
35 #if defined(__WIN32__)
37 #define WIN32_LEAN_AND_MEAN
39 static WSADATA wsaData;
41 #elif defined(__unix__) || defined(__APPLE__)
48 #include <netinet/in.h>
50 #include <sys/socket.h>
52 #include <sys/types.h>
54 #include <arpa/inet.h>
59 typedef struct hostent HOSTENT;
60 typedef struct sockaddr SOCKADDR;
61 typedef struct sockaddr_in SOCKADDR_IN;
62 typedef struct in_addr IN_ADDR;
63 #define closesocket(s) close(s)
70 #if defined(__unix__) || defined(__APPLE__)
76 GuiApplication guiApp;
79 enum GuiErrorCode : ErrorCode
81 driverNotSupported = ErrorCode { VeryFatal, 1 },
82 windowCreationFailed = ErrorCode { VeryFatal, 2 },
83 graphicsLoadingFailed = ErrorCode { VeryFatal, 3 },
84 modeSwitchFailed = ErrorCode { VeryFatal, 4 }
87 static char * errorMessages[] =
90 "Graphics driver not supported by any user interface system",
91 "Window creation failed",
92 "Window graphics loading failed",
93 "Driver/Mode switch failed"
96 public class GuiApplication : Application
105 subclass(Interface) interfaceDriver;
106 subclass(Skin) currentSkin;
113 bool fullScreenMode; // Needs to start at true for the desktop to resize
116 Resolution resolution;
117 PixelFormat pixelFormat;
120 char * defaultDisplayDriver;
122 Cursor systemCursors[SystemCursor];
126 OldList customCursors;
129 OldList windowTimers;
132 Window prevWindow; // Used for OnMouseLeave
133 Window windowCaptured;
135 // Mouse based moving & resizing
137 Point windowMovingStart;
138 Point windowMovingBefore;
139 Size windowResizingBefore;
141 bool windowIsResizing;
142 bool resizeX, resizeEndX;
143 bool resizeY, resizeEndY;
145 // Mouse based scrolling
146 Window windowScrolling;
147 Point windowScrollingBefore, windowScrollingStart;
150 Bitmap cursorBackground { };
151 int cursorBackgroundX, cursorBackgroundY;
152 int cursorBackgroundW, cursorBackgroundH;
158 Window acquiredWindow;
159 int acquiredMouseX, acquiredMouseY;
161 Cursor currentCursor;
163 uint errorLevel, lastErrorCode;
171 Window interimWindow;
175 uint timerResolution;
178 Point virtualScreenPos;
186 mainThread = GetCurrentThreadID();
190 strcpy(appName, "ECERE Application");
195 // customCursors.offset = OFFSET(Cursor, prev);
196 windowTimers.offset = (uint)&((Timer)0).prev;
198 for(c = 0; c<SystemCursor::enumSize; c++)
199 systemCursors[c] = Cursor { systemCursor = c; };
201 globalSystem.eventSemaphore = Semaphore { };
202 globalSystem.fileMonitorMutex = Mutex { };
203 globalSystem.fileMonitors.offset = (uint)&((FileMonitor)0).prev;
214 customCursors.Clear();
216 #if defined(__unix__)
218 XUnlockDisplay(xGlobalDisplay);
225 interfaceDriver.Terminate();
228 // interfaceDrivers.Free(null);
234 for(c = 0; c<SystemCursor::enumSize; c++)
235 delete systemCursors[c];
237 #if !defined(ECERE_VANILLA) && !defined(ECERE_NONET)
241 delete globalSystem.eventSemaphore;
242 delete globalSystem.fileMonitorMutex;
243 delete globalSystem.fileMonitorThread;
245 UnapplySkin(class(Window));
251 Time time = GetTime();
254 for(timer = windowTimers.first; timer; timer = timer.next)
255 timer.dispatched = false;
258 for(timer = windowTimers.first; timer; timer = timer.next)
260 if(!timer.dispatched)
262 if((timer.delay - (Seconds)(time - timer.lastTime)) < Seconds { 0.00001 })
265 timer.lastTime = time;
266 if(timer.DelayExpired(timer.window))
268 timer.dispatched = true;
270 eInstance_DecRef(timer);
280 // --- Mouse-based window movement ---
281 void SetCurrentCursor(Cursor cursor)
283 currentCursor = cursor;
286 if(fullScreenMode && cursor.bitmap)
287 interfaceDriver.SetMouseCursor((SystemCursor)-1);
290 interfaceDriver.SetMouseCursor(cursor.systemCursor);
291 cursorBackground.Free();
297 void PreserveAndDrawCursor()
300 if(!acquiredWindow && cursorUpdate && currentCursor && currentCursor->bitmap)
304 Box against = {0,0, desktop.w-1,desktop.h-1};
305 Box box = {0, 0, currentCursor->bitmap->width,currentCursor->bitmap->height};
307 interfaceDriver->GetMousePosition(&mouseX, &mouseY);
309 mouseX -= currentCursor->hotSpotX;
310 mouseY -= currentCursor->hotSpotY;
312 // Preserve Background
313 if(!(eDisplay_GetFlags(desktop.display) & DISPLAY_FLIPPING))
315 cursorBackgroundX = mouseX;
316 cursorBackgroundY = mouseY;
317 cursorBackgroundW = currentCursor->bitmap->width;
318 cursorBackgroundH = currentCursor->bitmap->height;
319 eDisplay_Grab(desktop.display, cursorBackground,
320 mouseX, mouseY, cursorBackgroundW, cursorBackgroundH);
323 eBox_ClipOffset(&box, &against, mouseX, mouseY);
325 if(!(eDisplay_GetFlags(desktop.display) & DISPLAY_FLIPPING))
326 eDisplay_StartUpdate(desktop.display);
328 surface = eDisplay_GetSurface(desktop.display, mouseX, mouseY, &box);
331 eSurface_SetForeground(surface, WHITE);
332 eSurface_Blit(surface, currentCursor->bitmap, 0,0, 0,0,
333 currentCursor->bitmap->width,currentCursor->bitmap->height);
334 eInstance_Delete(surface);
336 if(!(eDisplay_GetFlags(desktop.display) & DISPLAY_FLIPPING))
341 box.bottom += mouseY;
342 eDisplay_Update(desktop.display, &box);
345 if(!(eDisplay_GetFlags(desktop.display) & DISPLAY_FLIPPING))
346 eDisplay_EndUpdate(desktop.display);
351 void RestoreCursorBackground()
354 // Restore Cursor Background
355 if(cursorBackground && desktop.active)
357 Box box = {0, 0, cursorBackgroundW-1,cursorBackgroundH-1};
358 Box against = {0,0, desktop.w-1,desktop.h-1};
361 eBox_ClipOffset(&box, &against, cursorBackgroundX, cursorBackgroundY);
362 if((surface = eDisplay_GetSurface(desktop.display, cursorBackgroundX,cursorBackgroundY, &box)))
364 eSurface_Blit(surface, cursorBackground, 0, 0, 0,0, cursorBackgroundW,cursorBackgroundH);
365 eInstance_Delete(surface);
371 bool IsModeSwitching()
373 return modeSwitching;
376 public bool SetDesktopPosition(int x, int y, int w, int h, bool moveChildren)
379 bool windowResized = desktop.size.w != w || desktop.size.h != h;
380 bool windowMoved = desktop.clientStart.x != x || desktop.clientStart.y != y;
382 if((windowResized || windowMoved) && moveChildren)
385 desktop.Position(x, y, w, h, true, true, true, true, false, false);
387 // Maximized native decorations windows suffer when we drag the dock around, so remaximize them
388 // It's a little jumpy, but oh well.
389 for(child = desktop.children.first; child; child = child.next)
391 if(child.nativeDecorations && child.rootWindow == child && child.state == maximized)
393 child.state = normal;
394 child.state = maximized;
397 /*for(child = desktop.children.first; child; child = child.next)
399 if(!child.systemParent)
404 child.ComputeAnchors(
405 child.ax, child.ay, child.aw, child.ah,
407 child.Position(x, y, w, h, true, true, true, true, false);
409 if(child.state == Maximized)
413 child.ComputeAnchors(,
414 A_LEFT,A_LEFT,A_OFFSET,A_OFFSET,
416 child.Position(, x, y, w, h, false, true, true, true, false);
422 desktop.display.Lock(true);
425 if(!desktop.display.Resize(desktop.size.w, desktop.size.h))
428 desktop.dirty = true;
429 if(!desktop.display.flags.flipping)
430 desktop.Update(null);
432 // When does the desktop have a display in not fullscreen mode?
433 if(!fullScreenMode && !modeSwitching)
434 desktop.UpdateDisplay();
435 desktop.display.Unlock();
439 desktop.SetPosition(x, y, w, h, false, false, false);
443 void SetAppFocus(bool state)
445 // Shouldn't be property here
446 desktop.active = state;
449 bool SelectSkin(char * skinName)
455 for(link = class(Skin).derivatives.first; link; link = link.next)
458 if(skin.name && !strcmp(skin.name, skinName))
461 if(!link) skin = null;
465 if(skin != currentSkin || !currentSkin)
467 // Try finding a driver to support this mode
468 if(skin.textMode != textMode)
474 bool needReload = false;
476 if(!modeSwitching && currentSkin)
478 modeSwitching = true;
479 desktop.UnloadGraphics(true);
483 UnapplySkin(class(Window));
487 ApplySkin(class(Window), skin.name, null);
491 if(desktop.SetupDisplay())
492 if(desktop.LoadGraphics(false, true))
494 modeSwitching = false;
506 void Initialize(bool switchMode)
508 static bool initialized = false;
511 // if(!initialized && eClass_IsDerived(__ecereModule->app->module.inst.class, guiApplicationClass))
514 char * defaultDriver = null;
515 #if defined(ECERE_VANILLA)
516 char * driver = null;
519 // char * driver = getenv("ECERE_DRIVER");
520 char * driver = null;
521 static char driverStorage[1024];
522 GetEnvironment("ECERE_DRIVER", driverStorage, sizeof(driverStorage));
523 if(driverStorage[0]) driver = driverStorage;
527 fullScreenMode = true; // Needs to start at true for the desktop to resize
528 // Set this to true earlier so we can override it!
534 #if defined(__unix__)
536 XLockDisplay(xGlobalDisplay);
542 desktop = Window { };
545 desktop.childrenOrder.circ = true;
546 desktop.childrenCycle.circ = true;
547 desktop.background = blue;
548 desktop.rootWindow = desktop;
549 desktop.cursor = GetCursor(arrow);
550 desktop.caption = new char[strlen(appName) + 1];
551 strcpy(desktop.caption, appName);
552 *&desktop.visible = true;
553 desktop.position = Point { };
554 desktop.mutex = Mutex { };
555 desktop.created = true;
558 #if defined(__WIN32__)
561 defaultDriver = driver;
562 else if(this.isGUIApp && !textMode)
563 defaultDriver = "GDI";
565 defaultDriver = "Win32Console";
568 if(this.isGUIApp && !textMode)
570 char * display = getenv("DISPLAY");
572 if(!display || !display[0] || !SwitchMode(false, "X", 0, 0, 0, null, true))
573 defaultDriver = "NCurses";
574 // SwitchMode(true, "NCurses", 0, PixelFormatText, 0, null, true);
578 defaultDriver = driver;
581 defaultDriver = "NCurses";
586 SwitchMode(false, defaultDriver, 0, 0, 0, null, true);
590 #if defined(__WIN32__)
591 SwitchMode(true, "Win32Console", 0, PixelFormatText, 0, null, true);
596 SwitchMode(true, "SVGA", Res640x480, PixelFormat8, 0, null, true);
599 #if defined(__unix__) || defined(__APPLE__)
600 #if defined(ECERE_MINIGLX)
601 SwitchMode(true, "OpenGL", 0, 0, 0, null, true);
609 defaultDisplayDriver = defaultDriver;
614 virtual bool Init(void);
615 virtual bool Cycle(bool idle);
616 virtual void Terminate(void);
626 // better solution when designing tab order/activated window etc, why do windows move in the list?
629 for(window = desktop.children.first; window; window = window.next)
631 if(window.autoCreate && !window.created)
645 while(desktop && interfaceDriver)
649 if(terminateX != terminated)
651 terminated = terminateX;
657 //printf("Resetting terminate X to 0\n");
661 for(child = desktop.children.first; child; child = child.next)
662 if(child.created && child.visible)
666 for(window = desktop.children.first; window; window = window.next)
667 if(window.mutex) window.mutex.Wait();
669 for(window = desktop.children.first; window; window = window.next)
670 if(window.mutex) window.mutex.Release();
671 wait = !ProcessInput(true);
673 if(lockMutex.owningThread != GetCurrentThreadID())
674 PrintLn("WARNING: ProcessInput returned unlocked GUI!");
683 #if defined(__unix__)
685 XUnlockDisplay(xGlobalDisplay);
691 #if defined(__unix__)
693 XLockDisplay(xGlobalDisplay);
697 eInstance_DecRef(desktop);
705 #if defined(__unix__)
707 XUnlockDisplay(xGlobalDisplay);
715 interfaceDriver.Wait();
721 #if defined(__unix__)
723 XLockDisplay(xGlobalDisplay);
727 bool ProcessInput(bool useProcessAll)
733 #if !defined(ECERE_VANILLA) && !defined(ECERE_NONET)
734 ProcessNetworkEvents();
738 result = interfaceDriver.ProcessInput(useProcessAll && processAll);
739 if(!desktop || !interfaceDriver) return;
743 for(child = app.desktop.children.first; child; child = child.next)
744 if(child.created && child.visible)
746 if(!child) return result;
749 result |= UpdateTimers();
750 result |= ProcessFileNotifications();
753 result |= ProcessFileNotifications();
754 result |= UpdateTimers();
755 result |= interfaceDriver.ProcessInput(useProcessAll && processAll);
762 void UpdateDisplay(void)
764 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
765 if(Desktop3DUpdateDisplay()) return;
770 if(fullScreenMode && desktop.display)
772 desktop.mutex.Wait();
775 desktop.display.Lock(true);
777 if(desktop.dirty || cursorUpdate)
779 if(desktop.display.flags.flipping)
780 desktop.Update(null);
781 desktop.UpdateDisplay();
784 if(cursorUpdate || desktop.dirty)
786 PreserveAndDrawCursor();
787 cursorUpdate = false;
788 desktop.dirty = false;
789 RestoreCursorBackground();
792 desktop.display.Unlock();
794 desktop.mutex.Release();
800 for(window = desktop.children.first; window; window = window.next)
802 if(window.mutex) window.mutex.Wait();
803 if(window.visible && window.dirty)
805 // Logf("Updating %s\n", window.name);
806 interfaceDriver.Lock(window);
809 if(window.display.current)
813 window.display.Lock(true);
814 window.UpdateDisplay();
815 window.display.Unlock();
818 window.dirty = false;
819 interfaceDriver.Unlock(window);
821 Log("--------------\n");
825 if(window.mutex) window.mutex.Release();
833 globalSystem.eventSemaphore.Wait();
836 #if !defined(ECERE_VANILLA) && !defined(ECERE_NONET)
837 bool ProcessNetworkEvents()
839 bool gotEvent = false;
840 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
841 if(network.networkInitialized)
845 struct timeval tv = {0, 0};
850 PauseNetworkEvents();
851 network.mutex.Wait();
854 if(network.connectEvent || network.networkEvent)
855 Log("[P] [NProcess]\n");
857 rs = network.readSet;
858 ws = network.writeSet;
859 es = network.exceptSet;
861 if((network.ns && select(network.ns, &rs, &ws, &es, &tv)) || network.leftOverBytes)
863 network.leftOverBytes = false;
865 // Danger here? Why looping with a next and not unlocking anything?
866 for(socket = network.connectSockets.first; socket; socket = next)
869 if(!socket.processAlone && FD_ISSET(socket.s, &ws))
871 network.mutex.Release();
872 socket.connectThread.Wait();
873 network.mutex.Wait();
876 for(socket = network.sockets.first; socket; socket = next)
879 if(!socket.processAlone)
881 network.mutex.Release();
882 gotEvent |= socket.ProcessSocket(&rs, &ws, &es);
883 network.mutex.Wait();
887 for(service = network.services.first; service; service = nextService)
889 nextService = service.next;
890 if(!service.processAlone)
892 if(FD_ISSET(service.s, &rs))
895 Logf("[P] Accepting connection (%x)\n", service.s);
897 service.accepted = false;
899 if(!service.accepted)
903 int addrLen = sizeof(a);
904 s = accept(service.s,(SOCKADDR *)&a,&addrLen);
910 Log("[P] Connection accepted\n");
914 for(socket = service.sockets.first; socket; socket = next)
917 if(!socket.processAlone)
919 network.mutex.Release();
920 gotEvent |= socket.ProcessSocket(&rs, &ws, &es);
921 network.mutex.Wait();
926 if(network.connectEvent)
932 for(socket = network.connectSockets.first; socket; socket = next)
935 if(socket._connected && socket._connected != -2)
937 network.connectSockets.Remove(socket);
938 delete socket.connectThread;
940 // printf("%s is connected = %d\n", socket._class.name, socket._connected);
941 if(socket._connected == -1)
944 Logf("[P] Processing disconnected connect (%x)\n", socket.s);
947 if(socket.disconnectCode == ResolveFailed)
948 Logf("Error resolving address %s\n", socket.address);
950 if(socket.s == network.ns - 1)
951 Network_DetermineMaxSocket();
956 else if(socket._connected == 1)
959 Log("[P] Processing connected connect\n");
961 FD_CLR(socket.s, &network.writeSet);
962 FD_SET(socket.s, &network.readSet);
963 FD_SET(socket.s, &network.exceptSet);
964 network.mutex.Release();
966 // printf("Calling OnConnect on %s\n", socket._class.name);
968 network.mutex.Wait();
969 network.sockets.Add(socket);
977 network.connectEvent = false;
979 if(network.networkEvent)
981 network.networkEvent = false;
982 network.selectSemaphore.Release();
987 for(semPtr = network.mtSemaphores.first; semPtr; semPtr = semPtr.next)
989 ((Semaphore)semPtr.data).Release();
993 network.mutex.Release();
994 ResumeNetworkEvents();
1000 void WaitNetworkEvent()
1002 if(network.networkInitialized)
1004 if(GetCurrentThreadID() == network.mainThreadID)
1010 Semaphore semaphore { };
1011 OldLink semPtr { data = semaphore };
1012 network.mutex.Wait();
1013 network.mtSemaphores.Add(semPtr);
1014 network.mutex.Release();
1016 ResumeNetworkEvents();
1018 PauseNetworkEvents();
1019 network.mutex.Wait();
1020 network.mtSemaphores.Delete(semPtr);
1021 network.mutex.Release();
1027 void PauseNetworkEvents()
1029 if(network.networkInitialized)
1031 network.processMutex.Wait();
1035 void ResumeNetworkEvents()
1037 if(network.networkInitialized)
1039 network.processMutex.Release();
1044 void SignalEvent(void)
1046 globalSystem.eventSemaphore.Release();
1049 // TODO: Might want to make this private with simpler public version?
1050 bool SwitchMode(bool fullScreen, char * driverName, Resolution resolution, PixelFormat colorDepth, int refreshRate, char * skinName, bool fallBack)
1052 bool result = false;
1055 bool fbFullScreen = 0;
1056 Resolution fbResolution = 0;
1057 PixelFormat fbColorDepth = 0;
1058 int fbRefreshRate = 0;
1059 subclass(Interface) inter;
1060 subclass(Skin) skin = null;
1066 for(link = class(Skin).derivatives.first; link; link = link.next)
1069 if(skin.name && !strcmp(skin.name, skinName))
1072 if(!link) skin = null;
1077 fbDriver = defaultDisplayDriver;
1078 inter = interfaceDriver;
1081 interfaceDriver.GetCurrentMode(&fbFullScreen, &fbResolution, &fbColorDepth, &fbRefreshRate);
1083 if(!driverName && !interfaceDriver)
1084 driverName = defaultDisplayDriver;
1086 if(driverName || (skin && skin.textMode != textMode))
1088 for(link = class(Interface).derivatives.first; link; link = link.next)
1090 bool foundDriver = false;
1092 char ** graphicsDrivers;
1095 graphicsDrivers = inter.GraphicsDrivers(&numDrivers);
1097 for(c=0; c<numDrivers; c++)
1098 if(!driverName || !strcmp(driverName, graphicsDrivers[c]))
1100 if(!skin || skin.textMode == IsDriverTextMode(graphicsDrivers[c]))
1102 driverName = graphicsDrivers[c];
1117 #if defined(__WIN32__)
1118 #if !defined(ECERE_VANILLA)
1119 if(!strcmp(driverName, "Win32Console")) inter = (subclass(Interface))class(Win32ConsoleInterface); else
1121 inter = (subclass(Interface))class(Win32Interface);
1123 if(!strcmp(driverName, "X")) inter = (subclass(Interface))class(XInterface);
1124 else inter = (subclass(Interface))class(NCursesInterface);
1129 if(interfaceDriver && (!driverName || (fbDriver && !strcmp(fbDriver, driverName))) &&
1130 fullScreen == fbFullScreen &&
1131 (!resolution || resolution == fbResolution) &&
1132 (!colorDepth || colorDepth == fbColorDepth) &&
1133 (!refreshRate || refreshRate == fbRefreshRate) &&
1134 (currentSkin && (!skinName || !strcmp(currentSkin.name, skinName))))
1138 bool wasFullScreen = fullScreenMode;
1139 subclass(Skin) oldSkin = currentSkin;
1142 modeSwitching = true;
1145 desktop.UnloadGraphics(true);
1147 if(inter != interfaceDriver)
1151 interfaceDriver.Terminate();
1153 result = inter.Initialize();
1161 interfaceDriver = inter;
1162 interfaceDriver.SetTimerResolution(timerResolution);
1163 inter.EnsureFullScreen(&fullScreen);
1164 fullScreenMode = fullScreen;
1166 if((!wasFullScreen && !fullScreen) ||
1167 inter.ScreenMode(fullScreen, resolution, colorDepth, refreshRate, &textMode))
1169 if(!fbDriver || (driverName && strcmp(fbDriver, driverName)))
1170 defaultDisplayDriver = driverName;
1172 if(!skinName || !SelectSkin(skinName))
1174 if(!currentSkin || currentSkin.textMode != textMode ||
1175 !SelectSkin(currentSkin.name))
1178 subclass(Skin) skin = null;
1180 for(link = class(Skin).derivatives.first; link; link = link.next)
1183 if(skin.textMode == textMode)
1186 if(!link) skin = null;
1189 SelectSkin(skin.name);
1193 if(currentSkin && desktop.SetupDisplay())
1195 desktop.active = true;
1199 desktop.display.Lock(false);
1200 desktop.display.Position(0,0);
1201 desktop.display.Unlock();
1204 if(desktop.LoadGraphics(false, oldSkin != currentSkin))
1208 desktop.UpdateDisplay();
1211 this.fullScreen = fullScreen;
1217 modeSwitching = false;
1219 LogErrorCode(modeSwitchFailed, driverName ? driverName : defaultDisplayDriver);
1222 LogErrorCode(driverNotSupported, driverName ? driverName : defaultDisplayDriver);
1224 if(!result && fallBack && fbDriver)
1226 if(!SwitchMode(fbFullScreen, fbDriver, fbResolution, fbColorDepth, fbRefreshRate, null, false))
1227 Log("Error falling back to previous video mode.\n");
1232 bool ProcessFileNotifications()
1234 bool activity = false;
1235 FileMonitor monitor, next;
1236 static int reentrant = 0;
1238 // printf("[%d] Waiting in ProcessFileNotifications for fileMonitor Mutex %x...\n", GetCurrentThreadID(), globalSystem.fileMonitorMutex);
1239 globalSystem.fileMonitorMutex.Wait();
1241 for(monitor = globalSystem.fileMonitors.first; monitor; monitor = next)
1245 next = monitor.next;
1248 if(!monitor.reentrant && !monitor.toBeFreed)
1250 monitor.reentrant = true;
1251 while((notify = monitor.fileNotifies.first))
1253 monitor.fileNotifies.Remove(notify);
1257 if(monitor.directory)
1259 if(!monitor.OnDirNotify(monitor.data, notify.action, notify.fileName, notify.param))
1260 monitor.StopMonitoring();
1264 if(!monitor.OnFileNotify(monitor.data, notify.action, notify.param))
1265 monitor.StopMonitoring();
1268 monitor.reentrant = false;
1274 monitor.reentrant = false;
1281 for(monitor = globalSystem.fileMonitors.first; monitor; monitor = next)
1283 next = monitor.next;
1284 if(monitor.toBeFreed && !monitor.reentrant)
1285 monitor.FreeMonitor();
1288 // printf("[%d] Releasing in ProcessFileNotifications fileMonitor Mutex %x...\n", GetCurrentThreadID(), globalSystem.fileMonitorMutex);
1289 globalSystem.fileMonitorMutex.Release();
1296 #if defined(__unix__)
1298 XLockDisplay(xGlobalDisplay);
1304 #if defined(__unix__)
1306 XUnlockDisplay(xGlobalDisplay);
1308 lockMutex.Release();
1311 Cursor GetCursor(SystemCursor cursor)
1313 return systemCursors[cursor];
1316 bool GetKeyState(Key key)
1318 return interfaceDriver.GetKeyState(key);
1321 bool GetMouseState(MouseButtons * buttons, int * x, int * y)
1323 return interfaceDriver.GetMouseState(buttons, x, y);
1327 property char * appName
1331 strcpy(appName, value);
1332 if(desktop) desktop.text = appName;
1336 return (char *)(this ? appName : null);
1339 property Semaphore semaphore { get { return globalSystem.eventSemaphore; } };
1340 property bool alwaysEmptyInput{ set { processAll = value; } get { return processAll; } };
1341 property bool fullScreen
1345 SwitchMode(value, defaultDisplayDriver, resolution,
1346 pixelFormat, refreshRate, currentSkin ? currentSkin.name : null, true);
1348 get { return this ? fullScreen : false; }
1350 property char * driver
1354 SwitchMode( fullScreen, value, resolution, pixelFormat, refreshRate,
1355 currentSkin ? currentSkin.name : null, true);
1357 get { return this ? defaultDisplayDriver : null; }
1359 property Resolution resolution
1363 SwitchMode(fullScreen, defaultDisplayDriver, value, pixelFormat, refreshRate,
1364 currentSkin ? currentSkin.name : null, true);
1366 get { return this ? resolution : 0; }
1368 property PixelFormat pixelFormat
1372 SwitchMode(fullScreen, defaultDisplayDriver, resolution,
1373 pixelFormat, refreshRate, currentSkin ? currentSkin.name : null, true);
1375 get { return this ? pixelFormat : 0; }
1377 property int refreshRate
1381 SwitchMode(fullScreen, defaultDisplayDriver, resolution,
1382 pixelFormat, refreshRate, currentSkin ? currentSkin.name : null, true);
1384 get { return this ? refreshRate : 0; }
1386 property char * skin
1388 set { SelectSkin(value); }
1389 get { return (this && currentSkin) ? currentSkin.name : null; }
1391 property bool textMode
1393 set { textMode = value; } // TODO: Implement switching
1394 get { return this ? textMode : false; }
1396 property Window desktop { get { return this ? desktop : null; } };
1397 property char ** drivers { get { return null; } };
1398 property char ** skins { get { return null; } };
1399 property subclass(Skin) currentSkin { get { return this ? currentSkin : null; } };
1400 property int numDrivers { get { return 0; } };
1401 property int numSkins { get { return 0; } };
1402 property uint timerResolution
1404 set { timerResolution = value; if(interfaceDriver) interfaceDriver.SetTimerResolution(value); }