#ifndef DESKTOP_H
#define DESKTOP_H
#include <AutoDeleter.h>
#include <Autolock.h>
#include <InterfaceDefs.h>
#include <List.h>
#include <Menu.h>
#include <ObjectList.h>
#include <Region.h>
#include <String.h>
#include <Window.h>
#include <ServerProtocolStructs.h>
#include "CursorManager.h"
#include "DelayedMessage.h"
#include "DesktopListener.h"
#include "DesktopSettings.h"
#include "EventDispatcher.h"
#include "MessageLooper.h"
#include "MultiLocker.h"
#include "Screen.h"
#include "ScreenManager.h"
#include "ServerCursor.h"
#include "StackAndTile.h"
#include "VirtualScreen.h"
#include "WindowList.h"
#include "Workspace.h"
#include "WorkspacePrivate.h"
class BMessage;
class DecorAddOn;
class DrawingEngine;
class HWInterface;
class ServerApp;
class Window;
class WorkspacesView;
struct server_read_only_memory;
namespace BPrivate {
class LinkSender;
};
class Desktop : public DesktopObservable, public MessageLooper,
public ScreenOwner {
public:
Desktop(uid_t userID,
const char* targetScreen);
virtual ~Desktop();
void RegisterListener(DesktopListener* listener);
status_t Init();
uid_t UserID() const { return fUserID; }
const char* TargetScreen() { return fTargetScreen; }
virtual port_id MessagePort() const { return fMessagePort; }
area_id SharedReadOnlyArea() const
{ return fSharedReadOnlyArea; }
::EventDispatcher& EventDispatcher() { return fEventDispatcher; }
void BroadcastToAllApps(int32 code);
void BroadcastToAllWindows(int32 code);
int32 GetAllWindowTargets(DelayedMessage& message);
int32 GetAllAppTargets(DelayedMessage& message);
filter_result KeyEvent(uint32 what, int32 key,
int32 modifiers);
bool LockSingleWindow()
{ return fWindowLock.ReadLock(); }
void UnlockSingleWindow()
{ fWindowLock.ReadUnlock(); }
bool LockAllWindows()
{ return fWindowLock.WriteLock(); }
void UnlockAllWindows()
{ fWindowLock.WriteUnlock(); }
const MultiLocker& WindowLocker() { return fWindowLock; }
void SetCursor(ServerCursor* cursor);
ServerCursorReference Cursor() const;
void SetManagementCursor(ServerCursor* newCursor);
void SetLastMouseState(const BPoint& position,
int32 buttons, Window* windowUnderMouse);
void GetLastMouseState(BPoint* position,
int32* buttons) const;
CursorManager& GetCursorManager() { return fCursorManager; }
status_t SetScreenMode(int32 workspace, int32 id,
const display_mode& mode, bool makeDefault);
status_t GetScreenMode(int32 workspace, int32 id,
display_mode& mode);
status_t GetScreenFrame(int32 workspace, int32 id,
BRect& frame);
void RevertScreenModes(uint32 workspaces);
status_t SetBrightness(int32 id, float brightness);
MultiLocker& ScreenLocker() { return fScreenLock; }
status_t LockDirectScreen(team_id team);
status_t UnlockDirectScreen(team_id team);
const ::VirtualScreen& VirtualScreen() const
{ return fVirtualScreen; }
DrawingEngine* GetDrawingEngine() const
{ return fVirtualScreen.DrawingEngine(); }
::HWInterface* HWInterface() const
{ return fVirtualScreen.HWInterface(); }
void RebuildAndRedrawAfterWindowChange(
Window* window, BRegion& dirty);
virtual void ScreenRemoved(Screen* screen) {}
virtual void ScreenAdded(Screen* screen) {}
virtual void ScreenChanged(Screen* screen);
virtual bool ReleaseScreen(Screen* screen) { return false; }
void SetWorkspaceAsync(int32 index,
bool moveFocusWindow = false);
void SetWorkspace(int32 index,
bool moveFocusWindow = false);
int32 CurrentWorkspace()
{ return fCurrentWorkspace; }
Workspace::Private& WorkspaceAt(int32 index)
{ return fWorkspaces[index]; }
status_t SetWorkspacesLayout(int32 columns, int32 rows);
BRect WorkspaceFrame(int32 index) const;
void StoreWorkspaceConfiguration(int32 index);
void AddWorkspacesView(WorkspacesView* view);
void RemoveWorkspacesView(WorkspacesView* view);
void SelectWindow(Window* window);
void ActivateWindow(Window* window);
void SendWindowBehind(Window* window,
Window* behindOf = NULL,
bool sendStack = true);
void ShowWindow(Window* window);
void HideWindow(Window* window,
bool fromMinimize = false);
void MinimizeWindow(Window* window, bool minimize);
void MoveWindowBy(Window* window, float x, float y,
int32 workspace = -1);
void ResizeWindowBy(Window* window, float x,
float y);
void SetWindowOutlinesDelta(Window* window,
BPoint delta);
bool SetWindowTabLocation(Window* window,
float location, bool isShifting);
bool SetWindowDecoratorSettings(Window* window,
const BMessage& settings);
void SetWindowWorkspaces(Window* window,
uint32 workspaces);
void AddWindow(Window* window);
void RemoveWindow(Window* window);
bool AddWindowToSubset(Window* subset,
Window* window);
void RemoveWindowFromSubset(Window* subset,
Window* window);
void FontsChanged(Window* window);
void ColorUpdated(Window* window, color_which which,
rgb_color color);
void SetWindowLook(Window* window, window_look look);
void SetWindowFeel(Window* window, window_feel feel);
void SetWindowFlags(Window* window, uint32 flags);
void SetWindowTitle(Window* window,
const char* title);
Window* FocusWindow() const { return fFocus; }
Window* FrontWindow() const { return fFront; }
Window* BackWindow() const { return fBack; }
Window* WindowAt(BPoint where);
Window* MouseEventWindow() const
{ return fMouseEventWindow; }
void SetMouseEventWindow(Window* window);
void SetViewUnderMouse(const Window* window,
int32 viewToken);
int32 ViewUnderMouse(const Window* window);
EventTarget* KeyboardEventTarget();
void SetFocusWindow(Window* window = NULL);
void SetFocusLocked(const Window* window);
Window* FindWindowByClientToken(int32 token,
team_id teamID);
EventTarget* FindTarget(BMessenger& messenger);
void MarkDirty(BRegion& dirtyRegion, BRegion& exposeRegion);
void MarkDirty(BRegion& region)
{ return MarkDirty(region, region); }
void Redraw();
void RedrawBackground();
bool ReloadDecor(DecorAddOn* oldDecor);
BRegion& BackgroundRegion()
{ return fBackgroundRegion; }
void MinimizeApplication(team_id team);
void BringApplicationToFront(team_id team);
void WindowAction(int32 windowToken, int32 action);
void WriteWindowList(team_id team,
BPrivate::LinkSender& sender);
void WriteWindowInfo(int32 serverToken,
BPrivate::LinkSender& sender);
void WriteApplicationOrder(int32 workspace,
BPrivate::LinkSender& sender);
void WriteWindowOrder(int32 workspace,
BPrivate::LinkSender& sender);
WindowList& CurrentWindows();
WindowList& AllWindows();
Window* WindowForClientLooperPort(port_id port);
StackAndTile* GetStackAndTile() { return &fStackAndTile; }
private:
WindowList& _Windows(int32 index);
void _FlushPendingColors();
void _LaunchInputServer();
void _GetLooperName(char* name, size_t size);
void _PrepareQuit();
void _DispatchMessage(int32 code,
BPrivate::LinkReceiver &link);
void _UpdateFloating(int32 previousWorkspace = -1,
int32 nextWorkspace = -1,
Window* mouseEventWindow = NULL);
void _UpdateBack();
void _UpdateFront(bool updateFloating = true);
void _UpdateFronts(bool updateFloating = true);
bool _WindowHasModal(Window* window) const;
bool _WindowCanHaveFocus(Window* window) const;
void _WindowChanged(Window* window);
void _WindowRemoved(Window* window);
void _ShowWindow(Window* window,
bool affectsOtherWindows = true);
void _HideWindow(Window* window);
void _UpdateSubsetWorkspaces(Window* window,
int32 previousIndex = -1,
int32 newIndex = -1);
void _ChangeWindowWorkspaces(Window* window,
uint32 oldWorkspaces, uint32 newWorkspaces);
void _BringWindowsToFront(WindowList& windows,
int32 list, bool wereVisible);
Window* _LastFocusSubsetWindow(Window* window);
bool _CheckSendFakeMouseMoved(
const Window* lastWindowUnderMouse);
void _SendFakeMouseMoved(Window* window = NULL);
Screen* _DetermineScreenFor(BRect frame);
void _RebuildClippingForAllWindows(
BRegion& stillAvailableOnScreen);
void _TriggerWindowRedrawing(
BRegion& dirtyRegion, BRegion& exposeRegion);
void _SetBackground(BRegion& background);
status_t _ActivateApp(team_id team);
void _SuspendDirectFrameBufferAccess();
void _ResumeDirectFrameBufferAccess();
void _ScreenChanged(Screen* screen);
void _SetCurrentWorkspaceConfiguration();
void _SetWorkspace(int32 index,
bool moveFocusWindow = false);
private:
friend class DesktopSettings;
friend class LockedDesktopSettings;
uid_t fUserID;
char* fTargetScreen;
::VirtualScreen fVirtualScreen;
ObjectDeleter<DesktopSettingsPrivate>
fSettings;
port_id fMessagePort;
::EventDispatcher fEventDispatcher;
area_id fSharedReadOnlyArea;
server_read_only_memory* fServerReadOnlyMemory;
BLocker fApplicationsLock;
BObjectList<ServerApp> fApplications;
sem_id fShutdownSemaphore;
int32 fShutdownCount;
::Workspace::Private fWorkspaces[kMaxWorkspaces];
MultiLocker fScreenLock;
BLocker fDirectScreenLock;
team_id fDirectScreenTeam;
int32 fCurrentWorkspace;
int32 fPreviousWorkspace;
WindowList fAllWindows;
WindowList fSubsetWindows;
WindowList fFocusList;
Window* fLastWorkspaceFocus[kMaxWorkspaces];
BObjectList<WorkspacesView> fWorkspacesViews;
BLocker fWorkspacesLock;
CursorManager fCursorManager;
ServerCursorReference fCursor;
ServerCursorReference fManagementCursor;
MultiLocker fWindowLock;
BRegion fBackgroundRegion;
BRegion fScreenRegion;
Window* fMouseEventWindow;
const Window* fWindowUnderMouse;
const Window* fLockedFocusWindow;
int32 fViewUnderMouse;
BPoint fLastMousePosition;
int32 fLastMouseButtons;
Window* fFocus;
Window* fFront;
Window* fBack;
StackAndTile fStackAndTile;
BMessage fPendingColors;
};
#endif