xref: /haiku/src/servers/app/ScreenManager.cpp (revision cf02b29e4e0dd6d61c4bb25fcc8620e99d4908bf)
1 /*
2  * Copyright 2005-2009, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Axel Dörfler, axeld@pinc-software.de
7  */
8 
9 /**	Manages all available physical screens */
10 
11 
12 #include "ScreenManager.h"
13 
14 #include "Screen.h"
15 #include "ServerConfig.h"
16 
17 #include <Autolock.h>
18 #include <Entry.h>
19 #include <NodeMonitor.h>
20 
21 #include <new>
22 
23 using std::nothrow;
24 
25 
26 #ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST
27 #	include "AccelerantHWInterface.h"
28 #else
29 #	include "ViewHWInterface.h"
30 #	include "DWindowHWInterface.h"
31 #endif
32 
33 
34 ScreenManager* gScreenManager;
35 
36 
37 ScreenManager::ScreenManager()
38 	:
39 	BLooper("screen manager"),
40 	fScreenList(4)
41 {
42 	_ScanDrivers();
43 
44 	// turn on node monitoring the graphics driver directory
45 	BEntry entry("/dev/graphics");
46 	node_ref nodeRef;
47 	if (entry.InitCheck() == B_OK && entry.GetNodeRef(&nodeRef) == B_OK)
48 		watch_node(&nodeRef, B_WATCH_DIRECTORY, this);
49 }
50 
51 
52 ScreenManager::~ScreenManager()
53 {
54 	for (int32 i = 0; i < fScreenList.CountItems(); i++) {
55 		screen_item* item = fScreenList.ItemAt(i);
56 
57 		delete item->screen;
58 		delete item;
59 	}
60 }
61 
62 
63 Screen*
64 ScreenManager::ScreenAt(int32 index) const
65 {
66 	if (!IsLocked())
67 		debugger("Called ScreenManager::ScreenAt() without lock!");
68 
69 	screen_item* item = fScreenList.ItemAt(index);
70 	if (item != NULL)
71 		return item->screen;
72 
73 	return NULL;
74 }
75 
76 
77 int32
78 ScreenManager::CountScreens() const
79 {
80 	if (!IsLocked())
81 		debugger("Called ScreenManager::CountScreens() without lock!");
82 
83 	return fScreenList.CountItems();
84 }
85 
86 
87 status_t
88 ScreenManager::AcquireScreens(ScreenOwner* owner, int32* wishList,
89 	int32 wishCount, bool force, ScreenList& list)
90 {
91 	BAutolock locker(this);
92 	int32 added = 0;
93 
94 	// ToDo: don't ignore the wish list
95 
96 	for (int32 i = 0; i < fScreenList.CountItems(); i++) {
97 		screen_item* item = fScreenList.ItemAt(i);
98 
99 		if (item->owner == NULL && list.AddItem(item->screen)) {
100 			item->owner = owner;
101 			added++;
102 		}
103 	}
104 
105 	return added > 0 ? B_OK : B_ENTRY_NOT_FOUND;
106 }
107 
108 
109 void
110 ScreenManager::ReleaseScreens(ScreenList& list)
111 {
112 	BAutolock locker(this);
113 
114 	for (int32 i = 0; i < fScreenList.CountItems(); i++) {
115 		screen_item* item = fScreenList.ItemAt(i);
116 
117 		for (int32 j = 0; j < list.CountItems(); j++) {
118 			Screen* screen = list.ItemAt(j);
119 
120 			if (item->screen == screen)
121 				item->owner = NULL;
122 		}
123 	}
124 }
125 
126 
127 void
128 ScreenManager::_ScanDrivers()
129 {
130 	HWInterface* interface = NULL;
131 
132 	// Eventually we will loop through drivers until
133 	// one can't initialize in order to support multiple monitors.
134 	// For now, we'll just load one and be done with it.
135 
136 	// ToDo: to make monitoring the driver directory useful, we need more
137 	//	power and data here, and should do the scanning on our own
138 
139 	bool initDrivers = true;
140 	while (initDrivers) {
141 
142 #ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST
143 		  interface = new AccelerantHWInterface();
144 #elif defined(USE_DIRECT_WINDOW_TEST_MODE)
145 		  interface = new DWindowHWInterface();
146 #else
147 		  interface = new ViewHWInterface();
148 #endif
149 
150 		_AddHWInterface(interface);
151 		initDrivers = false;
152 	}
153 }
154 
155 
156 void
157 ScreenManager::_AddHWInterface(HWInterface* interface)
158 {
159 	Screen* screen = new(nothrow) Screen(interface, fScreenList.CountItems());
160 	if (screen == NULL) {
161 		delete interface;
162 		return;
163 	}
164 
165 	// The interface is now owned by the screen
166 
167 	if (screen->Initialize() >= B_OK) {
168 		screen_item* item = new(nothrow) screen_item;
169 		if (item != NULL) {
170 			item->screen = screen;
171 			item->owner = NULL;
172 			if (fScreenList.AddItem(item))
173 				return;
174 
175 			delete item;
176 		}
177 	}
178 
179 	delete screen;
180 }
181 
182 
183 void
184 ScreenManager::MessageReceived(BMessage* message)
185 {
186 	switch (message->what) {
187 		case B_NODE_MONITOR:
188 			// TODO: handle notification
189 			break;
190 
191 		default:
192 			BHandler::MessageReceived(message);
193 	}
194 }
195 
196