btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / apps / cortex / ParameterView / ParameterWindowManager.cpp
blob1395e341b473740206301ae95074b1faf84837c5
1 /*
2 * Copyright (c) 1999-2000, Eric Moon.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions, and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 // ParameterWindowManager.cpp
34 #include "ParameterWindowManager.h"
35 #include "ParameterWindow.h"
36 // NodeManager
37 #include "NodeRef.h"
39 // Application Kit
40 #include <AppDefs.h>
41 // Media Kit
42 #include <MediaRoster.h>
43 // Support Kit
44 #include <List.h>
46 __USE_CORTEX_NAMESPACE
48 #include <Debug.h>
49 #define D_ACCESS(x) //PRINT (x)
50 #define D_ALLOC(x) //PRINT (x)
51 #define D_INTERNAL(x) //PRINT (x)
52 #define D_MESSAGE(x) //PRINT (x)
53 #define D_WINDOW(x) //PRINT (x)
55 // -------------------------------------------------------- //
56 // internal types
57 // -------------------------------------------------------- //
59 // used to remember the list of ParameterWindows
60 struct window_map_entry {
62 public: // *** ctor/dtor
64 window_map_entry(
65 const NodeRef *ref,
66 BWindow *window)
67 : ref(ref),
68 window(window)
69 { }
71 public: // *** data members
73 const NodeRef *ref;
75 BWindow *window;
78 // used to remember the list of ControlPanels
79 struct panel_map_entry {
81 public: // *** ctor/dtor
83 panel_map_entry(
84 int32 id,
85 const BMessenger &messenger)
86 : id(id),
87 messenger(messenger)
88 { }
90 public: // *** data members
92 int32 id;
94 const BMessenger messenger;
97 // -------------------------------------------------------- //
98 // static member init
99 // -------------------------------------------------------- //
101 const BPoint ParameterWindowManager::M_DEFAULT_OFFSET = BPoint(20.0, 20.0);
102 const BPoint ParameterWindowManager::M_INIT_POSITION = BPoint(90.0, 90.0);
104 ParameterWindowManager *ParameterWindowManager::s_instance = 0;
106 // -------------------------------------------------------- //
107 // *** ctor/dtor
108 // -------------------------------------------------------- //
110 /* hidden */
111 ParameterWindowManager::ParameterWindowManager()
112 : BLooper("ParameterWindowManager",
113 B_NORMAL_PRIORITY),
114 m_windowList(0),
115 m_panelList(0),
116 m_lastWindowPosition(M_INIT_POSITION - M_DEFAULT_OFFSET) {
117 D_ALLOC(("ParameterWindowManager::ParameterWindowManager()\n"));
119 m_windowList = new BList();
120 m_panelList = new BList();
121 Run();
124 ParameterWindowManager::~ParameterWindowManager() {
125 D_ALLOC(("ParameterWindowManager::~ParameterWindowManager()\n"));
127 while (m_windowList->CountItems() > 0) {
128 window_map_entry *entry = static_cast<window_map_entry *>
129 (m_windowList->ItemAt(0));
130 if (entry && entry->window) {
131 remove_observer(this, entry->ref);
132 entry->window->Lock();
133 entry->window->Quit();
135 m_windowList->RemoveItem(reinterpret_cast<void *>(entry));
136 delete entry;
138 delete m_windowList;
140 while (m_panelList->CountItems() > 0) {
141 panel_map_entry *entry = static_cast<panel_map_entry *>
142 (m_panelList->ItemAt(0));
143 if (entry && entry->messenger.IsValid()) {
144 entry->messenger.SendMessage(B_QUIT_REQUESTED);
146 m_panelList->RemoveItem(reinterpret_cast<void *>(entry));
147 delete entry;
149 delete m_panelList;
151 s_instance = 0;
154 // -------------------------------------------------------- //
155 // *** singleton access
156 // -------------------------------------------------------- //
158 /*static*/
159 ParameterWindowManager *ParameterWindowManager::Instance() {
160 D_ACCESS(("ParameterWindowManager::Instance()\n"));
162 if (!s_instance) {
163 D_ACCESS((" -> create instance\n"));
164 s_instance = new ParameterWindowManager();
167 return s_instance;
170 /* static */
171 void ParameterWindowManager::shutDown() {
172 D_WINDOW(("ParameterWindowManager::shutDown()\n"));
174 if (s_instance) {
175 s_instance->Lock();
176 s_instance->Quit();
180 // -------------------------------------------------------- //
181 // *** operations
182 // -------------------------------------------------------- //
184 status_t ParameterWindowManager::openWindowFor(
185 const NodeRef *ref) {
186 D_WINDOW(("ParameterWindowManager::openWindowFor()\n"));
188 // make absolutely sure we're locked
189 if (!IsLocked()) {
190 debugger("The looper must be locked !");
193 // make sure the ref is valid
194 if (!ref) {
195 return B_ERROR;
198 BWindow *window = 0;
199 if (_findWindowFor(ref->id(), &window)) {
200 // window for this node already exists, activate it
201 window->SetWorkspaces(B_CURRENT_WORKSPACE);
202 window->Activate();
203 return B_OK;
206 BMessenger messenger(0, this);
207 live_node_info nodeInfo = ref->nodeInfo();
208 m_lastWindowPosition += M_DEFAULT_OFFSET;
209 window = new ParameterWindow(m_lastWindowPosition,
210 nodeInfo, &messenger);
211 if (_addWindowFor(ref, window)) {
212 window->Show();
213 return B_OK;
215 delete window;
217 return B_ERROR;
220 status_t ParameterWindowManager::startControlPanelFor(
221 const NodeRef *ref) {
222 D_WINDOW(("ParameterWindowManager::startControlPanelFor()\n"));
224 // make absolutely sure we're locked
225 if (!IsLocked()) {
226 debugger("The looper must be locked !");
229 BMediaRoster *roster = BMediaRoster::CurrentRoster();
230 if (!roster) {
231 D_WINDOW((" -> MediaRoster not available\n"));
232 return B_ERROR;
235 BMessenger messenger;
236 if (_findPanelFor(ref->id(), &messenger)) {
237 // find out if the messengers target still exists
238 if (messenger.IsValid()) {
239 return B_OK;
241 else {
242 _removePanelFor(ref->id());
246 status_t error = roster->StartControlPanel(ref->node(),
247 &messenger);
248 if (error) {
249 D_INTERNAL((" -> StartControlPanel() failed (%s)\n",
250 strerror(error)));
251 return error;
254 _addPanelFor(ref->id(), messenger);
255 return B_OK;
258 // -------------------------------------------------------- //
259 // *** BLooper impl
260 // -------------------------------------------------------- //
262 void ParameterWindowManager::MessageReceived(
263 BMessage *message) {
264 D_MESSAGE(("ParameterWindowManager::MessageReceived()\n"));
266 switch (message->what) {
267 case ParameterWindow::M_CLOSED: {
268 D_MESSAGE((" -> ParameterWindow::M_CLOSED\n"));
269 int32 nodeID;
270 if (message->FindInt32("nodeID", &nodeID) != B_OK) {
271 return;
273 _removeWindowFor(nodeID);
274 break;
276 case ParameterWindow::M_CONTROL_PANEL_STARTED: {
277 D_MESSAGE((" -> ParameterWindow::M_CONTROL_PANEL_STARTED\n"));
278 int32 nodeID;
279 if (message->FindInt32("nodeID", &nodeID) != B_OK) {
280 return;
282 BMessenger messenger;
283 if (message->FindMessenger("messenger", &messenger) != B_OK) {
284 return;
286 _addPanelFor(nodeID, messenger);
287 break;
289 case NodeRef::M_RELEASED: {
290 D_MESSAGE((" -> NodeRef::M_RELEASED\n"));
291 int32 nodeID;
292 if (message->FindInt32("nodeID", &nodeID) != B_OK) {
293 return;
295 BWindow *window;
296 if (_findWindowFor(nodeID, &window)) {
297 window->Lock();
298 window->Quit();
299 _removeWindowFor(nodeID);
301 break;
303 default: {
304 BLooper::MessageReceived(message);
309 // -------------------------------------------------------- //
310 // *** internal operations
311 // -------------------------------------------------------- //
313 bool ParameterWindowManager::_addWindowFor(
314 const NodeRef *ref,
315 BWindow *window) {
316 D_INTERNAL(("ParameterWindowManager::_addWindowFor()\n"));
318 window_map_entry *entry = new window_map_entry(ref,
319 window);
320 if (m_windowList->AddItem(reinterpret_cast<void *>(entry))) {
321 add_observer(this, entry->ref);
322 return true;
325 return false;
328 bool ParameterWindowManager::_findWindowFor(
329 int32 id,
330 BWindow **outWindow) {
331 D_INTERNAL(("ParameterWindowManager::_findWindowFor()\n"));
333 for (int32 i = 0; i < m_windowList->CountItems(); i++) {
334 window_map_entry *entry = static_cast<window_map_entry *>
335 (m_windowList->ItemAt(i));
336 if (entry->ref->id() == id) {
337 *outWindow = entry->window;
338 return true;
342 return false;
345 void ParameterWindowManager::_removeWindowFor(
346 int32 id) {
347 D_INTERNAL(("ParameterWindowManager::_removeWindowFor()\n"));
349 for (int32 i = 0; i < m_windowList->CountItems(); i++) {
350 window_map_entry *entry = static_cast<window_map_entry *>
351 (m_windowList->ItemAt(i));
352 if (entry->ref->id() == id) {
353 m_windowList->RemoveItem(reinterpret_cast<void *>(entry));
354 remove_observer(this, entry->ref);
355 delete entry;
359 // try to shutdown
360 if (m_windowList->CountItems() == 0) {
361 int32 i = 0;
362 while (true) {
363 // take all invalid messengers out of the panel list
364 panel_map_entry *entry = static_cast<panel_map_entry *>
365 (m_panelList->ItemAt(i));
366 if (!entry) {
367 // end of list
368 break;
370 if (!entry->messenger.IsValid()) {
371 // this control panel doesn't exist anymore
372 m_panelList->RemoveItem(entry);
373 continue;
376 if (m_panelList->CountItems() == 0) {
377 // neither windows nor panels to manage, go to sleep
378 PostMessage(B_QUIT_REQUESTED);
383 bool ParameterWindowManager::_addPanelFor(
384 int32 id,
385 const BMessenger &messenger) {
386 D_INTERNAL(("ParameterWindowManager::_addPanelFor()\n"));
388 panel_map_entry *entry = new panel_map_entry(id,
389 messenger);
390 if (m_panelList->AddItem(reinterpret_cast<void *>(entry))) {
391 return true;
394 return false;
397 bool ParameterWindowManager::_findPanelFor(
398 int32 id,
399 BMessenger *outMessenger) {
400 D_INTERNAL(("ParameterWindowManager::_findPanelFor()\n"));
402 for (int32 i = 0; i < m_panelList->CountItems(); i++) {
403 panel_map_entry *entry = static_cast<panel_map_entry *>
404 (m_panelList->ItemAt(i));
405 if (entry->id == id) {
406 *outMessenger = entry->messenger;
407 return true;
411 return false;
414 void ParameterWindowManager::_removePanelFor(
415 int32 id) {
416 D_INTERNAL(("ParameterWindowManager::_removeWindowFor()\n"));
418 for (int32 i = 0; i < m_panelList->CountItems(); i++) {
419 panel_map_entry *entry = static_cast<panel_map_entry *>
420 (m_panelList->ItemAt(i));
421 if (entry->id == id) {
422 m_panelList->RemoveItem(reinterpret_cast<void *>(entry));
423 delete entry;
428 // END -- ParameterWindowManager.cpp --