* Copyright 2010, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Clemens Zeidler <haiku@clemens-zeidler.de>
*/
#include "WindowStack.h"
#include <new>
#include <Window.h>
#include <ApplicationPrivate.h>
#include <MessengerPrivate.h>
#include <PortLink.h>
#include <ServerProtocol.h>
#include "StackAndTilePrivate.h"
using namespace BPrivate;
BWindowStack::BWindowStack(BWindow* window)
{
fLink = window->fLink;
}
BWindowStack::~BWindowStack()
{
}
status_t
BWindowStack::AddWindow(const BWindow* window)
{
BMessenger messenger(window);
return AddWindow(messenger);
}
status_t
BWindowStack::AddWindow(const BMessenger& window)
{
return AddWindowAt(window, -1);
}
status_t
BWindowStack::AddWindowAt(const BWindow* window, int32 position)
{
BMessenger messenger(window);
return AddWindowAt(messenger, position);
}
status_t
BWindowStack::AddWindowAt(const BMessenger& window, int32 position)
{
_StartMessage(kAddWindowToStack);
_AttachMessenger(window);
fLink->Attach<int32>(position);
int32 code = B_ERROR;
if (fLink->FlushWithReply(code) != B_OK)
return code;
return B_OK;
}
status_t
BWindowStack::RemoveWindow(const BWindow* window)
{
BMessenger messenger(window);
return RemoveWindow(messenger);
}
status_t
BWindowStack::RemoveWindow(const BMessenger& window)
{
_StartMessage(kRemoveWindowFromStack);
_AttachMessenger(window);
if (fLink->Flush() != B_OK)
return B_ERROR;
return B_OK;
}
status_t
BWindowStack::RemoveWindowAt(int32 position, BMessenger* window)
{
_StartMessage(kRemoveWindowFromStackAt);
fLink->Attach<int32>(position);
int32 code = B_ERROR;
if (fLink->FlushWithReply(code) != B_OK)
return code;
if (window == NULL)
return B_OK;
return _ReadMessenger(*window);
}
int32
BWindowStack::CountWindows()
{
_StartMessage(kCountWindowsOnStack);
int32 code = B_ERROR;
fLink->FlushWithReply(code);
if (code != B_OK)
return -1;
int32 count;
if (fLink->Read<int32>(&count) != B_OK)
return -1;
return count;
}
status_t
BWindowStack::WindowAt(int32 position, BMessenger& messenger)
{
_StartMessage(kWindowOnStackAt);
fLink->Attach<int32>(position);
int32 code = B_ERROR;
fLink->FlushWithReply(code);
if (code != B_OK)
return code;
return _ReadMessenger(messenger);
}
bool
BWindowStack::HasWindow(const BWindow* window)
{
BMessenger messenger(window);
return HasWindow(messenger);
}
bool
BWindowStack::HasWindow(const BMessenger& window)
{
_StartMessage(kStackHasWindow);
_AttachMessenger(window);
int32 code = B_ERROR;
fLink->FlushWithReply(code);
if (code != B_OK)
return false;
bool hasWindow;
if (fLink->Read<bool>(&hasWindow) != B_OK)
return false;
return hasWindow;
}
status_t
BWindowStack::_AttachMessenger(const BMessenger& window)
{
BMessenger::Private messengerPrivate(const_cast<BMessenger&>(window));
fLink->Attach<port_id>(messengerPrivate.Port());
fLink->Attach<int32>(messengerPrivate.Token());
return fLink->Attach<team_id>(messengerPrivate.Team());
}
status_t
BWindowStack::_ReadMessenger(BMessenger& window)
{
port_id port;
int32 token;
team_id team;
fLink->Read<port_id>(&port);
fLink->Read<int32>(&token);
status_t status = fLink->Read<team_id>(&team);
if (status != B_OK)
return status;
BMessenger::Private messengerPrivate(window);
messengerPrivate.SetTo(team, port, token);
return B_OK;
}
status_t
BWindowStack::_StartMessage(int32 what)
{
fLink->StartMessage(AS_TALK_TO_DESKTOP_LISTENER);
fLink->Attach<int32>(kMagicSATIdentifier);
fLink->Attach<int32>(kStacking);
return fLink->Attach<int32>(what);
}