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;
187 strcpy(appName, "ECERE Application");
192 // customCursors.offset = OFFSET(Cursor, prev);
193 windowTimers.offset = (uint)&((Timer)0).prev;
195 for(c = 0; c<SystemCursor::enumSize; c++)
196 systemCursors[c] = Cursor { systemCursor = c; };
198 globalSystem.eventSemaphore = Semaphore { };
199 globalSystem.fileMonitorMutex = Mutex { };
200 globalSystem.fileMonitors.offset = (uint)&((FileMonitor)0).prev;
211 customCursors.Clear();
213 #if defined(__unix__)
215 XUnlockDisplay(xGlobalDisplay);
222 interfaceDriver.Terminate();
225 // interfaceDrivers.Free(null);
231 for(c = 0; c<SystemCursor::enumSize; c++)
232 delete systemCursors[c];
234 #if !defined(ECERE_VANILLA) && !defined(ECERE_NONET)
238 delete globalSystem.eventSemaphore;
239 delete globalSystem.fileMonitorMutex;
240 delete globalSystem.fileMonitorThread;
242 UnapplySkin(class(Window));
248 Time time = GetTime();
251 for(timer = windowTimers.first; timer; timer = timer.next)
252 timer.dispatched = false;
255 for(timer = windowTimers.first; timer; timer = timer.next)
257 if(!timer.dispatched)
259 if((timer.delay - (Seconds)(time - timer.lastTime)) < Seconds { 0.00001 })
262 timer.lastTime = time;
263 if(timer.DelayExpired(timer.window))
265 timer.dispatched = true;
267 eInstance_DecRef(timer);
277 // --- Mouse-based window movement ---
278 void SetCurrentCursor(Cursor cursor)
280 currentCursor = cursor;
283 if(fullScreenMode && cursor.bitmap)
284 interfaceDriver.SetMouseCursor((SystemCursor)-1);
287 interfaceDriver.SetMouseCursor(cursor.systemCursor);
288 cursorBackground.Free();
294 void PreserveAndDrawCursor()
297 if(!acquiredWindow && cursorUpdate && currentCursor && currentCursor->bitmap)
301 Box against = {0,0, desktop.w-1,desktop.h-1};
302 Box box = {0, 0, currentCursor->bitmap->width,currentCursor->bitmap->height};
304 interfaceDriver->GetMousePosition(&mouseX, &mouseY);
306 mouseX -= currentCursor->hotSpotX;
307 mouseY -= currentCursor->hotSpotY;
309 // Preserve Background
310 if(!(eDisplay_GetFlags(desktop.display) & DISPLAY_FLIPPING))
312 cursorBackgroundX = mouseX;
313 cursorBackgroundY = mouseY;
314 cursorBackgroundW = currentCursor->bitmap->width;
315 cursorBackgroundH = currentCursor->bitmap->height;
316 eDisplay_Grab(desktop.display, cursorBackground,
317 mouseX, mouseY, cursorBackgroundW, cursorBackgroundH);
320 eBox_ClipOffset(&box, &against, mouseX, mouseY);
322 if(!(eDisplay_GetFlags(desktop.display) & DISPLAY_FLIPPING))
323 eDisplay_StartUpdate(desktop.display);
325 surface = eDisplay_GetSurface(desktop.display, mouseX, mouseY, &box);
328 eSurface_SetForeground(surface, WHITE);
329 eSurface_Blit(surface, currentCursor->bitmap, 0,0, 0,0,
330 currentCursor->bitmap->width,currentCursor->bitmap->height);
331 eInstance_Delete(surface);
333 if(!(eDisplay_GetFlags(desktop.display) & DISPLAY_FLIPPING))
338 box.bottom += mouseY;
339 eDisplay_Update(desktop.display, &box);
342 if(!(eDisplay_GetFlags(desktop.display) & DISPLAY_FLIPPING))
343 eDisplay_EndUpdate(desktop.display);
348 void RestoreCursorBackground()
351 // Restore Cursor Background
352 if(cursorBackground && desktop.active)
354 Box box = {0, 0, cursorBackgroundW-1,cursorBackgroundH-1};
355 Box against = {0,0, desktop.w-1,desktop.h-1};
358 eBox_ClipOffset(&box, &against, cursorBackgroundX, cursorBackgroundY);
359 if((surface = eDisplay_GetSurface(desktop.display, cursorBackgroundX,cursorBackgroundY, &box)))
361 eSurface_Blit(surface, cursorBackground, 0, 0, 0,0, cursorBackgroundW,cursorBackgroundH);
362 eInstance_Delete(surface);
368 bool IsModeSwitching()
370 return modeSwitching;
373 public bool SetDesktopPosition(int x, int y, int w, int h, bool moveChildren)
376 bool windowResized = desktop.size.w != w || desktop.size.h != h;
377 bool windowMoved = desktop.clientStart.x != x || desktop.clientStart.y != y;
379 if((windowResized || windowMoved) && moveChildren)
382 desktop.Position(x, y, w, h, true, true, true, true, false, false);
384 // Maximized native decorations windows suffer when we drag the dock around, so remaximize them
385 // It's a little jumpy, but oh well.
386 for(child = desktop.children.first; child; child = child.next)
388 if(child.nativeDecorations && child.rootWindow == child && child.state == maximized)
390 child.state = normal;
391 child.state = maximized;
394 /*for(child = desktop.children.first; child; child = child.next)
396 if(!child.systemParent)
401 child.ComputeAnchors(
402 child.ax, child.ay, child.aw, child.ah,
404 child.Position(x, y, w, h, true, true, true, true, false);
406 if(child.state == Maximized)
410 child.ComputeAnchors(,
411 A_LEFT,A_LEFT,A_OFFSET,A_OFFSET,
413 child.Position(, x, y, w, h, false, true, true, true, false);
419 desktop.display.Lock(true);
422 if(!desktop.display.Resize(desktop.size.w, desktop.size.h))
425 desktop.dirty = true;
426 if(!desktop.display.flags.flipping)
427 desktop.Update(null);
429 // When does the desktop have a display in not fullscreen mode?
430 if(!fullScreenMode && !modeSwitching)
431 desktop.UpdateDisplay();
432 desktop.display.Unlock();
436 desktop.SetPosition(x, y, w, h, false, false, false);
440 void SetAppFocus(bool state)
442 // Shouldn't be property here
443 desktop.active = state;
446 bool SelectSkin(char * skinName)
452 for(link = class(Skin).derivatives.first; link; link = link.next)
455 if(skin.name && !strcmp(skin.name, skinName))
458 if(!link) skin = null;
462 if(skin != currentSkin || !currentSkin)
464 // Try finding a driver to support this mode
465 if(skin.textMode != textMode)
471 bool needReload = false;
473 if(!modeSwitching && currentSkin)
475 modeSwitching = true;
476 desktop.UnloadGraphics(true);
480 UnapplySkin(class(Window));
484 ApplySkin(class(Window), skin.name, null);
488 if(desktop.SetupDisplay())
489 if(desktop.LoadGraphics(false, true))
491 modeSwitching = false;
503 void Initialize(bool switchMode)
505 static bool initialized = false;
508 // if(!initialized && eClass_IsDerived(__ecereModule->app->module.inst.class, guiApplicationClass))
511 char * defaultDriver = null;
512 #if defined(ECERE_VANILLA)
513 char * driver = null;
516 // char * driver = getenv("ECERE_DRIVER");
517 char * driver = null;
518 static char driverStorage[1024];
519 GetEnvironment("ECERE_DRIVER", driverStorage, sizeof(driverStorage));
520 if(driverStorage[0]) driver = driverStorage;
524 fullScreenMode = true; // Needs to start at true for the desktop to resize
525 // Set this to true earlier so we can override it!
531 #if defined(__unix__)
533 XLockDisplay(xGlobalDisplay);
539 desktop = Window { };
542 desktop.childrenOrder.circ = true;
543 desktop.childrenCycle.circ = true;
544 desktop.background = blue;
545 desktop.rootWindow = desktop;
546 desktop.cursor = GetCursor(arrow);
547 desktop.caption = new char[strlen(appName) + 1];
548 strcpy(desktop.caption, appName);
549 *&desktop.visible = true;
550 desktop.position = Point { };
551 desktop.mutex = Mutex { };
552 desktop.created = true;
555 #if defined(__WIN32__)
558 defaultDriver = driver;
559 else if(this.isGUIApp && !textMode)
560 defaultDriver = "GDI";
562 defaultDriver = "Win32Console";
565 if(this.isGUIApp && !textMode)
567 char * display = getenv("DISPLAY");
569 if(!display || !display[0] || !SwitchMode(false, "X", 0, 0, 0, null, true))
570 defaultDriver = "NCurses";
571 // SwitchMode(true, "NCurses", 0, PixelFormatText, 0, null, true);
575 defaultDriver = driver;
578 defaultDriver = "NCurses";
583 SwitchMode(false, defaultDriver, 0, 0, 0, null, true);
587 #if defined(__WIN32__)
588 SwitchMode(true, "Win32Console", 0, PixelFormatText, 0, null, true);
593 SwitchMode(true, "SVGA", Res640x480, PixelFormat8, 0, null, true);
596 #if defined(__unix__) || defined(__APPLE__)
597 #if defined(ECERE_MINIGLX)
598 SwitchMode(true, "OpenGL", 0, 0, 0, null, true);
606 defaultDisplayDriver = defaultDriver;
611 virtual bool Init(void);
612 virtual bool Cycle(bool idle);
613 virtual void Terminate(void);
623 // better solution when designing tab order/activated window etc, why do windows move in the list?
626 for(window = desktop.children.first; window; window = window.next)
628 if(window.autoCreate && !window.created)
642 while(desktop && interfaceDriver)
646 if(terminateX != terminated)
648 terminated = terminateX;
654 //printf("Resetting terminate X to 0\n");
658 for(child = desktop.children.first; child; child = child.next)
659 if(child.created && child.visible)
663 for(window = desktop.children.first; window; window = window.next)
664 if(window.mutex) window.mutex.Wait();
666 for(window = desktop.children.first; window; window = window.next)
667 if(window.mutex) window.mutex.Release();
668 wait = !ProcessInput(true);
676 #if defined(__unix__)
678 XUnlockDisplay(xGlobalDisplay);
684 #if defined(__unix__)
686 XLockDisplay(xGlobalDisplay);
690 eInstance_DecRef(desktop);
698 #if defined(__unix__)
700 XUnlockDisplay(xGlobalDisplay);
708 interfaceDriver.Wait();
714 #if defined(__unix__)
716 XLockDisplay(xGlobalDisplay);
720 bool ProcessInput(bool useProcessAll)
726 #if !defined(ECERE_VANILLA) && !defined(ECERE_NONET)
727 ProcessNetworkEvents();
731 result = interfaceDriver.ProcessInput(useProcessAll && processAll);
732 if(!desktop || !interfaceDriver) return;
736 for(child = app.desktop.children.first; child; child = child.next)
737 if(child.created && child.visible)
739 if(!child) return result;
742 result |= UpdateTimers();
743 result |= ProcessFileNotifications();
746 result |= ProcessFileNotifications();
747 result |= UpdateTimers();
748 result |= interfaceDriver.ProcessInput(useProcessAll && processAll);
755 void UpdateDisplay(void)
757 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
758 if(Desktop3DUpdateDisplay()) return;
763 if(fullScreenMode && desktop.display)
765 desktop.mutex.Wait();
768 desktop.display.Lock(true);
770 if(desktop.dirty || cursorUpdate)
772 if(desktop.display.flags.flipping)
773 desktop.Update(null);
774 desktop.UpdateDisplay();
777 if(cursorUpdate || desktop.dirty)
779 PreserveAndDrawCursor();
780 cursorUpdate = false;
781 desktop.dirty = false;
782 RestoreCursorBackground();
785 desktop.display.Unlock();
787 desktop.mutex.Release();
793 for(window = desktop.children.first; window; window = window.next)
795 if(window.mutex) window.mutex.Wait();
796 if(window.visible && window.dirty)
798 // Logf("Updating %s\n", window.name);
799 interfaceDriver.Lock(window);
802 if(window.display.current)
806 window.display.Lock(true);
807 window.UpdateDisplay();
808 window.display.Unlock();
811 window.dirty = false;
812 interfaceDriver.Unlock(window);
814 Log("--------------\n");
818 if(window.mutex) window.mutex.Release();
826 globalSystem.eventSemaphore.Wait();
829 #if !defined(ECERE_VANILLA) && !defined(ECERE_NONET)
830 bool ProcessNetworkEvents()
832 bool gotEvent = false;
833 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
834 if(network.networkInitialized)
838 struct timeval tv = {0, 0};
843 PauseNetworkEvents();
844 network.mutex.Wait();
847 if(network.connectEvent || network.networkEvent)
848 Log("[P] [NProcess]\n");
850 rs = network.readSet;
851 ws = network.writeSet;
852 es = network.exceptSet;
854 if((network.ns && select(network.ns, &rs, &ws, &es, &tv)) || network.leftOverBytes)
856 network.leftOverBytes = false;
858 // Danger here? Why looping with a next and not unlocking anything?
859 for(socket = network.connectSockets.first; socket; socket = next)
862 if(!socket.processAlone && FD_ISSET(socket.s, &ws))
864 network.mutex.Release();
865 socket.connectThread.Wait();
866 network.mutex.Wait();
869 for(socket = network.sockets.first; socket; socket = next)
872 if(!socket.processAlone)
874 network.mutex.Release();
875 gotEvent |= socket.ProcessSocket(&rs, &ws, &es);
876 network.mutex.Wait();
880 for(service = network.services.first; service; service = nextService)
882 nextService = service.next;
883 if(!service.processAlone)
885 if(FD_ISSET(service.s, &rs))
888 Logf("[P] Accepting connection (%x)\n", service.s);
890 service.accepted = false;
892 if(!service.accepted)
896 int addrLen = sizeof(a);
897 s = accept(service.s,(SOCKADDR *)&a,&addrLen);
903 Log("[P] Connection accepted\n");
907 for(socket = service.sockets.first; socket; socket = next)
910 if(!socket.processAlone)
912 network.mutex.Release();
913 gotEvent |= socket.ProcessSocket(&rs, &ws, &es);
914 network.mutex.Wait();
919 if(network.connectEvent)
925 for(socket = network.connectSockets.first; socket; socket = next)
928 if(socket._connected && socket._connected != -2)
930 network.connectSockets.Remove(socket);
931 delete socket.connectThread;
933 // printf("%s is connected = %d\n", socket._class.name, socket._connected);
934 if(socket._connected == -1)
937 Logf("[P] Processing disconnected connect (%x)\n", socket.s);
940 if(socket.disconnectCode == ResolveFailed)
941 Logf("Error resolving address %s\n", socket.address);
943 if(socket.s == network.ns - 1)
944 Network_DetermineMaxSocket();
949 else if(socket._connected == 1)
952 Log("[P] Processing connected connect\n");
954 FD_CLR(socket.s, &network.writeSet);
955 FD_SET(socket.s, &network.readSet);
956 FD_SET(socket.s, &network.exceptSet);
957 network.mutex.Release();
959 // printf("Calling OnConnect on %s\n", socket._class.name);
961 network.mutex.Wait();
962 network.sockets.Add(socket);
970 network.connectEvent = false;
972 if(network.networkEvent)
974 network.networkEvent = false;
975 network.selectSemaphore.Release();
980 for(semPtr = network.mtSemaphores.first; semPtr; semPtr = semPtr.next)
982 ((Semaphore)semPtr.data).Release();
986 network.mutex.Release();
987 ResumeNetworkEvents();
993 void WaitNetworkEvent()
995 if(network.networkInitialized)
997 if(GetCurrentThreadID() == network.mainThreadID)
1003 Semaphore semaphore { };
1004 OldLink semPtr { data = semaphore };
1005 network.mutex.Wait();
1006 network.mtSemaphores.Add(semPtr);
1007 network.mutex.Release();
1009 ResumeNetworkEvents();
1011 PauseNetworkEvents();
1012 network.mutex.Wait();
1013 network.mtSemaphores.Delete(semPtr);
1014 network.mutex.Release();
1020 void PauseNetworkEvents()
1022 if(network.networkInitialized)
1024 network.processMutex.Wait();
1028 void ResumeNetworkEvents()
1030 if(network.networkInitialized)
1032 network.processMutex.Release();
1037 void SignalEvent(void)
1039 globalSystem.eventSemaphore.Release();
1042 // TODO: Might want to make this private with simpler public version?
1043 bool SwitchMode(bool fullScreen, char * driverName, Resolution resolution, PixelFormat colorDepth, int refreshRate, char * skinName, bool fallBack)
1045 bool result = false;
1048 bool fbFullScreen = 0;
1049 Resolution fbResolution = 0;
1050 PixelFormat fbColorDepth = 0;
1051 int fbRefreshRate = 0;
1052 subclass(Interface) inter;
1053 subclass(Skin) skin = null;
1059 for(link = class(Skin).derivatives.first; link; link = link.next)
1062 if(skin.name && !strcmp(skin.name, skinName))
1065 if(!link) skin = null;
1070 fbDriver = defaultDisplayDriver;
1071 inter = interfaceDriver;
1074 interfaceDriver.GetCurrentMode(&fbFullScreen, &fbResolution, &fbColorDepth, &fbRefreshRate);
1076 if(!driverName && !interfaceDriver)
1077 driverName = defaultDisplayDriver;
1079 if(driverName || (skin && skin.textMode != textMode))
1081 for(link = class(Interface).derivatives.first; link; link = link.next)
1083 bool foundDriver = false;
1085 char ** graphicsDrivers;
1088 graphicsDrivers = inter.GraphicsDrivers(&numDrivers);
1090 for(c=0; c<numDrivers; c++)
1091 if(!driverName || !strcmp(driverName, graphicsDrivers[c]))
1093 if(!skin || skin.textMode == IsDriverTextMode(graphicsDrivers[c]))
1095 driverName = graphicsDrivers[c];
1110 #if defined(__WIN32__)
1111 #if !defined(ECERE_VANILLA)
1112 if(!strcmp(driverName, "Win32Console")) inter = (subclass(Interface))class(Win32ConsoleInterface); else
1114 inter = (subclass(Interface))class(Win32Interface);
1116 if(!strcmp(driverName, "X")) inter = (subclass(Interface))class(XInterface);
1117 else inter = (subclass(Interface))class(NCursesInterface);
1122 if(interfaceDriver && (!driverName || (fbDriver && !strcmp(fbDriver, driverName))) &&
1123 fullScreen == fbFullScreen &&
1124 (!resolution || resolution == fbResolution) &&
1125 (!colorDepth || colorDepth == fbColorDepth) &&
1126 (!refreshRate || refreshRate == fbRefreshRate) &&
1127 (currentSkin && (!skinName || !strcmp(currentSkin.name, skinName))))
1131 bool wasFullScreen = fullScreenMode;
1132 subclass(Skin) oldSkin = currentSkin;
1135 modeSwitching = true;
1138 desktop.UnloadGraphics(true);
1140 if(inter != interfaceDriver)
1144 interfaceDriver.Terminate();
1146 result = inter.Initialize();
1154 interfaceDriver = inter;
1155 interfaceDriver.SetTimerResolution(timerResolution);
1156 inter.EnsureFullScreen(&fullScreen);
1157 fullScreenMode = fullScreen;
1159 if((!wasFullScreen && !fullScreen) ||
1160 inter.ScreenMode(fullScreen, resolution, colorDepth, refreshRate, &textMode))
1162 if(!fbDriver || (driverName && strcmp(fbDriver, driverName)))
1163 defaultDisplayDriver = driverName;
1165 if(!skinName || !SelectSkin(skinName))
1167 if(!currentSkin || currentSkin.textMode != textMode ||
1168 !SelectSkin(currentSkin.name))
1171 subclass(Skin) skin = null;
1173 for(link = class(Skin).derivatives.first; link; link = link.next)
1176 if(skin.textMode == textMode)
1179 if(!link) skin = null;
1182 SelectSkin(skin.name);
1186 if(currentSkin && desktop.SetupDisplay())
1188 desktop.active = true;
1192 desktop.display.Lock(false);
1193 desktop.display.Position(0,0);
1194 desktop.display.Unlock();
1197 if(desktop.LoadGraphics(false, oldSkin != currentSkin))
1201 desktop.UpdateDisplay();
1204 this.fullScreen = fullScreen;
1210 modeSwitching = false;
1212 LogErrorCode(modeSwitchFailed, driverName ? driverName : defaultDisplayDriver);
1215 LogErrorCode(driverNotSupported, driverName ? driverName : defaultDisplayDriver);
1217 if(!result && fallBack && fbDriver)
1219 if(!SwitchMode(fbFullScreen, fbDriver, fbResolution, fbColorDepth, fbRefreshRate, null, false))
1220 Log("Error falling back to previous video mode.\n");
1225 bool ProcessFileNotifications()
1227 bool activity = false;
1228 FileMonitor monitor, next;
1229 static int reentrant = 0;
1231 // printf("[%d] Waiting in ProcessFileNotifications for fileMonitor Mutex %x...\n", GetCurrentThreadID(), globalSystem.fileMonitorMutex);
1232 globalSystem.fileMonitorMutex.Wait();
1234 for(monitor = globalSystem.fileMonitors.first; monitor; monitor = next)
1238 next = monitor.next;
1241 if(!monitor.reentrant && !monitor.toBeFreed)
1243 monitor.reentrant = true;
1244 while((notify = monitor.fileNotifies.first))
1246 monitor.fileNotifies.Remove(notify);
1250 if(monitor.directory)
1252 if(!monitor.OnDirNotify(monitor.data, notify.action, notify.fileName, notify.param))
1253 monitor.StopMonitoring();
1257 if(!monitor.OnFileNotify(monitor.data, notify.action, notify.param))
1258 monitor.StopMonitoring();
1261 monitor.reentrant = false;
1267 monitor.reentrant = false;
1274 for(monitor = globalSystem.fileMonitors.first; monitor; monitor = next)
1276 next = monitor.next;
1277 if(monitor.toBeFreed && !monitor.reentrant)
1278 monitor.FreeMonitor();
1281 // printf("[%d] Releasing in ProcessFileNotifications fileMonitor Mutex %x...\n", GetCurrentThreadID(), globalSystem.fileMonitorMutex);
1282 globalSystem.fileMonitorMutex.Release();
1289 #if defined(__unix__)
1291 XLockDisplay(xGlobalDisplay);
1297 #if defined(__unix__)
1299 XUnlockDisplay(xGlobalDisplay);
1301 lockMutex.Release();
1304 Cursor GetCursor(SystemCursor cursor)
1306 return systemCursors[cursor];
1309 bool GetKeyState(Key key)
1311 return interfaceDriver.GetKeyState(key);
1314 bool GetMouseState(MouseButtons * buttons, int * x, int * y)
1316 return interfaceDriver.GetMouseState(buttons, x, y);
1320 property char * appName
1324 strcpy(appName, value);
1325 if(desktop) desktop.text = appName;
1329 return (char *)(this ? appName : null);
1332 property Semaphore semaphore { get { return globalSystem.eventSemaphore; } };
1333 property bool alwaysEmptyInput{ set { processAll = value; } get { return processAll; } };
1334 property bool fullScreen
1338 SwitchMode(value, defaultDisplayDriver, resolution,
1339 pixelFormat, refreshRate, currentSkin ? currentSkin.name : null, true);
1341 get { return this ? fullScreen : false; }
1343 property char * driver
1347 SwitchMode( fullScreen, value, resolution, pixelFormat, refreshRate,
1348 currentSkin ? currentSkin.name : null, true);
1350 get { return this ? defaultDisplayDriver : null; }
1352 property Resolution resolution
1356 SwitchMode(fullScreen, defaultDisplayDriver, value, pixelFormat, refreshRate,
1357 currentSkin ? currentSkin.name : null, true);
1359 get { return this ? resolution : 0; }
1361 property PixelFormat pixelFormat
1365 SwitchMode(fullScreen, defaultDisplayDriver, resolution,
1366 pixelFormat, refreshRate, currentSkin ? currentSkin.name : null, true);
1368 get { return this ? pixelFormat : 0; }
1370 property int refreshRate
1374 SwitchMode(fullScreen, defaultDisplayDriver, resolution,
1375 pixelFormat, refreshRate, currentSkin ? currentSkin.name : null, true);
1377 get { return this ? refreshRate : 0; }
1379 property char * skin
1381 set { SelectSkin(value); }
1382 get { return (this && currentSkin) ? currentSkin.name : null; }
1384 property bool textMode
1386 set { textMode = value; } // TODO: Implement switching
1387 get { return this ? textMode : false; }
1389 property Window desktop { get { return this ? desktop : null; } };
1390 property char ** drivers { get { return null; } };
1391 property char ** skins { get { return null; } };
1392 property subclass(Skin) currentSkin { get { return this ? currentSkin : null; } };
1393 property int numDrivers { get { return 0; } };
1394 property int numSkins { get { return 0; } };
1395 property uint timerResolution
1397 set { timerResolution = value; if(interfaceDriver) interfaceDriver.SetTimerResolution(value); }