1 /* 2 * Copyright 2010, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Clemens Zeidler <haiku@clemens-zeidler.de> 7 */ 8 9 10 #include "WindowStack.h" 11 12 #include <new> 13 14 #include <Window.h> 15 16 #include <ApplicationPrivate.h> 17 #include <MessengerPrivate.h> 18 #include <PortLink.h> 19 #include <ServerProtocol.h> 20 21 #include "StackAndTilePrivate.h" 22 23 24 using namespace BPrivate; 25 26 27 BWindowStack::BWindowStack(BWindow* window) 28 { 29 fLink = window->fLink; 30 } 31 32 33 BWindowStack::~BWindowStack() 34 { 35 36 } 37 38 39 status_t 40 BWindowStack::AddWindow(const BWindow* window) 41 { 42 BMessenger messenger(window); 43 return AddWindow(messenger); 44 } 45 46 47 status_t 48 BWindowStack::AddWindow(const BMessenger& window) 49 { 50 return AddWindowAt(window, -1); 51 } 52 53 54 status_t 55 BWindowStack::AddWindowAt(const BWindow* window, int32 position) 56 { 57 BMessenger messenger(window); 58 return AddWindowAt(messenger, position); 59 } 60 61 62 status_t 63 BWindowStack::AddWindowAt(const BMessenger& window, int32 position) 64 { 65 _StartMessage(kAddWindowToStack); 66 67 _AttachMessenger(window); 68 fLink->Attach<int32>(position); 69 70 int32 code = B_ERROR; 71 if (fLink->FlushWithReply(code) != B_OK) 72 return code; 73 74 return B_OK; 75 } 76 77 78 status_t 79 BWindowStack::RemoveWindow(const BWindow* window) 80 { 81 BMessenger messenger(window); 82 return RemoveWindow(messenger); 83 } 84 85 86 status_t 87 BWindowStack::RemoveWindow(const BMessenger& window) 88 { 89 _StartMessage(kRemoveWindowFromStack); 90 _AttachMessenger(window); 91 92 if (fLink->Flush() != B_OK) 93 return B_ERROR; 94 95 return B_OK; 96 } 97 98 99 status_t 100 BWindowStack::RemoveWindowAt(int32 position, BMessenger* window) 101 { 102 _StartMessage(kRemoveWindowFromStackAt); 103 fLink->Attach<int32>(position); 104 105 int32 code = B_ERROR; 106 if (fLink->FlushWithReply(code) != B_OK) 107 return code; 108 109 if (window == NULL) 110 return B_OK; 111 112 return _ReadMessenger(*window); 113 } 114 115 116 int32 117 BWindowStack::CountWindows() 118 { 119 _StartMessage(kCountWindowsOnStack); 120 121 int32 code = B_ERROR; 122 fLink->FlushWithReply(code); 123 if (code != B_OK) 124 return -1; 125 126 int32 count; 127 if (fLink->Read<int32>(&count) != B_OK) 128 return -1; 129 130 return count; 131 } 132 133 134 status_t 135 BWindowStack::WindowAt(int32 position, BMessenger& messenger) 136 { 137 _StartMessage(kWindowOnStackAt); 138 fLink->Attach<int32>(position); 139 140 int32 code = B_ERROR; 141 fLink->FlushWithReply(code); 142 if (code != B_OK) 143 return code; 144 145 return _ReadMessenger(messenger); 146 } 147 148 149 bool 150 BWindowStack::HasWindow(const BWindow* window) 151 { 152 BMessenger messenger(window); 153 return HasWindow(messenger); 154 } 155 156 157 bool 158 BWindowStack::HasWindow(const BMessenger& window) 159 { 160 _StartMessage(kStackHasWindow); 161 _AttachMessenger(window); 162 163 int32 code = B_ERROR; 164 fLink->FlushWithReply(code); 165 if (code != B_OK) 166 return false; 167 168 bool hasWindow; 169 if (fLink->Read<bool>(&hasWindow) != B_OK) 170 return false; 171 172 return hasWindow; 173 } 174 175 176 status_t 177 BWindowStack::_AttachMessenger(const BMessenger& window) 178 { 179 BMessenger::Private messengerPrivate(const_cast<BMessenger&>(window)); 180 fLink->Attach<port_id>(messengerPrivate.Port()); 181 fLink->Attach<int32>(messengerPrivate.Token()); 182 return fLink->Attach<team_id>(messengerPrivate.Team()); 183 } 184 185 186 status_t 187 BWindowStack::_ReadMessenger(BMessenger& window) 188 { 189 port_id port; 190 int32 token; 191 team_id team; 192 fLink->Read<port_id>(&port); 193 fLink->Read<int32>(&token); 194 status_t status = fLink->Read<team_id>(&team); 195 if (status != B_OK) 196 return status; 197 BMessenger::Private messengerPrivate(window); 198 messengerPrivate.SetTo(team, port, token); 199 return B_OK; 200 } 201 202 203 status_t 204 BWindowStack::_StartMessage(int32 what) 205 { 206 fLink->StartMessage(AS_TALK_TO_DESKTOP_LISTENER); 207 fLink->Attach<int32>(kMagicSATIdentifier); 208 fLink->Attach<int32>(kStacking); 209 return fLink->Attach<int32>(what); 210 } 211