xref: /haiku/src/servers/app/ScreenManager.cpp (revision 220d04022750f40f8bac8f01fa551211e28d04f2)
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 "RemoteHWInterface.h"
18 #include "HTML5HWInterface.h"
19 
20 #include <Autolock.h>
21 #include <Entry.h>
22 #include <NodeMonitor.h>
23 
24 #include <new>
25 
26 using std::nothrow;
27 
28 
29 #ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST
30 #	include "AccelerantHWInterface.h"
31 #else
32 #	include "ViewHWInterface.h"
33 #	include "DWindowHWInterface.h"
34 #endif
35 
36 
37 ScreenManager* gScreenManager;
38 
39 
40 ScreenManager::ScreenManager()
41 	:
42 	BLooper("screen manager"),
43 	fScreenList(4)
44 {
45 	_ScanDrivers();
46 
47 	// turn on node monitoring the graphics driver directory
48 	BEntry entry("/dev/graphics");
49 	node_ref nodeRef;
50 	if (entry.InitCheck() == B_OK && entry.GetNodeRef(&nodeRef) == B_OK)
51 		watch_node(&nodeRef, B_WATCH_DIRECTORY, this);
52 }
53 
54 
55 ScreenManager::~ScreenManager()
56 {
57 	for (int32 i = 0; i < fScreenList.CountItems(); i++) {
58 		screen_item* item = fScreenList.ItemAt(i);
59 
60 		delete item->screen;
61 		delete item;
62 	}
63 }
64 
65 
66 Screen*
67 ScreenManager::ScreenAt(int32 index) const
68 {
69 	if (!IsLocked())
70 		debugger("Called ScreenManager::ScreenAt() without lock!");
71 
72 	screen_item* item = fScreenList.ItemAt(index);
73 	if (item != NULL)
74 		return item->screen;
75 
76 	return NULL;
77 }
78 
79 
80 int32
81 ScreenManager::CountScreens() const
82 {
83 	if (!IsLocked())
84 		debugger("Called ScreenManager::CountScreens() without lock!");
85 
86 	return fScreenList.CountItems();
87 }
88 
89 
90 status_t
91 ScreenManager::AcquireScreens(ScreenOwner* owner, int32* wishList,
92 	int32 wishCount, const char* target, bool force, ScreenList& list)
93 {
94 	BAutolock locker(this);
95 	int32 added = 0;
96 
97 	// TODO: don't ignore the wish list
98 
99 	for (int32 i = 0; i < fScreenList.CountItems(); i++) {
100 		screen_item* item = fScreenList.ItemAt(i);
101 
102 		if (item->owner == NULL && list.AddItem(item->screen)) {
103 			item->owner = owner;
104 			added++;
105 		}
106 	}
107 
108 #if TEST_MODE == 0 && !defined(__x86_64__)
109 	if (added == 0 && target != NULL) {
110 		// there's a specific target screen we want to initialize
111 		// TODO: right now we only support remote screens, but we could
112 		// also target specific accelerants to support other graphics cards
113 		HWInterface* interface;
114 		/*
115 		if (strncmp(target, "vnc:", 4) == 0)
116 			interface = new(nothrow) VNCHWInterface(target);
117 		else*/
118 		if (strncmp(target, "html5:", 6) == 0)
119 			interface = new(nothrow) HTML5HWInterface(target);
120 		else
121 			interface = new(nothrow) RemoteHWInterface(target);
122 		if (interface != NULL) {
123 			screen_item* item = _AddHWInterface(interface);
124 			if (item != NULL && list.AddItem(item->screen)) {
125 				item->owner = owner;
126 				added++;
127 			}
128 		}
129 	}
130 #endif // TEST_MODE == 0
131 
132 	return added > 0 ? B_OK : B_ENTRY_NOT_FOUND;
133 }
134 
135 
136 void
137 ScreenManager::ReleaseScreens(ScreenList& list)
138 {
139 	BAutolock locker(this);
140 
141 	for (int32 i = 0; i < fScreenList.CountItems(); i++) {
142 		screen_item* item = fScreenList.ItemAt(i);
143 
144 		for (int32 j = 0; j < list.CountItems(); j++) {
145 			Screen* screen = list.ItemAt(j);
146 
147 			if (item->screen == screen)
148 				item->owner = NULL;
149 		}
150 	}
151 }
152 
153 
154 void
155 ScreenManager::_ScanDrivers()
156 {
157 	HWInterface* interface = NULL;
158 
159 	// Eventually we will loop through drivers until
160 	// one can't initialize in order to support multiple monitors.
161 	// For now, we'll just load one and be done with it.
162 
163 	// ToDo: to make monitoring the driver directory useful, we need more
164 	//	power and data here, and should do the scanning on our own
165 
166 	bool initDrivers = true;
167 	while (initDrivers) {
168 
169 #ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST
170 		  interface = new AccelerantHWInterface();
171 #elif defined(USE_DIRECT_WINDOW_TEST_MODE)
172 		  interface = new DWindowHWInterface();
173 #else
174 		  interface = new ViewHWInterface();
175 #endif
176 
177 		_AddHWInterface(interface);
178 		initDrivers = false;
179 	}
180 }
181 
182 
183 ScreenManager::screen_item*
184 ScreenManager::_AddHWInterface(HWInterface* interface)
185 {
186 	Screen* screen = new(nothrow) Screen(interface, fScreenList.CountItems());
187 	if (screen == NULL) {
188 		delete interface;
189 		return NULL;
190 	}
191 
192 	// The interface is now owned by the screen
193 
194 	if (screen->Initialize() >= B_OK) {
195 		screen_item* item = new(nothrow) screen_item;
196 		if (item != NULL) {
197 			item->screen = screen;
198 			item->owner = NULL;
199 			if (fScreenList.AddItem(item))
200 				return item;
201 
202 			delete item;
203 		}
204 	}
205 
206 	delete screen;
207 	return NULL;
208 }
209 
210 
211 void
212 ScreenManager::MessageReceived(BMessage* message)
213 {
214 	switch (message->what) {
215 		case B_NODE_MONITOR:
216 			// TODO: handle notification
217 			break;
218 
219 		default:
220 			BHandler::MessageReceived(message);
221 	}
222 }
223 
224