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