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
BWindowStack(BWindow * window)27 BWindowStack::BWindowStack(BWindow* window)
28 {
29 fLink = window->fLink;
30 }
31
32
~BWindowStack()33 BWindowStack::~BWindowStack()
34 {
35
36 }
37
38
39 status_t
AddWindow(const BWindow * window)40 BWindowStack::AddWindow(const BWindow* window)
41 {
42 BMessenger messenger(window);
43 return AddWindow(messenger);
44 }
45
46
47 status_t
AddWindow(const BMessenger & window)48 BWindowStack::AddWindow(const BMessenger& window)
49 {
50 return AddWindowAt(window, -1);
51 }
52
53
54 status_t
AddWindowAt(const BWindow * window,int32 position)55 BWindowStack::AddWindowAt(const BWindow* window, int32 position)
56 {
57 BMessenger messenger(window);
58 return AddWindowAt(messenger, position);
59 }
60
61
62 status_t
AddWindowAt(const BMessenger & window,int32 position)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
RemoveWindow(const BWindow * window)79 BWindowStack::RemoveWindow(const BWindow* window)
80 {
81 BMessenger messenger(window);
82 return RemoveWindow(messenger);
83 }
84
85
86 status_t
RemoveWindow(const BMessenger & window)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
RemoveWindowAt(int32 position,BMessenger * window)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
CountWindows()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
WindowAt(int32 position,BMessenger & messenger)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
HasWindow(const BWindow * window)150 BWindowStack::HasWindow(const BWindow* window)
151 {
152 BMessenger messenger(window);
153 return HasWindow(messenger);
154 }
155
156
157 bool
HasWindow(const BMessenger & window)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
_AttachMessenger(const BMessenger & window)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
_ReadMessenger(BMessenger & window)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
_StartMessage(int32 what)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