xref: /haiku/src/kits/interface/WindowStack.cpp (revision 220d04022750f40f8bac8f01fa551211e28d04f2)
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