16a0a0a80SAxel Dörfler /* 2bb86786aSClemens Zeidler * Copyright 2001-2010, Haiku. 36a0a0a80SAxel Dörfler * Distributed under the terms of the MIT License. 46a0a0a80SAxel Dörfler * 56a0a0a80SAxel Dörfler * Authors: 66a0a0a80SAxel Dörfler * Adrian Oanca <adioanca@cotty.iren.ro> 76a0a0a80SAxel Dörfler * Stephan Aßmus <superstippi@gmx.de> 8926e63c8SBrecht Machiels * Axel Dörfler <axeld@pinc-software.de> 9b09e2f6fSStephan Aßmus * Andrej Spielmann, <andrej.spielmann@seh.ox.ac.uk> 10926e63c8SBrecht Machiels * Brecht Machiels <brecht@mos6581.org> 11bb86786aSClemens Zeidler * Clemens Zeidler <haiku@clemens-zeidler.de> 126a0a0a80SAxel Dörfler */ 1327adb969SAxel Dörfler #ifndef DESKTOP_H 1427adb969SAxel Dörfler #define DESKTOP_H 1533bbe223SAxel Dörfler 1608f35604SAxel Dörfler 17b6ba2290SClemens Zeidler #include <Autolock.h> 18b6ba2290SClemens Zeidler #include <InterfaceDefs.h> 19b6ba2290SClemens Zeidler #include <List.h> 20b6ba2290SClemens Zeidler #include <Menu.h> 21b6ba2290SClemens Zeidler #include <ObjectList.h> 22b6ba2290SClemens Zeidler #include <Region.h> 23b6ba2290SClemens Zeidler #include <Window.h> 24b6ba2290SClemens Zeidler 253ddebe7eSMichael Lotz #include "CursorManager.h" 26860dfc9aSClemens Zeidler #include "DesktopListener.h" 27ace2d5eeSStephan Aßmus #include "DesktopSettings.h" 2808f35604SAxel Dörfler #include "EventDispatcher.h" 29ace2d5eeSStephan Aßmus #include "MessageLooper.h" 30953d895eSAxel Dörfler #include "Screen.h" 31fd5bec1eSAxel Dörfler #include "ScreenManager.h" 32ace2d5eeSStephan Aßmus #include "ServerCursor.h" 33fd5bec1eSAxel Dörfler #include "VirtualScreen.h" 34e83820edSAxel Dörfler #include "WindowList.h" 3527adb969SAxel Dörfler #include "Workspace.h" 365ca8477eSAxel Dörfler #include "WorkspacePrivate.h" 37fd5bec1eSAxel Dörfler 3823e00a25SAxel Dörfler 3939c9925fSStephan Aßmus #define USE_MULTI_LOCKER 1 40e83820edSAxel Dörfler 41e83820edSAxel Dörfler #if USE_MULTI_LOCKER 42e83820edSAxel Dörfler # include "MultiLocker.h" 43e83820edSAxel Dörfler #else 44e83820edSAxel Dörfler # include <Locker.h> 45e83820edSAxel Dörfler #endif 4633bbe223SAxel Dörfler 470eed9183SAxel Dörfler 483dcb3b07SStephan Aßmus class BMessage; 496a0a0a80SAxel Dörfler 5058468dfeSStephan Aßmus class DrawingEngine; 513dcb3b07SStephan Aßmus class HWInterface; 52e83820edSAxel Dörfler class ServerApp; 53953d895eSAxel Dörfler class Window; 54953d895eSAxel Dörfler class WorkspacesView; 556d5488e1SAxel Dörfler struct server_read_only_memory; 5633bbe223SAxel Dörfler 576a0a0a80SAxel Dörfler namespace BPrivate { 586a0a0a80SAxel Dörfler class LinkSender; 596a0a0a80SAxel Dörfler }; 606a0a0a80SAxel Dörfler 610eed9183SAxel Dörfler 62860dfc9aSClemens Zeidler class Desktop : public DesktopObservable, public MessageLooper, 63860dfc9aSClemens Zeidler public ScreenOwner { 6433bbe223SAxel Dörfler public: 6568667bf4SMichael Lotz Desktop(uid_t userID, const char* targetScreen); 663dcb3b07SStephan Aßmus virtual ~Desktop(); 673dcb3b07SStephan Aßmus 68d6734c08SClemens Zeidler void RegisterListener(DesktopListener* listener); 69d6734c08SClemens Zeidler 706d5488e1SAxel Dörfler status_t Init(); 7136deda69SAxel Dörfler 7236deda69SAxel Dörfler uid_t UserID() const { return fUserID; } 7368667bf4SMichael Lotz const char* TargetScreen() { return fTargetScreen; } 74770c05d6SAxel Dörfler virtual port_id MessagePort() const { return fMessagePort; } 759dbce7a4SAxel Dörfler area_id SharedReadOnlyArea() const 769dbce7a4SAxel Dörfler { return fSharedReadOnlyArea; } 77770c05d6SAxel Dörfler 78f7598223SAxel Dörfler ::EventDispatcher& EventDispatcher() { return fEventDispatcher; } 796c17d025SAxel Dörfler 80770c05d6SAxel Dörfler void BroadcastToAllApps(int32 code); 810a3f410fSAxel Dörfler void BroadcastToAllWindows(int32 code); 8233bbe223SAxel Dörfler 83860dfc9aSClemens Zeidler void KeyEvent(uint32 what, int32 key, 84860dfc9aSClemens Zeidler int32 modifiers); 85cc93fbbbSAxel Dörfler // Locking 86cc93fbbbSAxel Dörfler #if USE_MULTI_LOCKER 87cc93fbbbSAxel Dörfler bool LockSingleWindow() 88cc93fbbbSAxel Dörfler { return fWindowLock.ReadLock(); } 89cc93fbbbSAxel Dörfler void UnlockSingleWindow() 90cc93fbbbSAxel Dörfler { fWindowLock.ReadUnlock(); } 91cc93fbbbSAxel Dörfler 92cc93fbbbSAxel Dörfler bool LockAllWindows() 93cc93fbbbSAxel Dörfler { return fWindowLock.WriteLock(); } 94cc93fbbbSAxel Dörfler void UnlockAllWindows() 95cc93fbbbSAxel Dörfler { fWindowLock.WriteUnlock(); } 96cc93fbbbSAxel Dörfler 9778ca6157SAxel Dörfler const MultiLocker& WindowLocker() { return fWindowLock; } 98cc93fbbbSAxel Dörfler #else // USE_MULTI_LOCKER 99cc93fbbbSAxel Dörfler bool LockSingleWindow() 100cc93fbbbSAxel Dörfler { return fWindowLock.Lock(); } 101cc93fbbbSAxel Dörfler void UnlockSingleWindow() 102cc93fbbbSAxel Dörfler { fWindowLock.Unlock(); } 103cc93fbbbSAxel Dörfler 104cc93fbbbSAxel Dörfler bool LockAllWindows() 105cc93fbbbSAxel Dörfler { return fWindowLock.Lock(); } 106cc93fbbbSAxel Dörfler void UnlockAllWindows() 107cc93fbbbSAxel Dörfler { fWindowLock.Unlock(); } 108cc93fbbbSAxel Dörfler #endif // USE_MULTI_LOCKER 109cc93fbbbSAxel Dörfler 1100eed9183SAxel Dörfler // Mouse and cursor methods 11133bbe223SAxel Dörfler 112195e980eSAxel Dörfler void SetCursor(ServerCursor* cursor); 113ace2d5eeSStephan Aßmus ServerCursorReference Cursor() const; 1144d1c4228SStephan Aßmus void SetLastMouseState(const BPoint& position, 11521b40eddSStephan Aßmus int32 buttons, Window* windowUnderMouse); 1164d1c4228SStephan Aßmus // for use by the mouse filter only 1174d1c4228SStephan Aßmus // both mouse position calls require 1184d1c4228SStephan Aßmus // the Desktop object to be locked 1194d1c4228SStephan Aßmus // already 1204d1c4228SStephan Aßmus void GetLastMouseState(BPoint* position, 1214d1c4228SStephan Aßmus int32* buttons) const; 1224d1c4228SStephan Aßmus // for use by ServerWindow 1230eed9183SAxel Dörfler 1240eed9183SAxel Dörfler CursorManager& GetCursorManager() { return fCursorManager; } 1250eed9183SAxel Dörfler 126fe7f167dSAxel Dörfler // Screen and drawing related methods 127fe7f167dSAxel Dörfler 1280eed9183SAxel Dörfler status_t SetScreenMode(int32 workspace, int32 id, 1290eed9183SAxel Dörfler const display_mode& mode, bool makeDefault); 1300eed9183SAxel Dörfler status_t GetScreenMode(int32 workspace, int32 id, 1310eed9183SAxel Dörfler display_mode& mode); 132e18224cdSAxel Dörfler status_t GetScreenFrame(int32 workspace, int32 id, 133e18224cdSAxel Dörfler BRect& frame); 1345e3f4c41SAxel Dörfler void RevertScreenModes(uint32 workspaces); 1350eed9183SAxel Dörfler 13678ca6157SAxel Dörfler MultiLocker& ScreenLocker() { return fScreenLock; } 13778ca6157SAxel Dörfler 1389fe35223SAxel Dörfler status_t LockDirectScreen(team_id team); 1399fe35223SAxel Dörfler status_t UnlockDirectScreen(team_id team); 1409fe35223SAxel Dörfler 1415e3f4c41SAxel Dörfler const ::VirtualScreen& VirtualScreen() const 1425e3f4c41SAxel Dörfler { return fVirtualScreen; } 14327adb969SAxel Dörfler DrawingEngine* GetDrawingEngine() const 14458468dfeSStephan Aßmus { return fVirtualScreen.DrawingEngine(); } 14527adb969SAxel Dörfler ::HWInterface* HWInterface() const 146fd5bec1eSAxel Dörfler { return fVirtualScreen.HWInterface(); } 14794fa2bd2SAdi Oanca 148*5483fa4eSClemens Zeidler void RebuildAndRedrawAfterWindowChange( 149*5483fa4eSClemens Zeidler Window* window, BRegion& dirty); 150*5483fa4eSClemens Zeidler // the window lock must be held when calling 151*5483fa4eSClemens Zeidler // this function 152*5483fa4eSClemens Zeidler 1530eed9183SAxel Dörfler // ScreenOwner implementation 1545e3f4c41SAxel Dörfler virtual void ScreenRemoved(Screen* screen) {} 1555e3f4c41SAxel Dörfler virtual void ScreenAdded(Screen* screen) {} 1565e3f4c41SAxel Dörfler virtual bool ReleaseScreen(Screen* screen) { return false; } 1570eed9183SAxel Dörfler 15827adb969SAxel Dörfler // Workspace methods 15927adb969SAxel Dörfler 16047212dddSAxel Dörfler void SetWorkspaceAsync(int32 index, 16147212dddSAxel Dörfler bool moveFocusWindow = false); 16247212dddSAxel Dörfler void SetWorkspace(int32 index, 16347212dddSAxel Dörfler bool moveFocusWindow = false); 16427adb969SAxel Dörfler int32 CurrentWorkspace() 16527adb969SAxel Dörfler { return fCurrentWorkspace; } 1665ca8477eSAxel Dörfler Workspace::Private& WorkspaceAt(int32 index) 16727adb969SAxel Dörfler { return fWorkspaces[index]; } 16869f9a367SAxel Dörfler status_t SetWorkspacesLayout(int32 columns, int32 rows); 16927c43a2dSRene Gollent BRect WorkspaceFrame(int32 index) const; 17027adb969SAxel Dörfler 171cc93fbbbSAxel Dörfler void StoreWorkspaceConfiguration(int32 index); 172cc93fbbbSAxel Dörfler 173cc93fbbbSAxel Dörfler void AddWorkspacesView(WorkspacesView* view); 174cc93fbbbSAxel Dörfler void RemoveWorkspacesView(WorkspacesView* view); 175cc93fbbbSAxel Dörfler 176953d895eSAxel Dörfler // Window methods 17727adb969SAxel Dörfler 178926e63c8SBrecht Machiels void SelectWindow(Window* window); 179953d895eSAxel Dörfler void ActivateWindow(Window* window); 180953d895eSAxel Dörfler void SendWindowBehind(Window* window, 181953d895eSAxel Dörfler Window* behindOf = NULL); 18227adb969SAxel Dörfler 183953d895eSAxel Dörfler void ShowWindow(Window* window); 184953d895eSAxel Dörfler void HideWindow(Window* window); 185860dfc9aSClemens Zeidler void MinimizeWindow(Window* window, bool minimize); 18615918e4fSAxel Dörfler 187953d895eSAxel Dörfler void MoveWindowBy(Window* window, float x, float y, 18814fe11cfSAxel Dörfler int32 workspace = -1); 1899dbce7a4SAxel Dörfler void ResizeWindowBy(Window* window, float x, 1909dbce7a4SAxel Dörfler float y); 1919dbce7a4SAxel Dörfler bool SetWindowTabLocation(Window* window, 1929dbce7a4SAxel Dörfler float location); 193953d895eSAxel Dörfler bool SetWindowDecoratorSettings(Window* window, 194b30e9021SStephan Aßmus const BMessage& settings); 19519d801a6SAxel Dörfler 196953d895eSAxel Dörfler void SetWindowWorkspaces(Window* window, 197a631158aSAxel Dörfler uint32 workspaces); 19827adb969SAxel Dörfler 199953d895eSAxel Dörfler void AddWindow(Window* window); 200953d895eSAxel Dörfler void RemoveWindow(Window* window); 20157be2866SAxel Dörfler 202953d895eSAxel Dörfler bool AddWindowToSubset(Window* subset, 203953d895eSAxel Dörfler Window* window); 204953d895eSAxel Dörfler void RemoveWindowFromSubset(Window* subset, 205953d895eSAxel Dörfler Window* window); 20634227d2cSAxel Dörfler 2070a3f410fSAxel Dörfler void FontsChanged(Window* window); 2080a3f410fSAxel Dörfler 209953d895eSAxel Dörfler void SetWindowLook(Window* window, window_look look); 210953d895eSAxel Dörfler void SetWindowFeel(Window* window, window_feel feel); 211953d895eSAxel Dörfler void SetWindowFlags(Window* window, uint32 flags); 2129dbce7a4SAxel Dörfler void SetWindowTitle(Window* window, 2139dbce7a4SAxel Dörfler const char* title); 21433bbe223SAxel Dörfler 215953d895eSAxel Dörfler Window* FocusWindow() const { return fFocus; } 216953d895eSAxel Dörfler Window* FrontWindow() const { return fFront; } 217953d895eSAxel Dörfler Window* BackWindow() const { return fBack; } 218e83820edSAxel Dörfler 219953d895eSAxel Dörfler Window* WindowAt(BPoint where); 220e83820edSAxel Dörfler 2219dbce7a4SAxel Dörfler Window* MouseEventWindow() const 2229dbce7a4SAxel Dörfler { return fMouseEventWindow; } 223953d895eSAxel Dörfler void SetMouseEventWindow(Window* window); 224e83820edSAxel Dörfler 2259dbce7a4SAxel Dörfler void SetViewUnderMouse(const Window* window, 2269dbce7a4SAxel Dörfler int32 viewToken); 227953d895eSAxel Dörfler int32 ViewUnderMouse(const Window* window); 2281e766d46SAxel Dörfler 22907dc2c69SAxel Dörfler EventTarget* KeyboardEventTarget(); 230cc93fbbbSAxel Dörfler 231cc93fbbbSAxel Dörfler void SetFocusWindow(Window* window = NULL); 23221b40eddSStephan Aßmus void SetFocusLocked(const Window* window); 233e83820edSAxel Dörfler 234953d895eSAxel Dörfler Window* FindWindowByClientToken(int32 token, 235953d895eSAxel Dörfler team_id teamID); 23695530739SAxel Dörfler EventTarget* FindTarget(BMessenger& messenger); 2376a0a0a80SAxel Dörfler 238e83820edSAxel Dörfler void MarkDirty(BRegion& region); 239b09e2f6fSStephan Aßmus void Redraw(); 240cc93fbbbSAxel Dörfler void RedrawBackground(); 241e83820edSAxel Dörfler 242b6ba2290SClemens Zeidler void ReloadDecor(); 243bb86786aSClemens Zeidler 244e83820edSAxel Dörfler BRegion& BackgroundRegion() 245e83820edSAxel Dörfler { return fBackgroundRegion; } 24633bbe223SAxel Dörfler 247f877af82SAxel Dörfler void MinimizeApplication(team_id team); 248f877af82SAxel Dörfler void BringApplicationToFront(team_id team); 249bfe69873SAxel Dörfler void WindowAction(int32 windowToken, int32 action); 250f877af82SAxel Dörfler 25127adb969SAxel Dörfler void WriteWindowList(team_id team, 25227adb969SAxel Dörfler BPrivate::LinkSender& sender); 25327adb969SAxel Dörfler void WriteWindowInfo(int32 serverToken, 25427adb969SAxel Dörfler BPrivate::LinkSender& sender); 255ae0606beSAxel Dörfler void WriteApplicationOrder(int32 workspace, 256ae0606beSAxel Dörfler BPrivate::LinkSender& sender); 257ae0606beSAxel Dörfler void WriteWindowOrder(int32 workspace, 258ae0606beSAxel Dörfler BPrivate::LinkSender& sender); 25933bbe223SAxel Dörfler 260860dfc9aSClemens Zeidler WindowList& CurrentWindows(); 261d6734c08SClemens Zeidler WindowList& AllWindows(); 262860dfc9aSClemens Zeidler 26333bbe223SAxel Dörfler private: 2640265102fSClemens Zeidler WindowList& _Windows(int32 index); 2650265102fSClemens Zeidler 2666869c8a5SRyan Leavengood void _LaunchInputServer(); 267cc93fbbbSAxel Dörfler void _GetLooperName(char* name, size_t size); 268cc93fbbbSAxel Dörfler void _PrepareQuit(); 269cc93fbbbSAxel Dörfler void _DispatchMessage(int32 code, 270cc93fbbbSAxel Dörfler BPrivate::LinkReceiver &link); 271e83820edSAxel Dörfler 27234227d2cSAxel Dörfler void _UpdateFloating(int32 previousWorkspace = -1, 273d479fa7aSAxel Dörfler int32 nextWorkspace = -1, 274953d895eSAxel Dörfler Window* mouseEventWindow = NULL); 275e83820edSAxel Dörfler void _UpdateBack(); 27634227d2cSAxel Dörfler void _UpdateFront(bool updateFloating = true); 27734227d2cSAxel Dörfler void _UpdateFronts(bool updateFloating = true); 278953d895eSAxel Dörfler bool _WindowHasModal(Window* window); 279e83820edSAxel Dörfler 280953d895eSAxel Dörfler void _WindowChanged(Window* window); 281953d895eSAxel Dörfler void _WindowRemoved(Window* window); 282ce8c4d79SAxel Dörfler 283cc93fbbbSAxel Dörfler void _ShowWindow(Window* window, 284cc93fbbbSAxel Dörfler bool affectsOtherWindows = true); 285cc93fbbbSAxel Dörfler void _HideWindow(Window* window); 2865f2edc0fSAxel Dörfler 287cc93fbbbSAxel Dörfler void _UpdateSubsetWorkspaces(Window* window, 288cc93fbbbSAxel Dörfler int32 previousIndex = -1, 289cc93fbbbSAxel Dörfler int32 newIndex = -1); 290cc93fbbbSAxel Dörfler void _ChangeWindowWorkspaces(Window* window, 291cc93fbbbSAxel Dörfler uint32 oldWorkspaces, uint32 newWorkspaces); 292cc93fbbbSAxel Dörfler void _BringWindowsToFront(WindowList& windows, 293cc93fbbbSAxel Dörfler int32 list, bool wereVisible); 294cc93fbbbSAxel Dörfler Window* _LastFocusSubsetWindow(Window* window); 295cc93fbbbSAxel Dörfler void _SendFakeMouseMoved(Window* window = NULL); 296cc93fbbbSAxel Dörfler 29778ca6157SAxel Dörfler Screen* _DetermineScreenFor(BRect frame); 298cc93fbbbSAxel Dörfler void _RebuildClippingForAllWindows( 299cc93fbbbSAxel Dörfler BRegion& stillAvailableOnScreen); 300cc93fbbbSAxel Dörfler void _TriggerWindowRedrawing( 301cc93fbbbSAxel Dörfler BRegion& newDirtyRegion); 302cc93fbbbSAxel Dörfler void _SetBackground(BRegion& background); 303cc93fbbbSAxel Dörfler 304cc93fbbbSAxel Dörfler status_t _ActivateApp(team_id team); 305cc93fbbbSAxel Dörfler 30678ca6157SAxel Dörfler void _SuspendDirectFrameBufferAccess(); 30778ca6157SAxel Dörfler void _ResumeDirectFrameBufferAccess(); 30878ca6157SAxel Dörfler 309cc93fbbbSAxel Dörfler void _ScreenChanged(Screen* screen); 310cc93fbbbSAxel Dörfler void _SetCurrentWorkspaceConfiguration(); 31147212dddSAxel Dörfler void _SetWorkspace(int32 index, 31247212dddSAxel Dörfler bool moveFocusWindow = false); 313e83820edSAxel Dörfler 3145f2edc0fSAxel Dörfler private: 315ef8810f2SAxel Dörfler friend class DesktopSettings; 316a17c3a48SAxel Dörfler friend class LockedDesktopSettings; 317ef8810f2SAxel Dörfler 31836deda69SAxel Dörfler uid_t fUserID; 31968667bf4SMichael Lotz const char* fTargetScreen; 320fd5bec1eSAxel Dörfler ::VirtualScreen fVirtualScreen; 321a17c3a48SAxel Dörfler DesktopSettingsPrivate* fSettings; 3225f2edc0fSAxel Dörfler port_id fMessagePort; 323f7598223SAxel Dörfler ::EventDispatcher fEventDispatcher; 3246c17d025SAxel Dörfler port_id fInputPort; 3256d5488e1SAxel Dörfler area_id fSharedReadOnlyArea; 3266d5488e1SAxel Dörfler server_read_only_memory* fServerReadOnlyMemory; 327770c05d6SAxel Dörfler 328e83820edSAxel Dörfler BLocker fApplicationsLock; 329e83820edSAxel Dörfler BObjectList<ServerApp> fApplications; 330770c05d6SAxel Dörfler 331770c05d6SAxel Dörfler sem_id fShutdownSemaphore; 332770c05d6SAxel Dörfler int32 fShutdownCount; 333770c05d6SAxel Dörfler 33482081c70SJérôme Duval ::Workspace::Private fWorkspaces[kMaxWorkspaces]; 33578ca6157SAxel Dörfler MultiLocker fScreenLock; 3369fe35223SAxel Dörfler BLocker fDirectScreenLock; 3379fe35223SAxel Dörfler team_id fDirectScreenTeam; 33827adb969SAxel Dörfler int32 fCurrentWorkspace; 3394932bc5eSAxel Dörfler int32 fPreviousWorkspace; 34027adb969SAxel Dörfler 341e83820edSAxel Dörfler WindowList fAllWindows; 34234227d2cSAxel Dörfler WindowList fSubsetWindows; 343d01879e5SAxel Dörfler WindowList fFocusList; 3440b63cc93SAxel Dörfler Window* fLastWorkspaceFocus[kMaxWorkspaces]; 345d8ebe612SAxel Dörfler 346953d895eSAxel Dörfler BObjectList<WorkspacesView> fWorkspacesViews; 347d8ebe612SAxel Dörfler BLocker fWorkspacesLock; 34833bbe223SAxel Dörfler 3493ddebe7eSMichael Lotz CursorManager fCursorManager; 350e83820edSAxel Dörfler 351e83820edSAxel Dörfler #if USE_MULTI_LOCKER 352e83820edSAxel Dörfler MultiLocker fWindowLock; 353e83820edSAxel Dörfler #else 354e83820edSAxel Dörfler BLocker fWindowLock; 355e83820edSAxel Dörfler #endif 356e83820edSAxel Dörfler 357e83820edSAxel Dörfler BRegion fBackgroundRegion; 358e83820edSAxel Dörfler BRegion fScreenRegion; 359e83820edSAxel Dörfler 360953d895eSAxel Dörfler Window* fMouseEventWindow; 361953d895eSAxel Dörfler const Window* fWindowUnderMouse; 36221b40eddSStephan Aßmus const Window* fLockedFocusWindow; 3631e766d46SAxel Dörfler int32 fViewUnderMouse; 3644d1c4228SStephan Aßmus BPoint fLastMousePosition; 3654d1c4228SStephan Aßmus int32 fLastMouseButtons; 3661e766d46SAxel Dörfler 367953d895eSAxel Dörfler Window* fFocus; 368953d895eSAxel Dörfler Window* fFront; 369953d895eSAxel Dörfler Window* fBack; 37033bbe223SAxel Dörfler }; 37133bbe223SAxel Dörfler 37227adb969SAxel Dörfler #endif // DESKTOP_H 373