* Changed AS_GET_SCREEN_ID_FROM_WINDOW as well as AS_SCREEN_GET_MODE to no
longer hold the window lock. There is now a lock that guards screen changes in particular. This fixes the deadlocks seen in apps using BDirectWindow. * All direct window handling now sits in the Desktop class - ServerWindow::HandleDirectConnection() is never called from anywhere else anymore. Furthermore, it's now only called when actually needed. * Resize/move actions now always send a B_CLIPPING_MODIFIED flag, too. * When the screen changed, the driver state is supposed to be B_MODE_CHANGED, not B_SCREEN_CHANGED (which is a message constant). * Direct windows are no longer suspended too late on screen changes. * Removed unused members of DirectWindowData, and cleaned it up a bit. * Made MultiLocker's default, and copy constructors private - I accidently used them, causing the ASSERT_MULTI_*LOCKED() macros to fail. * Added Unlock() to AutoWriteLocker as well. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32742 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+131
-23
@@ -289,13 +289,15 @@ workspace_in_workspaces(int32 index, uint32 workspaces)
|
|||||||
|
|
||||||
|
|
||||||
Desktop::Desktop(uid_t userID)
|
Desktop::Desktop(uid_t userID)
|
||||||
: MessageLooper("desktop"),
|
:
|
||||||
|
MessageLooper("desktop"),
|
||||||
|
|
||||||
fUserID(userID),
|
fUserID(userID),
|
||||||
fSettings(NULL),
|
fSettings(NULL),
|
||||||
fSharedReadOnlyArea(-1),
|
fSharedReadOnlyArea(-1),
|
||||||
fApplicationsLock("application list"),
|
fApplicationsLock("application list"),
|
||||||
fShutdownSemaphore(-1),
|
fShutdownSemaphore(-1),
|
||||||
|
fScreenLock("screen lock"),
|
||||||
fCurrentWorkspace(0),
|
fCurrentWorkspace(0),
|
||||||
fPreviousWorkspace(0),
|
fPreviousWorkspace(0),
|
||||||
fAllWindows(kAllWindowList),
|
fAllWindows(kAllWindowList),
|
||||||
@@ -492,14 +494,14 @@ status_t
|
|||||||
Desktop::SetScreenMode(int32 workspace, int32 id, const display_mode& mode,
|
Desktop::SetScreenMode(int32 workspace, int32 id, const display_mode& mode,
|
||||||
bool makeDefault)
|
bool makeDefault)
|
||||||
{
|
{
|
||||||
|
AutoWriteLocker _(fWindowLock);
|
||||||
|
|
||||||
if (workspace == B_CURRENT_WORKSPACE_INDEX)
|
if (workspace == B_CURRENT_WORKSPACE_INDEX)
|
||||||
workspace = fCurrentWorkspace;
|
workspace = fCurrentWorkspace;
|
||||||
|
|
||||||
if (workspace < 0 || workspace > kMaxWorkspaces)
|
if (workspace < 0 || workspace > kMaxWorkspaces)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
AutoWriteLocker _(fWindowLock);
|
|
||||||
|
|
||||||
Screen* screen = fVirtualScreen.ScreenByID(id);
|
Screen* screen = fVirtualScreen.ScreenByID(id);
|
||||||
if (screen == NULL)
|
if (screen == NULL)
|
||||||
return B_NAME_NOT_FOUND;
|
return B_NAME_NOT_FOUND;
|
||||||
@@ -516,9 +518,17 @@ Desktop::SetScreenMode(int32 workspace, int32 id, const display_mode& mode,
|
|||||||
|
|
||||||
// Set the new one
|
// Set the new one
|
||||||
|
|
||||||
|
_SuspendDirectFrameBufferAccess();
|
||||||
|
|
||||||
|
AutoWriteLocker locker(fScreenLock);
|
||||||
|
|
||||||
status_t status = screen->SetMode(mode);
|
status_t status = screen->SetMode(mode);
|
||||||
if (status != B_OK)
|
if (status != B_OK) {
|
||||||
|
locker.Unlock();
|
||||||
|
|
||||||
|
_ResumeDirectFrameBufferAccess();
|
||||||
return status;
|
return status;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// retrieve from settings
|
// retrieve from settings
|
||||||
screen_configuration* configuration
|
screen_configuration* configuration
|
||||||
@@ -543,6 +553,9 @@ Desktop::SetScreenMode(int32 workspace, int32 id, const display_mode& mode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
_ScreenChanged(screen);
|
_ScreenChanged(screen);
|
||||||
|
if (workspace == fCurrentWorkspace)
|
||||||
|
_ResumeDirectFrameBufferAccess();
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,14 +563,14 @@ Desktop::SetScreenMode(int32 workspace, int32 id, const display_mode& mode,
|
|||||||
status_t
|
status_t
|
||||||
Desktop::GetScreenMode(int32 workspace, int32 id, display_mode& mode)
|
Desktop::GetScreenMode(int32 workspace, int32 id, display_mode& mode)
|
||||||
{
|
{
|
||||||
|
AutoReadLocker _(fScreenLock);
|
||||||
|
|
||||||
if (workspace == B_CURRENT_WORKSPACE_INDEX)
|
if (workspace == B_CURRENT_WORKSPACE_INDEX)
|
||||||
workspace = fCurrentWorkspace;
|
workspace = fCurrentWorkspace;
|
||||||
|
|
||||||
if (workspace < 0 || workspace > kMaxWorkspaces)
|
if (workspace < 0 || workspace > kMaxWorkspaces)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
AutoReadLocker _(fWindowLock);
|
|
||||||
|
|
||||||
if (workspace == fCurrentWorkspace) {
|
if (workspace == fCurrentWorkspace) {
|
||||||
// retrieve from current screen
|
// retrieve from current screen
|
||||||
Screen* screen = fVirtualScreen.ScreenByID(id);
|
Screen* screen = fVirtualScreen.ScreenByID(id);
|
||||||
@@ -582,14 +595,14 @@ Desktop::GetScreenMode(int32 workspace, int32 id, display_mode& mode)
|
|||||||
status_t
|
status_t
|
||||||
Desktop::GetScreenFrame(int32 workspace, int32 id, BRect& frame)
|
Desktop::GetScreenFrame(int32 workspace, int32 id, BRect& frame)
|
||||||
{
|
{
|
||||||
|
AutoReadLocker _(fScreenLock);
|
||||||
|
|
||||||
if (workspace == B_CURRENT_WORKSPACE_INDEX)
|
if (workspace == B_CURRENT_WORKSPACE_INDEX)
|
||||||
workspace = fCurrentWorkspace;
|
workspace = fCurrentWorkspace;
|
||||||
|
|
||||||
if (workspace < 0 || workspace > kMaxWorkspaces)
|
if (workspace < 0 || workspace > kMaxWorkspaces)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
AutoReadLocker _(fWindowLock);
|
|
||||||
|
|
||||||
if (workspace == fCurrentWorkspace) {
|
if (workspace == fCurrentWorkspace) {
|
||||||
// retrieve from current screen
|
// retrieve from current screen
|
||||||
Screen* screen = fVirtualScreen.ScreenByID(id);
|
Screen* screen = fVirtualScreen.ScreenByID(id);
|
||||||
@@ -647,8 +660,11 @@ Desktop::RevertScreenModes(uint32 workspaces)
|
|||||||
fWorkspaces[workspace].CurrentScreenConfiguration()
|
fWorkspaces[workspace].CurrentScreenConfiguration()
|
||||||
.Remove(current);
|
.Remove(current);
|
||||||
|
|
||||||
if (workspace == fCurrentWorkspace)
|
if (workspace == fCurrentWorkspace) {
|
||||||
|
_SuspendDirectFrameBufferAccess();
|
||||||
_SetCurrentWorkspaceConfiguration();
|
_SetCurrentWorkspaceConfiguration();
|
||||||
|
_ResumeDirectFrameBufferAccess();
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
SetScreenMode(workspace, screen->ID(), stored->mode, false);
|
SetScreenMode(workspace, screen->ID(), stored->mode, false);
|
||||||
}
|
}
|
||||||
@@ -1078,8 +1094,12 @@ Desktop::MoveWindowBy(Window* window, float x, float y, int32 workspace)
|
|||||||
// the dirty region starts with the visible area of the window being moved
|
// the dirty region starts with the visible area of the window being moved
|
||||||
BRegion newDirtyRegion(window->VisibleRegion());
|
BRegion newDirtyRegion(window->VisibleRegion());
|
||||||
|
|
||||||
// no more drawing for DirectWindows
|
// stop direct frame buffer access
|
||||||
window->ServerWindow()->HandleDirectConnection(B_DIRECT_STOP);
|
bool direct = false;
|
||||||
|
if (window->ServerWindow()->IsDirectlyAccessing()) {
|
||||||
|
window->ServerWindow()->HandleDirectConnection(B_DIRECT_STOP);
|
||||||
|
direct = true;
|
||||||
|
}
|
||||||
|
|
||||||
window->MoveBy((int32)x, (int32)y);
|
window->MoveBy((int32)x, (int32)y);
|
||||||
|
|
||||||
@@ -1108,9 +1128,13 @@ Desktop::MoveWindowBy(Window* window, float x, float y, int32 workspace)
|
|||||||
_SetBackground(background);
|
_SetBackground(background);
|
||||||
_WindowChanged(window);
|
_WindowChanged(window);
|
||||||
|
|
||||||
// allow DirectWindows to draw again after the visual
|
// resume direct frame buffer access
|
||||||
// content is at the new location
|
if (direct) {
|
||||||
window->ServerWindow()->HandleDirectConnection(B_DIRECT_START | B_BUFFER_MOVED);
|
// TODO: the clipping actually only changes when we move our window
|
||||||
|
// off screen, or behind some other window
|
||||||
|
window->ServerWindow()->HandleDirectConnection(
|
||||||
|
B_DIRECT_START | B_BUFFER_MOVED | B_CLIPPING_MODIFIED);
|
||||||
|
}
|
||||||
|
|
||||||
UnlockAllWindows();
|
UnlockAllWindows();
|
||||||
}
|
}
|
||||||
@@ -1135,7 +1159,12 @@ Desktop::ResizeWindowBy(Window* window, float x, float y)
|
|||||||
// it is shrunk in "previouslyOccupiedRegion"
|
// it is shrunk in "previouslyOccupiedRegion"
|
||||||
BRegion previouslyOccupiedRegion(window->VisibleRegion());
|
BRegion previouslyOccupiedRegion(window->VisibleRegion());
|
||||||
|
|
||||||
window->ServerWindow()->HandleDirectConnection(B_DIRECT_STOP);
|
// stop direct frame buffer access
|
||||||
|
bool direct = false;
|
||||||
|
if (window->ServerWindow()->IsDirectlyAccessing()) {
|
||||||
|
window->ServerWindow()->HandleDirectConnection(B_DIRECT_STOP);
|
||||||
|
direct = true;
|
||||||
|
}
|
||||||
|
|
||||||
window->ResizeBy((int32)x, (int32)y, &newDirtyRegion);
|
window->ResizeBy((int32)x, (int32)y, &newDirtyRegion);
|
||||||
|
|
||||||
@@ -1155,7 +1184,11 @@ Desktop::ResizeWindowBy(Window* window, float x, float y)
|
|||||||
_SetBackground(background);
|
_SetBackground(background);
|
||||||
_WindowChanged(window);
|
_WindowChanged(window);
|
||||||
|
|
||||||
window->ServerWindow()->HandleDirectConnection(B_DIRECT_START | B_BUFFER_RESIZED);
|
// resume direct frame buffer access
|
||||||
|
if (direct) {
|
||||||
|
window->ServerWindow()->HandleDirectConnection(
|
||||||
|
B_DIRECT_START | B_BUFFER_RESIZED | B_CLIPPING_MODIFIED);
|
||||||
|
}
|
||||||
|
|
||||||
UnlockAllWindows();
|
UnlockAllWindows();
|
||||||
}
|
}
|
||||||
@@ -2428,8 +2461,10 @@ Desktop::_ShowWindow(Window* window, bool affectsOtherWindows)
|
|||||||
} else
|
} else
|
||||||
MarkDirty(dirty);
|
MarkDirty(dirty);
|
||||||
|
|
||||||
window->ServerWindow()->HandleDirectConnection(
|
if (window->ServerWindow()->HasDirectFrameBufferAccess()) {
|
||||||
B_DIRECT_START | B_BUFFER_RESET);
|
window->ServerWindow()->HandleDirectConnection(
|
||||||
|
B_DIRECT_START | B_BUFFER_RESET);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2439,7 +2474,8 @@ Desktop::_ShowWindow(Window* window, bool affectsOtherWindows)
|
|||||||
void
|
void
|
||||||
Desktop::_HideWindow(Window* window)
|
Desktop::_HideWindow(Window* window)
|
||||||
{
|
{
|
||||||
window->ServerWindow()->HandleDirectConnection(B_DIRECT_STOP);
|
if (window->ServerWindow()->IsDirectlyAccessing())
|
||||||
|
window->ServerWindow()->HandleDirectConnection(B_DIRECT_STOP);
|
||||||
|
|
||||||
// after rebuilding the clipping,
|
// after rebuilding the clipping,
|
||||||
// this window will not have a visible
|
// this window will not have a visible
|
||||||
@@ -2540,8 +2576,9 @@ Desktop::_ChangeWindowWorkspaces(Window* window, uint32 oldWorkspaces,
|
|||||||
window->SetCurrentWorkspace(fCurrentWorkspace);
|
window->SetCurrentWorkspace(fCurrentWorkspace);
|
||||||
|
|
||||||
if (!window->IsHidden()) {
|
if (!window->IsHidden()) {
|
||||||
// this only affects other windows if this windows has floating or
|
// This only affects other windows if this window has
|
||||||
// modal windows that need to be shown as well
|
// floating or modal windows that need to be shown as
|
||||||
|
// well
|
||||||
// TODO: take care of this
|
// TODO: take care of this
|
||||||
_ShowWindow(window, FrontWindow() == window);
|
_ShowWindow(window, FrontWindow() == window);
|
||||||
}
|
}
|
||||||
@@ -2674,6 +2711,16 @@ Desktop::_SendFakeMouseMoved(Window* window)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Screen*
|
||||||
|
Desktop::_DetermineScreenFor(BRect frame)
|
||||||
|
{
|
||||||
|
AutoReadLocker _(fScreenLock);
|
||||||
|
|
||||||
|
// TODO: choose the screen depending on where most of the area is
|
||||||
|
return fVirtualScreen.ScreenAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Desktop::_RebuildClippingForAllWindows(BRegion& stillAvailableOnScreen)
|
Desktop::_RebuildClippingForAllWindows(BRegion& stillAvailableOnScreen)
|
||||||
{
|
{
|
||||||
@@ -2688,6 +2735,13 @@ Desktop::_RebuildClippingForAllWindows(BRegion& stillAvailableOnScreen)
|
|||||||
window = window->PreviousWindow(fCurrentWorkspace)) {
|
window = window->PreviousWindow(fCurrentWorkspace)) {
|
||||||
if (!window->IsHidden()) {
|
if (!window->IsHidden()) {
|
||||||
window->SetClipping(&stillAvailableOnScreen);
|
window->SetClipping(&stillAvailableOnScreen);
|
||||||
|
window->SetScreen(_DetermineScreenFor(window->Frame()));
|
||||||
|
|
||||||
|
if (window->ServerWindow()->IsDirectlyAccessing()) {
|
||||||
|
window->ServerWindow()->HandleDirectConnection(
|
||||||
|
B_DIRECT_MODIFY | B_CLIPPING_MODIFIED);
|
||||||
|
}
|
||||||
|
|
||||||
// that windows region is not available on screen anymore
|
// that windows region is not available on screen anymore
|
||||||
stillAvailableOnScreen.Exclude(&window->VisibleRegion());
|
stillAvailableOnScreen.Exclude(&window->VisibleRegion());
|
||||||
}
|
}
|
||||||
@@ -2756,6 +2810,13 @@ Desktop::_RebuildAndRedrawAfterWindowChange(Window* changedWindow,
|
|||||||
dirty.IntersectWith(&stillAvailableOnScreen);
|
dirty.IntersectWith(&stillAvailableOnScreen);
|
||||||
|
|
||||||
window->SetClipping(&stillAvailableOnScreen);
|
window->SetClipping(&stillAvailableOnScreen);
|
||||||
|
window->SetScreen(_DetermineScreenFor(window->Frame()));
|
||||||
|
|
||||||
|
if (window->ServerWindow()->IsDirectlyAccessing()) {
|
||||||
|
window->ServerWindow()->HandleDirectConnection(
|
||||||
|
B_DIRECT_MODIFY | B_CLIPPING_MODIFIED);
|
||||||
|
}
|
||||||
|
|
||||||
// that windows region is not available on screen anymore
|
// that windows region is not available on screen anymore
|
||||||
stillAvailableOnScreen.Exclude(&window->VisibleRegion());
|
stillAvailableOnScreen.Exclude(&window->VisibleRegion());
|
||||||
}
|
}
|
||||||
@@ -2768,6 +2829,39 @@ Desktop::_RebuildAndRedrawAfterWindowChange(Window* changedWindow,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Suspend all windows with direct access to the frame buffer
|
||||||
|
void
|
||||||
|
Desktop::_SuspendDirectFrameBufferAccess()
|
||||||
|
{
|
||||||
|
ASSERT_MULTI_LOCKED(fWindowLock);
|
||||||
|
|
||||||
|
for (Window* window = fAllWindows.FirstWindow(); window != NULL;
|
||||||
|
window = window->NextWindow(kAllWindowList)) {
|
||||||
|
if (window->ServerWindow()->IsDirectlyAccessing())
|
||||||
|
window->ServerWindow()->HandleDirectConnection(B_DIRECT_STOP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Resume all windows with direct access to the frame buffer
|
||||||
|
void
|
||||||
|
Desktop::_ResumeDirectFrameBufferAccess()
|
||||||
|
{
|
||||||
|
ASSERT_MULTI_LOCKED(fWindowLock);
|
||||||
|
|
||||||
|
for (Window* window = fAllWindows.FirstWindow(); window != NULL;
|
||||||
|
window = window->NextWindow(kAllWindowList)) {
|
||||||
|
if (window->IsHidden() || !window->InWorkspace(fCurrentWorkspace))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (window->ServerWindow()->HasDirectFrameBufferAccess()) {
|
||||||
|
window->ServerWindow()->HandleDirectConnection(
|
||||||
|
B_DIRECT_START | B_BUFFER_RESET, B_MODE_CHANGED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Desktop::_ScreenChanged(Screen* screen)
|
Desktop::_ScreenChanged(Screen* screen)
|
||||||
{
|
{
|
||||||
@@ -2800,10 +2894,10 @@ Desktop::_ScreenChanged(Screen* screen)
|
|||||||
|
|
||||||
fVirtualScreen.UpdateFrame();
|
fVirtualScreen.UpdateFrame();
|
||||||
|
|
||||||
// TODO: currently ignores the screen argument!
|
|
||||||
for (Window* window = fAllWindows.FirstWindow(); window != NULL;
|
for (Window* window = fAllWindows.FirstWindow(); window != NULL;
|
||||||
window = window->NextWindow(kAllWindowList)) {
|
window = window->NextWindow(kAllWindowList)) {
|
||||||
window->ServerWindow()->ScreenChanged(&update);
|
if (window->Screen() == screen)
|
||||||
|
window->ServerWindow()->ScreenChanged(&update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2852,6 +2946,8 @@ Desktop::_SetCurrentWorkspaceConfiguration()
|
|||||||
{
|
{
|
||||||
ASSERT_MULTI_WRITE_LOCKED(fWindowLock);
|
ASSERT_MULTI_WRITE_LOCKED(fWindowLock);
|
||||||
|
|
||||||
|
AutoWriteLocker _(fScreenLock);
|
||||||
|
|
||||||
uint32 changedScreens;
|
uint32 changedScreens;
|
||||||
fVirtualScreen.SetConfiguration(*this,
|
fVirtualScreen.SetConfiguration(*this,
|
||||||
fWorkspaces[fCurrentWorkspace].CurrentScreenConfiguration(),
|
fWorkspaces[fCurrentWorkspace].CurrentScreenConfiguration(),
|
||||||
@@ -2870,6 +2966,8 @@ Desktop::_SetCurrentWorkspaceConfiguration()
|
|||||||
void
|
void
|
||||||
Desktop::_SetWorkspace(int32 index)
|
Desktop::_SetWorkspace(int32 index)
|
||||||
{
|
{
|
||||||
|
ASSERT_MULTI_WRITE_LOCKED(fWindowLock);
|
||||||
|
|
||||||
int32 previousIndex = fCurrentWorkspace;
|
int32 previousIndex = fCurrentWorkspace;
|
||||||
rgb_color previousColor = fWorkspaces[fCurrentWorkspace].Color();
|
rgb_color previousColor = fWorkspaces[fCurrentWorkspace].Color();
|
||||||
bool movedMouseEventWindow = false;
|
bool movedMouseEventWindow = false;
|
||||||
@@ -2914,6 +3012,10 @@ Desktop::_SetWorkspace(int32 index)
|
|||||||
// store current position in Workspace anchor
|
// store current position in Workspace anchor
|
||||||
window->Anchor(previousIndex).position = window->Frame().LeftTop();
|
window->Anchor(previousIndex).position = window->Frame().LeftTop();
|
||||||
|
|
||||||
|
if (!window->IsHidden()
|
||||||
|
&& window->ServerWindow()->IsDirectlyAccessing())
|
||||||
|
window->ServerWindow()->HandleDirectConnection(B_DIRECT_STOP);
|
||||||
|
|
||||||
window->WorkspaceActivated(previousIndex, false);
|
window->WorkspaceActivated(previousIndex, false);
|
||||||
|
|
||||||
if (window->InWorkspace(index))
|
if (window->InWorkspace(index))
|
||||||
@@ -2998,6 +3100,12 @@ Desktop::_SetWorkspace(int32 index)
|
|||||||
// send B_WORKSPACE_ACTIVATED message
|
// send B_WORKSPACE_ACTIVATED message
|
||||||
window->WorkspaceActivated(index, true);
|
window->WorkspaceActivated(index, true);
|
||||||
|
|
||||||
|
if (!window->IsHidden()
|
||||||
|
&& window->ServerWindow()->HasDirectFrameBufferAccess()) {
|
||||||
|
window->ServerWindow()->HandleDirectConnection(
|
||||||
|
B_DIRECT_START | B_BUFFER_RESET, B_MODE_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
if (window->InWorkspace(previousIndex) || window->IsHidden()
|
if (window->InWorkspace(previousIndex) || window->IsHidden()
|
||||||
|| (window == fMouseEventWindow && fMouseEventWindow->IsNormal())
|
|| (window == fMouseEventWindow && fMouseEventWindow->IsNormal())
|
||||||
|| (!window->IsNormal()
|
|| (!window->IsNormal()
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ public:
|
|||||||
void UnlockAllWindows()
|
void UnlockAllWindows()
|
||||||
{ fWindowLock.WriteUnlock(); }
|
{ fWindowLock.WriteUnlock(); }
|
||||||
|
|
||||||
MultiLocker WindowLocker() { return fWindowLock; }
|
const MultiLocker& WindowLocker() { return fWindowLock; }
|
||||||
#else // USE_MULTI_LOCKER
|
#else // USE_MULTI_LOCKER
|
||||||
bool LockSingleWindow()
|
bool LockSingleWindow()
|
||||||
{ return fWindowLock.Lock(); }
|
{ return fWindowLock.Lock(); }
|
||||||
@@ -125,6 +125,8 @@ public:
|
|||||||
BRect& frame);
|
BRect& frame);
|
||||||
void RevertScreenModes(uint32 workspaces);
|
void RevertScreenModes(uint32 workspaces);
|
||||||
|
|
||||||
|
MultiLocker& ScreenLocker() { return fScreenLock; }
|
||||||
|
|
||||||
const ::VirtualScreen& VirtualScreen() const
|
const ::VirtualScreen& VirtualScreen() const
|
||||||
{ return fVirtualScreen; }
|
{ return fVirtualScreen; }
|
||||||
DrawingEngine* GetDrawingEngine() const
|
DrawingEngine* GetDrawingEngine() const
|
||||||
@@ -268,6 +270,7 @@ private:
|
|||||||
Window* _LastFocusSubsetWindow(Window* window);
|
Window* _LastFocusSubsetWindow(Window* window);
|
||||||
void _SendFakeMouseMoved(Window* window = NULL);
|
void _SendFakeMouseMoved(Window* window = NULL);
|
||||||
|
|
||||||
|
Screen* _DetermineScreenFor(BRect frame);
|
||||||
void _RebuildClippingForAllWindows(
|
void _RebuildClippingForAllWindows(
|
||||||
BRegion& stillAvailableOnScreen);
|
BRegion& stillAvailableOnScreen);
|
||||||
void _TriggerWindowRedrawing(
|
void _TriggerWindowRedrawing(
|
||||||
@@ -278,6 +281,9 @@ private:
|
|||||||
|
|
||||||
status_t _ActivateApp(team_id team);
|
status_t _ActivateApp(team_id team);
|
||||||
|
|
||||||
|
void _SuspendDirectFrameBufferAccess();
|
||||||
|
void _ResumeDirectFrameBufferAccess();
|
||||||
|
|
||||||
void _ScreenChanged(Screen* screen);
|
void _ScreenChanged(Screen* screen);
|
||||||
void _SetCurrentWorkspaceConfiguration();
|
void _SetCurrentWorkspaceConfiguration();
|
||||||
void _SetWorkspace(int32 index);
|
void _SetWorkspace(int32 index);
|
||||||
@@ -302,6 +308,7 @@ private:
|
|||||||
int32 fShutdownCount;
|
int32 fShutdownCount;
|
||||||
|
|
||||||
::Workspace::Private fWorkspaces[kMaxWorkspaces];
|
::Workspace::Private fWorkspaces[kMaxWorkspaces];
|
||||||
|
MultiLocker fScreenLock;
|
||||||
int32 fCurrentWorkspace;
|
int32 fCurrentWorkspace;
|
||||||
int32 fPreviousWorkspace;
|
int32 fPreviousWorkspace;
|
||||||
|
|
||||||
|
|||||||
@@ -7,17 +7,18 @@
|
|||||||
* Axel Dörfler, [email protected]
|
* Axel Dörfler, [email protected]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "DirectWindowSupport.h"
|
#include "DirectWindowSupport.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
#include <Autolock.h>
|
#include <Autolock.h>
|
||||||
|
|
||||||
#include "RenderingBuffer.h"
|
#include "RenderingBuffer.h"
|
||||||
#include "clipping.h"
|
#include "clipping.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <syslog.h>
|
|
||||||
|
|
||||||
|
|
||||||
DirectWindowData::DirectWindowData()
|
DirectWindowData::DirectWindowData()
|
||||||
:
|
:
|
||||||
@@ -25,9 +26,7 @@ DirectWindowData::DirectWindowData()
|
|||||||
fBufferInfo(NULL),
|
fBufferInfo(NULL),
|
||||||
fSem(-1),
|
fSem(-1),
|
||||||
fAcknowledgeSem(-1),
|
fAcknowledgeSem(-1),
|
||||||
fBufferArea(-1),
|
fBufferArea(-1)
|
||||||
fTransition(0),
|
|
||||||
fStarted(false)
|
|
||||||
{
|
{
|
||||||
fBufferArea = create_area("direct area", (void**)&fBufferInfo,
|
fBufferArea = create_area("direct area", (void**)&fBufferInfo,
|
||||||
B_ANY_ADDRESS, DIRECT_BUFFER_INFO_AREA_SIZE,
|
B_ANY_ADDRESS, DIRECT_BUFFER_INFO_AREA_SIZE,
|
||||||
@@ -87,46 +86,31 @@ DirectWindowData::_SyncronizeWithClient()
|
|||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
//syslog(LOG_INFO, "Syncronize: released sem");
|
|
||||||
// Wait with a timeout of half a second until the client exits
|
// Wait with a timeout of half a second until the client exits
|
||||||
// from its DirectConnected() implementation
|
// from its DirectConnected() implementation
|
||||||
do {
|
do {
|
||||||
#if 0
|
#if 0
|
||||||
status = acquire_sem(fAcknowledgeSem);
|
status = acquire_sem(fAcknowledgeSem);
|
||||||
#else
|
#else
|
||||||
status = acquire_sem_etc(fAcknowledgeSem, 1, B_TIMEOUT, 500000);
|
status = acquire_sem_etc(fAcknowledgeSem, 1, B_TIMEOUT, 500000);
|
||||||
#endif
|
#endif
|
||||||
} while (status == B_INTERRUPTED);
|
} while (status == B_INTERRUPTED);
|
||||||
|
|
||||||
//syslog(LOG_INFO, "Syncronize: acquired sem");
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
DirectWindowData::SetState(const direct_buffer_state& bufferState,
|
DirectWindowData::SetState(direct_buffer_state bufferState,
|
||||||
const direct_driver_state& driverState, RenderingBuffer *buffer,
|
direct_driver_state driverState, RenderingBuffer* buffer,
|
||||||
const BRect& windowFrame, const BRegion& clipRegion)
|
const BRect& windowFrame, const BRegion& clipRegion)
|
||||||
{
|
{
|
||||||
if (!fStarted && (bufferState & B_DIRECT_MODE_MASK)
|
|
||||||
!= B_DIRECT_START)
|
|
||||||
return B_OK;
|
|
||||||
|
|
||||||
if ((fBufferInfo->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_STOP
|
if ((fBufferInfo->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_STOP
|
||||||
&& (bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_START)
|
&& (bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_START)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
#if 0
|
|
||||||
if ((bufferState & B_DIRECT_MODE_MASK) == B_DIRECT_MODIFY)
|
|
||||||
syslog(LOG_INFO, "direct_modify");
|
|
||||||
#endif
|
|
||||||
fStarted = true;
|
|
||||||
#if 0
|
|
||||||
char string[256];
|
|
||||||
snprintf(string, sizeof(string), "bufferState: 0x%x\n", (int)bufferState);
|
|
||||||
syslog(LOG_INFO, string);
|
|
||||||
#endif
|
|
||||||
fBufferInfo->buffer_state = bufferState;
|
fBufferInfo->buffer_state = bufferState;
|
||||||
|
|
||||||
if (driverState != -1)
|
if (driverState != -1)
|
||||||
fBufferInfo->driver_state = driverState;
|
fBufferInfo->driver_state = driverState;
|
||||||
|
|
||||||
@@ -180,6 +164,6 @@ DirectWindowData::SetState(const direct_buffer_state& bufferState,
|
|||||||
for (uint32 i = 0; i < fBufferInfo->clip_list_count; i++)
|
for (uint32 i = 0; i < fBufferInfo->clip_list_count; i++)
|
||||||
fBufferInfo->clip_list[i] = clipRegion.RectAtInt(i);
|
fBufferInfo->clip_list[i] = clipRegion.RectAtInt(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _SyncronizeWithClient();
|
return _SyncronizeWithClient();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
#ifndef DIRECT_WINDOW_SUPPORT_H
|
||||||
|
#define DIRECT_WINDOW_SUPPORT_H
|
||||||
|
|
||||||
|
|
||||||
#include <Autolock.h>
|
#include <Autolock.h>
|
||||||
#include <DirectWindow.h>
|
#include <DirectWindow.h>
|
||||||
@@ -11,26 +14,6 @@
|
|||||||
|
|
||||||
class RenderingBuffer;
|
class RenderingBuffer;
|
||||||
|
|
||||||
struct BufferState {
|
|
||||||
BufferState(const direct_buffer_state& state)
|
|
||||||
:
|
|
||||||
fState(state)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline direct_buffer_state Action() const
|
|
||||||
{
|
|
||||||
return (direct_buffer_state)(fState & B_DIRECT_MODE_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline direct_buffer_state Reason() const
|
|
||||||
{
|
|
||||||
return (direct_buffer_state)(fState & ~B_DIRECT_MODE_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
direct_buffer_state fState;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class DirectWindowData {
|
class DirectWindowData {
|
||||||
public:
|
public:
|
||||||
@@ -43,24 +26,23 @@ public:
|
|||||||
direct_window_sync_data& data) const;
|
direct_window_sync_data& data) const;
|
||||||
status_t SyncronizeWithClient();
|
status_t SyncronizeWithClient();
|
||||||
|
|
||||||
status_t SetState(const direct_buffer_state& bufferState,
|
status_t SetState(direct_buffer_state bufferState,
|
||||||
const direct_driver_state& driverState,
|
direct_driver_state driverState,
|
||||||
RenderingBuffer *renderingBuffer,
|
RenderingBuffer* renderingBuffer,
|
||||||
const BRect& windowFrame,
|
const BRect& windowFrame,
|
||||||
const BRegion& clipRegion);
|
const BRegion& clipRegion);
|
||||||
|
|
||||||
BRect old_window_frame;
|
BRect old_window_frame;
|
||||||
bool full_screen;
|
bool full_screen;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _SyncronizeWithClient();
|
status_t _SyncronizeWithClient();
|
||||||
|
|
||||||
direct_buffer_info* fBufferInfo;
|
direct_buffer_info* fBufferInfo;
|
||||||
sem_id fSem;
|
sem_id fSem;
|
||||||
sem_id fAcknowledgeSem;
|
sem_id fAcknowledgeSem;
|
||||||
area_id fBufferArea;
|
area_id fBufferArea;
|
||||||
direct_buffer_state fPreviousState;
|
|
||||||
int32 fTransition;
|
|
||||||
bool fStarted;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // DIRECT_WINDOW_SUPPORT_H
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Copyright 2005-2009, Haiku, Inc. All Rights Reserved.
|
* Copyright 2005-2009, Haiku, Inc. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Copyright 1999, Be Incorporated. All Rights Reserved.
|
* Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||||
* This file may be used under the terms of the Be Sample Code License.
|
* This file may be used under the terms of the Be Sample Code License.
|
||||||
*/
|
*/
|
||||||
#ifndef MULTI_LOCKER_H
|
#ifndef MULTI_LOCKER_H
|
||||||
@@ -66,6 +66,11 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
MultiLocker();
|
||||||
|
MultiLocker(const MultiLocker& other);
|
||||||
|
MultiLocker& operator=(const MultiLocker& other);
|
||||||
|
// not implemented
|
||||||
|
|
||||||
#if MULTI_LOCKER_DEBUG
|
#if MULTI_LOCKER_DEBUG
|
||||||
// functions for managing the DEBUG reader array
|
// functions for managing the DEBUG reader array
|
||||||
void _RegisterThread();
|
void _RegisterThread();
|
||||||
@@ -114,14 +119,20 @@ public:
|
|||||||
:
|
:
|
||||||
fLock(*lock)
|
fLock(*lock)
|
||||||
{
|
{
|
||||||
fLock.WriteLock();
|
fLocked = fLock.WriteLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoWriteLocker(MultiLocker& lock)
|
AutoWriteLocker(MultiLocker& lock)
|
||||||
:
|
:
|
||||||
fLock(lock)
|
fLock(lock)
|
||||||
{
|
{
|
||||||
fLock.WriteLock();
|
fLocked = fLock.WriteLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
~AutoWriteLocker()
|
||||||
|
{
|
||||||
|
if (fLocked)
|
||||||
|
fLock.WriteUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsLocked() const
|
bool IsLocked() const
|
||||||
@@ -129,13 +140,17 @@ public:
|
|||||||
return fLock.IsWriteLocked();
|
return fLock.IsWriteLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
~AutoWriteLocker()
|
void Unlock()
|
||||||
{
|
{
|
||||||
fLock.WriteUnlock();
|
if (fLocked) {
|
||||||
|
fLock.WriteUnlock();
|
||||||
|
fLocked = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MultiLocker& fLock;
|
MultiLocker& fLock;
|
||||||
|
bool fLocked;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -160,8 +175,7 @@ public:
|
|||||||
Unlock();
|
Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Unlock()
|
||||||
Unlock()
|
|
||||||
{
|
{
|
||||||
if (fLocked) {
|
if (fLocked) {
|
||||||
fLock.ReadUnlock();
|
fLock.ReadUnlock();
|
||||||
|
|||||||
@@ -2252,36 +2252,41 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
|
|
||||||
case AS_GET_SCREEN_ID_FROM_WINDOW:
|
case AS_GET_SCREEN_ID_FROM_WINDOW:
|
||||||
{
|
{
|
||||||
status_t status = B_ENTRY_NOT_FOUND;
|
status_t status = B_BAD_VALUE;
|
||||||
|
|
||||||
// Attached data
|
// Attached data
|
||||||
// 1) int32 - window client token
|
// 1) int32 - window client token
|
||||||
int32 clientToken;
|
int32 clientToken;
|
||||||
if (link.Read<int32>(&clientToken) != B_OK)
|
if (link.Read<int32>(&clientToken) != B_OK)
|
||||||
status = B_BAD_DATA;
|
status = B_BAD_DATA;
|
||||||
else if (fDesktop->LockAllWindows()) {
|
else {
|
||||||
BAutolock locker(fWindowListLock);
|
BAutolock locker(fWindowListLock);
|
||||||
|
|
||||||
for (int32 i = fWindowList.CountItems(); i-- > 0;) {
|
for (int32 i = fWindowList.CountItems(); i-- > 0;) {
|
||||||
ServerWindow* window = fWindowList.ItemAt(i);
|
ServerWindow* serverWindow = fWindowList.ItemAt(i);
|
||||||
|
|
||||||
|
if (serverWindow->ClientToken() == clientToken) {
|
||||||
|
AutoReadLocker _(fDesktop->ScreenLocker());
|
||||||
|
|
||||||
if (window->ClientToken() == clientToken) {
|
|
||||||
// found it!
|
// found it!
|
||||||
if (window->Window() == NULL) {
|
Window* window = serverWindow->Window();
|
||||||
|
const Screen* screen = NULL;
|
||||||
|
if (window != NULL)
|
||||||
|
screen = window->Screen();
|
||||||
|
|
||||||
|
if (screen == NULL) {
|
||||||
// The window hasn't been added to the desktop yet,
|
// The window hasn't been added to the desktop yet,
|
||||||
// or it's an offscreen window
|
// or it's an offscreen window
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fLink.StartMessage(B_OK);
|
fLink.StartMessage(B_OK);
|
||||||
fLink.Attach<int32>(window->Window()->Screen()->ID());
|
fLink.Attach<int32>(screen->ID());
|
||||||
status = B_OK;
|
status = B_OK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fDesktop->UnlockAllWindows();
|
}
|
||||||
} else
|
|
||||||
status = B_ERROR;
|
|
||||||
|
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
fLink.StartMessage(status);
|
fLink.StartMessage(status);
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ ServerWindow::ServerWindow(const char* title, ServerApp* app,
|
|||||||
fCurrentDrawingRegionValid(false),
|
fCurrentDrawingRegionValid(false),
|
||||||
|
|
||||||
fDirectWindowData(NULL),
|
fDirectWindowData(NULL),
|
||||||
|
fIsDirectlyAccessing(false),
|
||||||
fDirectWindowFeel(B_NORMAL_WINDOW_FEEL)
|
fDirectWindowFeel(B_NORMAL_WINDOW_FEEL)
|
||||||
{
|
{
|
||||||
STRACE(("ServerWindow(%s)::ServerWindow()\n", title));
|
STRACE(("ServerWindow(%s)::ServerWindow()\n", title));
|
||||||
@@ -3401,8 +3402,6 @@ ServerWindow::_MessageLooper()
|
|||||||
void
|
void
|
||||||
ServerWindow::ScreenChanged(const BMessage* message)
|
ServerWindow::ScreenChanged(const BMessage* message)
|
||||||
{
|
{
|
||||||
// TODO: execute the stop notification earlier
|
|
||||||
HandleDirectConnection(B_DIRECT_STOP);
|
|
||||||
SendMessageToClient(message);
|
SendMessageToClient(message);
|
||||||
|
|
||||||
if (fDirectWindowData != NULL && fDirectWindowData->full_screen) {
|
if (fDirectWindowData != NULL && fDirectWindowData->full_screen) {
|
||||||
@@ -3411,9 +3410,6 @@ ServerWindow::ScreenChanged(const BMessage* message)
|
|||||||
screenFrame.Width() - fWindow->Frame().Width(),
|
screenFrame.Width() - fWindow->Frame().Width(),
|
||||||
screenFrame.Height() - fWindow->Frame().Height());
|
screenFrame.Height() - fWindow->Frame().Height());
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleDirectConnection(B_DIRECT_START | B_BUFFER_RESET,
|
|
||||||
B_SCREEN_CHANGED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3441,15 +3437,6 @@ ServerWindow::MakeWindow(BRect frame, const char* name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* static */
|
|
||||||
bool
|
|
||||||
ServerWindow::_SupportsDirectMode()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
// TODO: For now, since it's broken
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
ServerWindow::_EnableDirectWindowMode()
|
ServerWindow::_EnableDirectWindowMode()
|
||||||
{
|
{
|
||||||
@@ -3458,9 +3445,6 @@ ServerWindow::_EnableDirectWindowMode()
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ServerWindow::_SupportsDirectMode())
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
fDirectWindowData = new (nothrow) DirectWindowData;
|
fDirectWindowData = new (nothrow) DirectWindowData;
|
||||||
if (fDirectWindowData == NULL)
|
if (fDirectWindowData == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
@@ -3480,34 +3464,35 @@ ServerWindow::_EnableDirectWindowMode()
|
|||||||
void
|
void
|
||||||
ServerWindow::HandleDirectConnection(int32 bufferState, int32 driverState)
|
ServerWindow::HandleDirectConnection(int32 bufferState, int32 driverState)
|
||||||
{
|
{
|
||||||
STRACE(("HandleDirectConnection(bufferState = %ld, driverState = %ld)\n",
|
ASSERT_MULTI_LOCKED(fDesktop->WindowLocker());
|
||||||
bufferState, driverState));
|
|
||||||
|
|
||||||
if (fDirectWindowData == NULL)
|
if (fDirectWindowData == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (fDesktop->LockSingleWindow()) {
|
STRACE(("HandleDirectConnection(bufferState = %ld, driverState = %ld)\n",
|
||||||
status_t status = fDirectWindowData->SetState(
|
bufferState, driverState));
|
||||||
(direct_buffer_state)bufferState,
|
|
||||||
(direct_driver_state)driverState,
|
|
||||||
fDesktop->HWInterface()->FrontBuffer(), fWindow->Frame(),
|
|
||||||
fWindow->VisibleContentRegion());
|
|
||||||
|
|
||||||
if (status != B_OK) {
|
status_t status = fDirectWindowData->SetState(
|
||||||
char errorString[256];
|
(direct_buffer_state)bufferState, (direct_driver_state)driverState,
|
||||||
snprintf(errorString, sizeof(errorString),
|
fDesktop->HWInterface()->FrontBuffer(), fWindow->Frame(),
|
||||||
"%s killed for a problem in DirectConnected(): %s",
|
fWindow->VisibleContentRegion());
|
||||||
App()->Signature(), strerror(status));
|
|
||||||
syslog(LOG_ERR, errorString);
|
|
||||||
|
|
||||||
// The client application didn't release the semaphore
|
if (status != B_OK) {
|
||||||
// within the given timeout. Or something else went wrong.
|
char errorString[256];
|
||||||
// Deleting this member should make it crash.
|
snprintf(errorString, sizeof(errorString),
|
||||||
delete fDirectWindowData;
|
"%s killed for a problem in DirectConnected(): %s",
|
||||||
fDirectWindowData = NULL;
|
App()->Signature(), strerror(status));
|
||||||
}
|
syslog(LOG_ERR, errorString);
|
||||||
fDesktop->UnlockSingleWindow();
|
|
||||||
}
|
// The client application didn't release the semaphore
|
||||||
|
// within the given timeout. Or something else went wrong.
|
||||||
|
// Deleting this member should make it crash.
|
||||||
|
delete fDirectWindowData;
|
||||||
|
fDirectWindowData = NULL;
|
||||||
|
} else if ((bufferState & B_DIRECT_MODE_MASK) == B_DIRECT_START)
|
||||||
|
fIsDirectlyAccessing = true;
|
||||||
|
else if ((bufferState & B_DIRECT_MODE_MASK) == B_DIRECT_STOP)
|
||||||
|
fIsDirectlyAccessing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,12 +13,6 @@
|
|||||||
#define SERVER_WINDOW_H
|
#define SERVER_WINDOW_H
|
||||||
|
|
||||||
|
|
||||||
#include "EventDispatcher.h"
|
|
||||||
#include "MessageLooper.h"
|
|
||||||
|
|
||||||
#include <PortLink.h>
|
|
||||||
#include <TokenSpace.h>
|
|
||||||
|
|
||||||
#include <GraphicsDefs.h>
|
#include <GraphicsDefs.h>
|
||||||
#include <Locker.h>
|
#include <Locker.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
@@ -28,6 +22,13 @@
|
|||||||
#include <String.h>
|
#include <String.h>
|
||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include <PortLink.h>
|
||||||
|
#include <TokenSpace.h>
|
||||||
|
|
||||||
|
#include "EventDispatcher.h"
|
||||||
|
#include "MessageLooper.h"
|
||||||
|
|
||||||
|
|
||||||
class BString;
|
class BString;
|
||||||
class BMessenger;
|
class BMessenger;
|
||||||
class BPoint;
|
class BPoint;
|
||||||
@@ -47,6 +48,7 @@ struct window_info;
|
|||||||
#define AS_UPDATE_COLORS 'asuc'
|
#define AS_UPDATE_COLORS 'asuc'
|
||||||
#define AS_UPDATE_FONTS 'asuf'
|
#define AS_UPDATE_FONTS 'asuf'
|
||||||
|
|
||||||
|
|
||||||
class ServerWindow : public MessageLooper {
|
class ServerWindow : public MessageLooper {
|
||||||
public:
|
public:
|
||||||
ServerWindow(const char *title, ServerApp *app,
|
ServerWindow(const char *title, ServerApp *app,
|
||||||
@@ -77,8 +79,8 @@ public:
|
|||||||
const BMessenger& HandlerMessenger() const
|
const BMessenger& HandlerMessenger() const
|
||||||
{ return fHandlerMessenger; }
|
{ return fHandlerMessenger; }
|
||||||
|
|
||||||
void ScreenChanged(const BMessage *screenChangedMessage);
|
void ScreenChanged(const BMessage* message);
|
||||||
status_t SendMessageToClient(const BMessage* msg,
|
status_t SendMessageToClient(const BMessage* message,
|
||||||
int32 target = B_NULL_TOKEN) const;
|
int32 target = B_NULL_TOKEN) const;
|
||||||
|
|
||||||
virtual ::Window* MakeWindow(BRect frame, const char* name,
|
virtual ::Window* MakeWindow(BRect frame, const char* name,
|
||||||
@@ -91,9 +93,6 @@ public:
|
|||||||
// related thread/team_id(s).
|
// related thread/team_id(s).
|
||||||
inline team_id ClientTeam() const { return fClientTeam; }
|
inline team_id ClientTeam() const { return fClientTeam; }
|
||||||
|
|
||||||
void HandleDirectConnection(int32 bufferState,
|
|
||||||
int32 driverState = -1);
|
|
||||||
|
|
||||||
inline int32 ClientToken() const { return fClientToken; }
|
inline int32 ClientToken() const { return fClientToken; }
|
||||||
inline int32 ServerToken() const { return fServerToken; }
|
inline int32 ServerToken() const { return fServerToken; }
|
||||||
|
|
||||||
@@ -101,6 +100,13 @@ public:
|
|||||||
|
|
||||||
void GetInfo(window_info& info);
|
void GetInfo(window_info& info);
|
||||||
|
|
||||||
|
void HandleDirectConnection(int32 bufferState,
|
||||||
|
int32 driverState = 0);
|
||||||
|
bool HasDirectFrameBufferAccess() const
|
||||||
|
{ return fDirectWindowData != NULL; }
|
||||||
|
bool IsDirectlyAccessing() const
|
||||||
|
{ return fIsDirectlyAccessing; }
|
||||||
|
|
||||||
void ResyncDrawState();
|
void ResyncDrawState();
|
||||||
|
|
||||||
// TODO: Change this
|
// TODO: Change this
|
||||||
@@ -127,8 +133,8 @@ private:
|
|||||||
virtual void _PrepareQuit();
|
virtual void _PrepareQuit();
|
||||||
virtual void _GetLooperName(char* name, size_t size);
|
virtual void _GetLooperName(char* name, size_t size);
|
||||||
|
|
||||||
static bool _SupportsDirectMode();
|
|
||||||
status_t _EnableDirectWindowMode();
|
status_t _EnableDirectWindowMode();
|
||||||
|
void _DirectWindowSetFullScreen(bool set);
|
||||||
|
|
||||||
void _SetCurrentView(View* view);
|
void _SetCurrentView(View* view);
|
||||||
void _UpdateDrawState(View* view);
|
void _UpdateDrawState(View* view);
|
||||||
@@ -137,8 +143,6 @@ private:
|
|||||||
bool _MessageNeedsAllWindowsLocked(
|
bool _MessageNeedsAllWindowsLocked(
|
||||||
uint32 code) const;
|
uint32 code) const;
|
||||||
|
|
||||||
void _DirectWindowSetFullScreen(bool set);
|
|
||||||
|
|
||||||
// TODO: Move me elsewhere
|
// TODO: Move me elsewhere
|
||||||
status_t PictureToRegion(ServerPicture *picture,
|
status_t PictureToRegion(ServerPicture *picture,
|
||||||
BRegion& region, bool inverse,
|
BRegion& region, bool inverse,
|
||||||
@@ -171,6 +175,7 @@ private:
|
|||||||
bool fCurrentDrawingRegionValid;
|
bool fCurrentDrawingRegionValid;
|
||||||
|
|
||||||
DirectWindowData* fDirectWindowData;
|
DirectWindowData* fDirectWindowData;
|
||||||
|
bool fIsDirectlyAccessing;
|
||||||
window_feel fDirectWindowFeel;
|
window_feel fDirectWindowFeel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+28
-29
@@ -77,6 +77,7 @@ Window::Window(const BRect& frame, const char *name,
|
|||||||
:
|
:
|
||||||
fTitle(name),
|
fTitle(name),
|
||||||
fFrame(frame),
|
fFrame(frame),
|
||||||
|
fScreen(NULL),
|
||||||
|
|
||||||
fVisibleRegion(),
|
fVisibleRegion(),
|
||||||
fVisibleContentRegion(),
|
fVisibleContentRegion(),
|
||||||
@@ -213,8 +214,6 @@ Window::SetClipping(BRegion* stillAvailableOnScreen)
|
|||||||
|
|
||||||
fVisibleContentRegionValid = false;
|
fVisibleContentRegionValid = false;
|
||||||
fEffectiveDrawingRegionValid = false;
|
fEffectiveDrawingRegionValid = false;
|
||||||
|
|
||||||
fWindow->HandleDirectConnection(B_DIRECT_MODIFY | B_CLIPPING_MODIFIED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -562,13 +561,19 @@ Window::PreviousWindow(int32 index) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
::Screen*
|
void
|
||||||
|
Window::SetScreen(const ::Screen* screen)
|
||||||
|
{
|
||||||
|
ASSERT_MULTI_WRITE_LOCKED(fDesktop->ScreenLocker());
|
||||||
|
fScreen = screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const ::Screen*
|
||||||
Window::Screen() const
|
Window::Screen() const
|
||||||
{
|
{
|
||||||
ASSERT_MULTI_LOCKED(fDesktop->WindowLocker());
|
ASSERT_MULTI_READ_LOCKED(fDesktop->ScreenLocker());
|
||||||
|
return fScreen;
|
||||||
// TODO: we need to know which screen the window is on
|
|
||||||
return fDesktop->VirtualScreen().ScreenAt(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1215,18 +1220,12 @@ Window::_AlterDeltaForSnap(BPoint& delta, bigtime_t now)
|
|||||||
void
|
void
|
||||||
Window::WorkspaceActivated(int32 index, bool active)
|
Window::WorkspaceActivated(int32 index, bool active)
|
||||||
{
|
{
|
||||||
if (!active && !IsHidden())
|
|
||||||
fWindow->HandleDirectConnection(B_DIRECT_STOP);
|
|
||||||
|
|
||||||
BMessage activatedMsg(B_WORKSPACE_ACTIVATED);
|
BMessage activatedMsg(B_WORKSPACE_ACTIVATED);
|
||||||
activatedMsg.AddInt64("when", system_time());
|
activatedMsg.AddInt64("when", system_time());
|
||||||
activatedMsg.AddInt32("workspace", index);
|
activatedMsg.AddInt32("workspace", index);
|
||||||
activatedMsg.AddBool("active", active);
|
activatedMsg.AddBool("active", active);
|
||||||
|
|
||||||
ServerWindow()->SendMessageToClient(&activatedMsg);
|
ServerWindow()->SendMessageToClient(&activatedMsg);
|
||||||
|
|
||||||
if (active && !IsHidden())
|
|
||||||
fWindow->HandleDirectConnection(B_DIRECT_START | B_BUFFER_RESET);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1338,8 +1337,8 @@ Window::IsVisible() const
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Window::SetSizeLimits(int32 minWidth, int32 maxWidth,
|
Window::SetSizeLimits(int32 minWidth, int32 maxWidth, int32 minHeight,
|
||||||
int32 minHeight, int32 maxHeight)
|
int32 maxHeight)
|
||||||
{
|
{
|
||||||
if (minWidth < 0)
|
if (minWidth < 0)
|
||||||
minWidth = 0;
|
minWidth = 0;
|
||||||
@@ -1354,8 +1353,8 @@ Window::SetSizeLimits(int32 minWidth, int32 maxWidth,
|
|||||||
|
|
||||||
// give the Decorator a say in this too
|
// give the Decorator a say in this too
|
||||||
if (fDecorator) {
|
if (fDecorator) {
|
||||||
fDecorator->GetSizeLimits(&fMinWidth, &fMinHeight,
|
fDecorator->GetSizeLimits(&fMinWidth, &fMinHeight, &fMaxWidth,
|
||||||
&fMaxWidth, &fMaxHeight);
|
&fMaxHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ObeySizeLimits();
|
_ObeySizeLimits();
|
||||||
@@ -1455,7 +1454,8 @@ Window::SetLook(window_look look, BRegion* updateRegion)
|
|||||||
fDecorator->SetLook(settings, look, updateRegion);
|
fDecorator->SetLook(settings, look, updateRegion);
|
||||||
|
|
||||||
// we might need to resize the window!
|
// we might need to resize the window!
|
||||||
fDecorator->GetSizeLimits(&fMinWidth, &fMinHeight, &fMaxWidth, &fMaxHeight);
|
fDecorator->GetSizeLimits(&fMinWidth, &fMinHeight, &fMaxWidth,
|
||||||
|
&fMaxHeight);
|
||||||
_ObeySizeLimits();
|
_ObeySizeLimits();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1471,8 +1471,10 @@ void
|
|||||||
Window::SetFeel(window_feel feel)
|
Window::SetFeel(window_feel feel)
|
||||||
{
|
{
|
||||||
// if the subset list is no longer needed, clear it
|
// if the subset list is no longer needed, clear it
|
||||||
if ((fFeel == B_MODAL_SUBSET_WINDOW_FEEL || fFeel == B_FLOATING_SUBSET_WINDOW_FEEL)
|
if ((fFeel == B_MODAL_SUBSET_WINDOW_FEEL
|
||||||
&& (feel != B_MODAL_SUBSET_WINDOW_FEEL && feel != B_FLOATING_SUBSET_WINDOW_FEEL))
|
|| fFeel == B_FLOATING_SUBSET_WINDOW_FEEL)
|
||||||
|
&& feel != B_MODAL_SUBSET_WINDOW_FEEL
|
||||||
|
&& feel != B_FLOATING_SUBSET_WINDOW_FEEL)
|
||||||
fSubsets.MakeEmpty();
|
fSubsets.MakeEmpty();
|
||||||
|
|
||||||
fFeel = feel;
|
fFeel = feel;
|
||||||
@@ -1793,8 +1795,7 @@ Window::InSubsetWorkspace(int32 index) const
|
|||||||
// #pragma mark - static
|
// #pragma mark - static
|
||||||
|
|
||||||
|
|
||||||
/*static*/
|
/*static*/ bool
|
||||||
bool
|
|
||||||
Window::IsValidLook(window_look look)
|
Window::IsValidLook(window_look look)
|
||||||
{
|
{
|
||||||
return look == B_TITLED_WINDOW_LOOK
|
return look == B_TITLED_WINDOW_LOOK
|
||||||
@@ -1808,8 +1809,7 @@ Window::IsValidLook(window_look look)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*static*/
|
/*static*/ bool
|
||||||
bool
|
|
||||||
Window::IsValidFeel(window_feel feel)
|
Window::IsValidFeel(window_feel feel)
|
||||||
{
|
{
|
||||||
return feel == B_NORMAL_WINDOW_FEEL
|
return feel == B_NORMAL_WINDOW_FEEL
|
||||||
@@ -1826,8 +1826,7 @@ Window::IsValidFeel(window_feel feel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*static*/
|
/*static*/ bool
|
||||||
bool
|
|
||||||
Window::IsModalFeel(window_feel feel)
|
Window::IsModalFeel(window_feel feel)
|
||||||
{
|
{
|
||||||
return feel == B_MODAL_SUBSET_WINDOW_FEEL
|
return feel == B_MODAL_SUBSET_WINDOW_FEEL
|
||||||
@@ -1836,8 +1835,7 @@ Window::IsModalFeel(window_feel feel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*static*/
|
/*static*/ bool
|
||||||
bool
|
|
||||||
Window::IsFloatingFeel(window_feel feel)
|
Window::IsFloatingFeel(window_feel feel)
|
||||||
{
|
{
|
||||||
return feel == B_FLOATING_SUBSET_WINDOW_FEEL
|
return feel == B_FLOATING_SUBSET_WINDOW_FEEL
|
||||||
@@ -2115,7 +2113,8 @@ Window::BeginUpdate(BPrivate::PortLink& link)
|
|||||||
// supress back to front buffer copies in the drawing engine
|
// supress back to front buffer copies in the drawing engine
|
||||||
fDrawingEngine->SetCopyToFrontEnabled(false);
|
fDrawingEngine->SetCopyToFrontEnabled(false);
|
||||||
|
|
||||||
if (!fCurrentUpdateSession->IsExpose() && fDrawingEngine->LockParallelAccess()) {
|
if (!fCurrentUpdateSession->IsExpose()
|
||||||
|
&& fDrawingEngine->LockParallelAccess()) {
|
||||||
fDrawingEngine->SuspendAutoSync();
|
fDrawingEngine->SuspendAutoSync();
|
||||||
|
|
||||||
fTopView->Draw(fDrawingEngine, dirty, &fContentRegion, true);
|
fTopView->Draw(fDrawingEngine, dirty, &fContentRegion, true);
|
||||||
|
|||||||
@@ -67,7 +67,8 @@ public:
|
|||||||
::EventTarget& EventTarget() const
|
::EventTarget& EventTarget() const
|
||||||
{ return fWindow->EventTarget(); }
|
{ return fWindow->EventTarget(); }
|
||||||
|
|
||||||
::Screen* Screen() const;
|
void SetScreen(const ::Screen* screen);
|
||||||
|
const ::Screen* Screen() const;
|
||||||
|
|
||||||
// setting and getting the "hard" clipping, you need to have
|
// setting and getting the "hard" clipping, you need to have
|
||||||
// WriteLock()ed the clipping!
|
// WriteLock()ed the clipping!
|
||||||
@@ -234,18 +235,15 @@ public:
|
|||||||
void FindWorkspacesViews(
|
void FindWorkspacesViews(
|
||||||
BObjectList<WorkspacesView>& list) const;
|
BObjectList<WorkspacesView>& list) const;
|
||||||
|
|
||||||
static bool IsValidLook(window_look look);
|
static bool IsValidLook(window_look look);
|
||||||
static bool IsValidFeel(window_feel feel);
|
static bool IsValidFeel(window_feel feel);
|
||||||
static bool IsModalFeel(window_feel feel);
|
static bool IsModalFeel(window_feel feel);
|
||||||
static bool IsFloatingFeel(window_feel feel);
|
static bool IsFloatingFeel(window_feel feel);
|
||||||
|
|
||||||
static uint32 ValidWindowFlags();
|
static uint32 ValidWindowFlags();
|
||||||
static uint32 ValidWindowFlags(window_feel feel);
|
static uint32 ValidWindowFlags(window_feel feel);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Desktop;
|
|
||||||
// TODO: for now (list management)
|
|
||||||
|
|
||||||
void _ShiftPartOfRegion(BRegion* region,
|
void _ShiftPartOfRegion(BRegion* region,
|
||||||
BRegion* regionToShift, int32 xOffset,
|
BRegion* regionToShift, int32 xOffset,
|
||||||
int32 yOffset);
|
int32 yOffset);
|
||||||
@@ -278,6 +276,7 @@ protected:
|
|||||||
BString fTitle;
|
BString fTitle;
|
||||||
// TODO: no fp rects anywhere
|
// TODO: no fp rects anywhere
|
||||||
BRect fFrame;
|
BRect fFrame;
|
||||||
|
const ::Screen* fScreen;
|
||||||
|
|
||||||
window_anchor fAnchor[kListCount];
|
window_anchor fAnchor[kListCount];
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user