From 5836cd75c258263c14eb31fb0a2d1d27dc3b1682 Mon Sep 17 00:00:00 2001 From: Clemens Zeidler Date: Tue, 17 Aug 2010 06:47:26 +0000 Subject: [PATCH] Add a BWindowStack interface class. Please review if adding a BWindowStack as a friend of BWindow in Window.h is ok. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38171 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/interface/Window.h | 1 + headers/private/interface/WindowStack.h | 44 +++++ src/kits/interface/Jamfile | 1 + src/kits/interface/WindowStack.cpp | 226 ++++++++++++++++++++++++ 4 files changed, 272 insertions(+) create mode 100644 headers/private/interface/WindowStack.h create mode 100644 src/kits/interface/WindowStack.cpp diff --git a/headers/os/interface/Window.h b/headers/os/interface/Window.h index 92e40b4881..621e86277f 100644 --- a/headers/os/interface/Window.h +++ b/headers/os/interface/Window.h @@ -285,6 +285,7 @@ private: friend class BWindowScreen; friend class BDirectWindow; friend class BFilePanel; + friend class BWindowStack; friend void _set_menu_sem_(BWindow* w, sem_id sem); friend status_t _safe_get_server_token_(const BLooper*, int32*); diff --git a/headers/private/interface/WindowStack.h b/headers/private/interface/WindowStack.h new file mode 100644 index 0000000000..170a0767a0 --- /dev/null +++ b/headers/private/interface/WindowStack.h @@ -0,0 +1,44 @@ +/* + * Copyright 2010, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef WINDOW_STACK_H +#define WINDOW_STACK_H + +#include + + +class BWindowStack +{ +public: + BWindowStack(BWindow* window); + ~BWindowStack(); + + status_t InitCheck(); + + status_t AddWindow(BWindow* window); + status_t AddWindow(BMessenger& window); + status_t AddWindowAt(BWindow* window, int32 position); + status_t AddWindowAt(BMessenger& window, int32 position); + + status_t RemoveWindow(BWindow* window); + status_t RemoveWindow(BMessenger& window); + status_t RemoveWindowAt(int32 position, + BMessenger* window = NULL); + + int32 CountWindows(); + + status_t WindowAt(int32 position, BMessenger& messenger); + bool HasWindow(BWindow* window); + bool HasWindow(BMessenger& window); + +private: + status_t _AttachMessenger(BMessenger& window); + status_t _ReadMessenger(BMessenger& window); + status_t _StartMessage(int32 what); + + BPrivate::PortLink* fLink; +}; + + +#endif diff --git a/src/kits/interface/Jamfile b/src/kits/interface/Jamfile index b3ef7c6162..182ce299ab 100644 --- a/src/kits/interface/Jamfile +++ b/src/kits/interface/Jamfile @@ -120,6 +120,7 @@ MergeObject interface_kit.o : View.cpp ViewLayoutItem.cpp Window.cpp + WindowStack.cpp ZombieReplicantView.cpp # BTextView support diff --git a/src/kits/interface/WindowStack.cpp b/src/kits/interface/WindowStack.cpp new file mode 100644 index 0000000000..183255e44e --- /dev/null +++ b/src/kits/interface/WindowStack.cpp @@ -0,0 +1,226 @@ +/* + * Copyright 2010, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Clemens Zeidler + */ + +#include "WindowStack.h" + +#include + +#include + +#include +#include +#include +#include + +#include "StackAndTilePrivate.h" + + +using namespace BPrivate; + + +BWindowStack::BWindowStack(BWindow* window) + : + fLink(NULL) +{ + port_id receivePort = create_port(B_LOOPER_PORT_DEFAULT_CAPACITY, + "w_stackfLink->SenderPort(), receivePort); +} + + +BWindowStack::~BWindowStack() +{ + if (fLink) + delete_port(fLink->ReceiverPort()); + delete fLink; +} + + +status_t +BWindowStack::InitCheck() +{ + if (!fLink) + return B_NO_MEMORY; + return B_OK; +} + + +status_t +BWindowStack::AddWindow(BWindow* window) +{ + BMessenger messenger(window); + return AddWindow(messenger); +} + + +status_t +BWindowStack::AddWindow(BMessenger& window) +{ + return AddWindowAt(window, -1); +} + + +status_t +BWindowStack::AddWindowAt(BWindow* window, int32 position) +{ + BMessenger messenger(window); + return AddWindowAt(messenger, position); +} + + +status_t +BWindowStack::AddWindowAt(BMessenger& window, int32 position) +{ + _StartMessage(kAddWindowToStack); + + _AttachMessenger(window); + fLink->Attach(position); + + int32 code = B_ERROR; + if (fLink->FlushWithReply(code) != B_OK) + return code; + + return B_OK; +} + + +status_t +BWindowStack::RemoveWindow(BWindow* window) +{ + BMessenger messenger(window); + return RemoveWindow(messenger); +} + + +status_t +BWindowStack::RemoveWindow(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(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(&count) != B_OK) + return -1; + + return count; +} + + +status_t +BWindowStack::WindowAt(int32 position, BMessenger& messenger) +{ + _StartMessage(kWindowOnStackAt); + fLink->Attach(position); + + int32 code = B_ERROR; + fLink->FlushWithReply(code); + if (code != B_OK) + return code; + + return _ReadMessenger(messenger); +} + + +bool +BWindowStack::HasWindow(BWindow* window) +{ + BMessenger messenger(window); + return HasWindow(messenger); +} + + +bool +BWindowStack::HasWindow(BMessenger& window) +{ + _StartMessage(kStackHasWindow); + _AttachMessenger(window); + + int32 code = B_ERROR; + fLink->FlushWithReply(code); + if (code != B_OK) + return code; + + bool hasWindow; + if (fLink->Read(&hasWindow) != B_OK) + return false; + + return hasWindow; +} + + +status_t +BWindowStack::_AttachMessenger(BMessenger& window) +{ + BMessenger::Private messengerPrivate(window); + fLink->Attach(messengerPrivate.Port()); + fLink->Attach(messengerPrivate.Token()); + return fLink->Attach(messengerPrivate.Team()); +} + + +status_t +BWindowStack::_ReadMessenger(BMessenger& window) +{ + port_id port; + int32 token; + team_id team; + fLink->Read(&port); + fLink->Read(&token); + status_t status = fLink->Read(&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(fLink->ReceiverPort()); + fLink->Attach(kMagicSATIdentifier); + return fLink->Attach(what); +}