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