xref: /haiku/src/kits/game/DirectWindow.cpp (revision 0f4fb801b0471822cd37fead421ddcd2a431bb82)
109ea3092SStefano Ceccherini /*
28575beb8SJérôme Duval  * Copyright 2003-2005, Haiku Inc.
317495d0bSStefano Ceccherini  * Authors:
409ea3092SStefano Ceccherini  *		Stefano Ceccherini (burton666@libero.it).
509ea3092SStefano Ceccherini  *		Carwyn Jones (turok2@currantbun.com)
617495d0bSStefano Ceccherini  *
709ea3092SStefano Ceccherini  * Distributed under the terms of the MIT License.
809ea3092SStefano Ceccherini  */
90b4a36abSbeveloper 
10366fdcdfSMarcus Overhagen 
11cafaa5aaSStefano Ceccherini #include <DirectWindow.h>
1271b55088SAxel Dörfler 
13cafaa5aaSStefano Ceccherini #include <clipping.h>
1471b55088SAxel Dörfler #include <DirectWindowPrivate.h>
150b4a36abSbeveloper 
16764ac9e5SAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_BEOS
17cafaa5aaSStefano Ceccherini #	include <R5_AppServerLink.h>
18cafaa5aaSStefano Ceccherini #	include <R5_Session.h>
19feee8cf2SStefano Ceccherini #	define DW_GET_SYNC_DATA		0x880
20feee8cf2SStefano Ceccherini #	define DW_SET_FULLSCREEN		0x881
21feee8cf2SStefano Ceccherini #	define DW_SUPPORTS_WINDOW_MODE 0xF2C
22764ac9e5SAxel Dörfler #else
23feee8cf2SStefano Ceccherini #	include <AppServerLink.h>
24feee8cf2SStefano Ceccherini #	include <ServerProtocol.h>
25feee8cf2SStefano Ceccherini #endif
26366fdcdfSMarcus Overhagen 
27764ac9e5SAxel Dörfler // Compiling for Dano/Zeta is broken as it doesn't have BRegion::set_size()
28764ac9e5SAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_DANO
29764ac9e5SAxel Dörfler #	warning "##### Building BDirectWindow for TARGET_PLATFORM=dano (DANO/Zeta) is broken #####"
30764ac9e5SAxel Dörfler #endif
31764ac9e5SAxel Dörfler 
32764ac9e5SAxel Dörfler 
33cafaa5aaSStefano Ceccherini // We don't need this kind of locking, since the directDeamonFunc
34cafaa5aaSStefano Ceccherini // doesn't access critical shared data.
35cafaa5aaSStefano Ceccherini #define DW_NEEDS_LOCKING 0
36cafaa5aaSStefano Ceccherini 
37cafaa5aaSStefano Ceccherini enum dw_status_bits {
3817495d0bSStefano Ceccherini 	DW_STATUS_AREA_CLONED	 = 0x1,
3917495d0bSStefano Ceccherini 	DW_STATUS_THREAD_STARTED = 0x2,
4017495d0bSStefano Ceccherini 	DW_STATUS_SEM_CREATED	 = 0x4
41cafaa5aaSStefano Ceccherini };
42cafaa5aaSStefano Ceccherini 
43cafaa5aaSStefano Ceccherini 
44764ac9e5SAxel Dörfler BDirectWindow::BDirectWindow(BRect frame, const char *title, window_type type,
45764ac9e5SAxel Dörfler 	uint32 flags, uint32 workspace)
46cafaa5aaSStefano Ceccherini 	: BWindow(frame, title, type, flags, workspace)
47cafaa5aaSStefano Ceccherini {
48cafaa5aaSStefano Ceccherini 	InitData();
490b4a36abSbeveloper }
500b4a36abSbeveloper 
510b4a36abSbeveloper 
52764ac9e5SAxel Dörfler BDirectWindow::BDirectWindow(BRect frame, const char *title, window_look look,
53764ac9e5SAxel Dörfler 	window_feel feel, uint32 flags, uint32 workspace)
54cafaa5aaSStefano Ceccherini 	: BWindow(frame, title, look, feel, flags, workspace)
550b4a36abSbeveloper {
56cafaa5aaSStefano Ceccherini 	InitData();
570b4a36abSbeveloper }
580b4a36abSbeveloper 
590b4a36abSbeveloper 
600b4a36abSbeveloper BDirectWindow::~BDirectWindow()
610b4a36abSbeveloper {
62cafaa5aaSStefano Ceccherini 	DisposeData();
630b4a36abSbeveloper }
640b4a36abSbeveloper 
650b4a36abSbeveloper 
66cafaa5aaSStefano Ceccherini // start of regular BWindow API
670b4a36abSbeveloper BArchivable *
680b4a36abSbeveloper BDirectWindow::Instantiate(BMessage *data)
690b4a36abSbeveloper {
700b4a36abSbeveloper 	return NULL;
710b4a36abSbeveloper }
720b4a36abSbeveloper 
730b4a36abSbeveloper 
740b4a36abSbeveloper status_t
75cafaa5aaSStefano Ceccherini BDirectWindow::Archive(BMessage *data, bool deep) const
760b4a36abSbeveloper {
77cafaa5aaSStefano Ceccherini 	return inherited::Archive(data, deep);
780b4a36abSbeveloper }
790b4a36abSbeveloper 
800b4a36abSbeveloper 
810b4a36abSbeveloper void
82cafaa5aaSStefano Ceccherini BDirectWindow::Quit()
830b4a36abSbeveloper {
84cafaa5aaSStefano Ceccherini 	inherited::Quit();
850b4a36abSbeveloper }
860b4a36abSbeveloper 
870b4a36abSbeveloper 
880b4a36abSbeveloper void
89cafaa5aaSStefano Ceccherini BDirectWindow::DispatchMessage(BMessage *message, BHandler *handler)
900b4a36abSbeveloper {
91cafaa5aaSStefano Ceccherini 	inherited::DispatchMessage(message, handler);
920b4a36abSbeveloper }
930b4a36abSbeveloper 
940b4a36abSbeveloper 
950b4a36abSbeveloper void
960b4a36abSbeveloper BDirectWindow::MessageReceived(BMessage *message)
970b4a36abSbeveloper {
98cafaa5aaSStefano Ceccherini 	inherited::MessageReceived(message);
990b4a36abSbeveloper }
1000b4a36abSbeveloper 
1010b4a36abSbeveloper 
1020b4a36abSbeveloper void
1030b4a36abSbeveloper BDirectWindow::FrameMoved(BPoint new_position)
1040b4a36abSbeveloper {
105cafaa5aaSStefano Ceccherini 	inherited::FrameMoved(new_position);
1060b4a36abSbeveloper }
1070b4a36abSbeveloper 
1080b4a36abSbeveloper 
1090b4a36abSbeveloper void
110cafaa5aaSStefano Ceccherini BDirectWindow::WorkspacesChanged(uint32 old_ws, uint32 new_ws)
1110b4a36abSbeveloper {
112cafaa5aaSStefano Ceccherini 	inherited::WorkspacesChanged(old_ws, new_ws);
1130b4a36abSbeveloper }
1140b4a36abSbeveloper 
1150b4a36abSbeveloper 
1160b4a36abSbeveloper void
117cafaa5aaSStefano Ceccherini BDirectWindow::WorkspaceActivated(int32 ws, bool state)
1180b4a36abSbeveloper {
119cafaa5aaSStefano Ceccherini 	inherited::WorkspaceActivated(ws, state);
1200b4a36abSbeveloper }
1210b4a36abSbeveloper 
1220b4a36abSbeveloper 
1230b4a36abSbeveloper void
124cafaa5aaSStefano Ceccherini BDirectWindow::FrameResized(float new_width, float new_height)
1250b4a36abSbeveloper {
126cafaa5aaSStefano Ceccherini 	inherited::FrameResized(new_width, new_height);
1270b4a36abSbeveloper }
1280b4a36abSbeveloper 
1290b4a36abSbeveloper 
1300b4a36abSbeveloper void
1310b4a36abSbeveloper BDirectWindow::Minimize(bool minimize)
1320b4a36abSbeveloper {
133cafaa5aaSStefano Ceccherini 	inherited::Minimize(minimize);
1340b4a36abSbeveloper }
1350b4a36abSbeveloper 
1360b4a36abSbeveloper 
1370b4a36abSbeveloper void
138cafaa5aaSStefano Ceccherini BDirectWindow::Zoom(BPoint rec_position, float rec_width, float rec_height)
1390b4a36abSbeveloper {
140cafaa5aaSStefano Ceccherini 	inherited::Zoom(rec_position, rec_width, rec_height);
1410b4a36abSbeveloper }
1420b4a36abSbeveloper 
1430b4a36abSbeveloper 
1440b4a36abSbeveloper void
145cafaa5aaSStefano Ceccherini BDirectWindow::ScreenChanged(BRect screen_size, color_space depth)
1460b4a36abSbeveloper {
147cafaa5aaSStefano Ceccherini 	inherited::ScreenChanged(screen_size, depth);
1480b4a36abSbeveloper }
1490b4a36abSbeveloper 
1500b4a36abSbeveloper 
1510b4a36abSbeveloper void
1520b4a36abSbeveloper BDirectWindow::MenusBeginning()
1530b4a36abSbeveloper {
154cafaa5aaSStefano Ceccherini 	inherited::MenusBeginning();
1550b4a36abSbeveloper }
1560b4a36abSbeveloper 
1570b4a36abSbeveloper 
1580b4a36abSbeveloper void
1590b4a36abSbeveloper BDirectWindow::MenusEnded()
1600b4a36abSbeveloper {
161cafaa5aaSStefano Ceccherini 	inherited::MenusEnded();
1620b4a36abSbeveloper }
1630b4a36abSbeveloper 
1640b4a36abSbeveloper 
1650b4a36abSbeveloper void
1660b4a36abSbeveloper BDirectWindow::WindowActivated(bool state)
1670b4a36abSbeveloper {
168cafaa5aaSStefano Ceccherini 	inherited::WindowActivated(state);
1690b4a36abSbeveloper }
1700b4a36abSbeveloper 
1710b4a36abSbeveloper 
1720b4a36abSbeveloper void
1730b4a36abSbeveloper BDirectWindow::Show()
1740b4a36abSbeveloper {
175cafaa5aaSStefano Ceccherini 	inherited::Show();
1760b4a36abSbeveloper }
1770b4a36abSbeveloper 
1780b4a36abSbeveloper 
1790b4a36abSbeveloper void
1800b4a36abSbeveloper BDirectWindow::Hide()
1810b4a36abSbeveloper {
182cafaa5aaSStefano Ceccherini 	inherited::Hide();
1830b4a36abSbeveloper }
1840b4a36abSbeveloper 
1850b4a36abSbeveloper 
1860b4a36abSbeveloper BHandler *
187cafaa5aaSStefano Ceccherini BDirectWindow::ResolveSpecifier(BMessage *msg, int32 index,
188cafaa5aaSStefano Ceccherini 	BMessage *specifier, int32 form, const char *property)
1890b4a36abSbeveloper {
190cafaa5aaSStefano Ceccherini 	return inherited::ResolveSpecifier(msg, index, specifier, form, property);
1910b4a36abSbeveloper }
1920b4a36abSbeveloper 
1930b4a36abSbeveloper 
1940b4a36abSbeveloper status_t
1950b4a36abSbeveloper BDirectWindow::GetSupportedSuites(BMessage *data)
1960b4a36abSbeveloper {
197cafaa5aaSStefano Ceccherini 	return inherited::GetSupportedSuites(data);
1980b4a36abSbeveloper }
1990b4a36abSbeveloper 
2000b4a36abSbeveloper 
2010b4a36abSbeveloper status_t
202cafaa5aaSStefano Ceccherini BDirectWindow::Perform(perform_code d, void *arg)
2030b4a36abSbeveloper {
204cafaa5aaSStefano Ceccherini 	return inherited::Perform(d, arg);
2050b4a36abSbeveloper }
2060b4a36abSbeveloper 
2070b4a36abSbeveloper 
208b816dc1eSIngo Weinhold void
209b816dc1eSIngo Weinhold BDirectWindow::task_looper()
210b816dc1eSIngo Weinhold {
211cafaa5aaSStefano Ceccherini 	inherited::task_looper();
212b816dc1eSIngo Weinhold }
213b816dc1eSIngo Weinhold 
214cafaa5aaSStefano Ceccherini 
215b816dc1eSIngo Weinhold BMessage *
216b816dc1eSIngo Weinhold BDirectWindow::ConvertToMessage(void *raw, int32 code)
217b816dc1eSIngo Weinhold {
218cafaa5aaSStefano Ceccherini 	return inherited::ConvertToMessage(raw, code);
219b816dc1eSIngo Weinhold }
2200b4a36abSbeveloper 
2210b4a36abSbeveloper 
222764ac9e5SAxel Dörfler //	#pragma mark - BDirectWindow specific API
223764ac9e5SAxel Dörfler 
224764ac9e5SAxel Dörfler 
2250b4a36abSbeveloper void
2260b4a36abSbeveloper BDirectWindow::DirectConnected(direct_buffer_info *info)
2270b4a36abSbeveloper {
228cafaa5aaSStefano Ceccherini 	// implemented in subclasses
2290b4a36abSbeveloper }
2300b4a36abSbeveloper 
2310b4a36abSbeveloper 
2320b4a36abSbeveloper status_t
233cafaa5aaSStefano Ceccherini BDirectWindow::GetClippingRegion(BRegion *region, BPoint *origin) const
2340b4a36abSbeveloper {
235cafaa5aaSStefano Ceccherini 	if (region == NULL)
236cafaa5aaSStefano Ceccherini 		return B_BAD_VALUE;
237cafaa5aaSStefano Ceccherini 
2384f6f70e0SStefano Ceccherini 	if (IsLocked() || !LockDirect())
2395fdea13fSStefano Ceccherini 		return B_ERROR;
2405fdea13fSStefano Ceccherini 
241cafaa5aaSStefano Ceccherini 	if (in_direct_connect) {
242cafaa5aaSStefano Ceccherini 		UnlockDirect();
243cafaa5aaSStefano Ceccherini 		return B_ERROR;
244cafaa5aaSStefano Ceccherini 	}
245cafaa5aaSStefano Ceccherini 
246cafaa5aaSStefano Ceccherini 	// BPoint's coordinates are floats. We can only work
247cafaa5aaSStefano Ceccherini 	// with integers.
248cafaa5aaSStefano Ceccherini 	int32 originX, originY;
249cafaa5aaSStefano Ceccherini 	if (origin == NULL) {
250cafaa5aaSStefano Ceccherini 		originX = 0;
251cafaa5aaSStefano Ceccherini 		originY = 0;
252cafaa5aaSStefano Ceccherini 	} else {
253cafaa5aaSStefano Ceccherini 		originX = (int32)origin->x;
254cafaa5aaSStefano Ceccherini 		originY = (int32)origin->y;
255cafaa5aaSStefano Ceccherini 	}
256cafaa5aaSStefano Ceccherini 
257764ac9e5SAxel Dörfler #ifndef HAIKU_TARGET_PLATFORM_DANO
258cafaa5aaSStefano Ceccherini 	// Since we are friend of BRegion, we can access its private members.
259cafaa5aaSStefano Ceccherini 	// Otherwise, we would need to call BRegion::Include(clipping_rect)
260cafaa5aaSStefano Ceccherini 	// for every clipping_rect in our clip_list, and that would be much
2615fdea13fSStefano Ceccherini 	// more overkill than this (tested ).
262cafaa5aaSStefano Ceccherini 	region->set_size(buffer_desc->clip_list_count);
263cafaa5aaSStefano Ceccherini 	region->count = buffer_desc->clip_list_count;
264cafaa5aaSStefano Ceccherini 	region->bound = buffer_desc->clip_bounds;
2654f6f70e0SStefano Ceccherini 	for (uint32 c = 0; c < buffer_desc->clip_list_count; c++)
2664f6f70e0SStefano Ceccherini 		region->data[c] = buffer_desc->clip_list[c];
267cafaa5aaSStefano Ceccherini 
268cafaa5aaSStefano Ceccherini 	// adjust bounds by the given origin point
2694f6f70e0SStefano Ceccherini 	region->OffsetBy(-originX, -originY);
270366fdcdfSMarcus Overhagen #endif
271366fdcdfSMarcus Overhagen 
272cafaa5aaSStefano Ceccherini 	UnlockDirect();
273cafaa5aaSStefano Ceccherini 
274cafaa5aaSStefano Ceccherini 	return B_OK;
275cafaa5aaSStefano Ceccherini 
2760b4a36abSbeveloper }
2770b4a36abSbeveloper 
2780b4a36abSbeveloper 
2790b4a36abSbeveloper status_t
2800b4a36abSbeveloper BDirectWindow::SetFullScreen(bool enable)
2810b4a36abSbeveloper {
282cafaa5aaSStefano Ceccherini 	status_t status = B_ERROR;
28309ea3092SStefano Ceccherini 	if (Lock()) {
284764ac9e5SAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_BEOS
28509ea3092SStefano Ceccherini 		a_session->swrite_l(DW_SET_FULLSCREEN);
28609ea3092SStefano Ceccherini 		a_session->swrite_l(server_token);
28717495d0bSStefano Ceccherini 		a_session->swrite_l((int32)enable);
28809ea3092SStefano Ceccherini 		Flush();
28909ea3092SStefano Ceccherini 
290bfc3bb18SStefano Ceccherini 		status_t fullScreen;
291bfc3bb18SStefano Ceccherini 		a_session->sread(sizeof(status_t), &fullScreen);
292bfc3bb18SStefano Ceccherini 		a_session->sread(sizeof(status_t), &status);
293feee8cf2SStefano Ceccherini 		full_screen_enable = enable;
294764ac9e5SAxel Dörfler #else
295ab6a6bedSAxel Dörfler 		fLink->StartMessage(AS_DIRECT_WINDOW_SET_FULLSCREEN);
296feee8cf2SStefano Ceccherini 		fLink->Attach<bool>(enable);
297feee8cf2SStefano Ceccherini 
298ab6a6bedSAxel Dörfler 		status_t status = B_ERROR;
299ab6a6bedSAxel Dörfler 		if (fLink->FlushWithReply(status) == B_OK
300ab6a6bedSAxel Dörfler 			&& status == B_OK)
301feee8cf2SStefano Ceccherini 			full_screen_enable = enable;
3028575beb8SJérôme Duval #endif
30309ea3092SStefano Ceccherini 		Unlock();
304bfc3bb18SStefano Ceccherini 
30509ea3092SStefano Ceccherini 	}
306cafaa5aaSStefano Ceccherini 	return status;
3070b4a36abSbeveloper }
3080b4a36abSbeveloper 
3090b4a36abSbeveloper 
3100b4a36abSbeveloper bool
3110b4a36abSbeveloper BDirectWindow::IsFullScreen() const
3120b4a36abSbeveloper {
313cafaa5aaSStefano Ceccherini 	return full_screen_enable;
3140b4a36abSbeveloper }
3150b4a36abSbeveloper 
3160b4a36abSbeveloper 
317*0f4fb801SAxel Dörfler /*static*/
3180b4a36abSbeveloper bool
319cafaa5aaSStefano Ceccherini BDirectWindow::SupportsWindowMode(screen_id id)
3200b4a36abSbeveloper {
321764ac9e5SAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_BEOS
322feee8cf2SStefano Ceccherini 	int32 result = 0;
323cafaa5aaSStefano Ceccherini 	_BAppServerLink_ link;
324cafaa5aaSStefano Ceccherini 	link.fSession->swrite_l(DW_SUPPORTS_WINDOW_MODE);
325cafaa5aaSStefano Ceccherini 	link.fSession->swrite_l(id.id);
326cafaa5aaSStefano Ceccherini 	link.fSession->sync();
327cafaa5aaSStefano Ceccherini 	link.fSession->sread(sizeof(result), &result);
328feee8cf2SStefano Ceccherini 	return result & true;
329764ac9e5SAxel Dörfler #else
330feee8cf2SStefano Ceccherini 	BPrivate::AppServerLink link;
331ab6a6bedSAxel Dörfler 	link.StartMessage(AS_DIRECT_WINDOW_SUPPORTS_WINDOW_MODE);
332feee8cf2SStefano Ceccherini 	link.Attach<screen_id>(id);
333ab6a6bedSAxel Dörfler 
334feee8cf2SStefano Ceccherini 	int32 reply;
335feee8cf2SStefano Ceccherini 	if (link.FlushWithReply(reply) == B_OK
336ab6a6bedSAxel Dörfler 		&& reply == B_OK)
337feee8cf2SStefano Ceccherini 		return true;
338feee8cf2SStefano Ceccherini #endif
339feee8cf2SStefano Ceccherini 
340feee8cf2SStefano Ceccherini 	return false;
341cafaa5aaSStefano Ceccherini }
342cafaa5aaSStefano Ceccherini 
343cafaa5aaSStefano Ceccherini 
344*0f4fb801SAxel Dörfler //	#pragma mark - Private methods
345*0f4fb801SAxel Dörfler 
346*0f4fb801SAxel Dörfler 
347cafaa5aaSStefano Ceccherini int32
348cafaa5aaSStefano Ceccherini BDirectWindow::DirectDeamonFunc(void *arg)
349cafaa5aaSStefano Ceccherini {
350cafaa5aaSStefano Ceccherini 	BDirectWindow *object = static_cast<BDirectWindow *>(arg);
351cafaa5aaSStefano Ceccherini 
352cafaa5aaSStefano Ceccherini 	while (!object->deamon_killer) {
353cafaa5aaSStefano Ceccherini 		// This sem is released by the app_server when our
354cafaa5aaSStefano Ceccherini 		// clipping region changes, or when our window is moved,
355cafaa5aaSStefano Ceccherini 		// resized, etc. etc.
356*0f4fb801SAxel Dörfler 		status_t status;
357*0f4fb801SAxel Dörfler 		do {
358*0f4fb801SAxel Dörfler 			status = acquire_sem(object->disable_sem);
359*0f4fb801SAxel Dörfler 		} while (status == B_INTERRUPTED);
360*0f4fb801SAxel Dörfler 
361*0f4fb801SAxel Dörfler 		if (status < B_OK)
362*0f4fb801SAxel Dörfler 			return -1;
363cafaa5aaSStefano Ceccherini 
364cafaa5aaSStefano Ceccherini 		if (object->LockDirect()) {
365cafaa5aaSStefano Ceccherini 			if ((object->buffer_desc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_START)
366cafaa5aaSStefano Ceccherini 				object->connection_enable = true;
367cafaa5aaSStefano Ceccherini 
368cafaa5aaSStefano Ceccherini 			object->in_direct_connect = true;
369cafaa5aaSStefano Ceccherini 			object->DirectConnected(object->buffer_desc);
370cafaa5aaSStefano Ceccherini 			object->in_direct_connect = false;
371cafaa5aaSStefano Ceccherini 
372cafaa5aaSStefano Ceccherini 			if ((object->buffer_desc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_STOP)
373cafaa5aaSStefano Ceccherini 				object->connection_enable = false;
374cafaa5aaSStefano Ceccherini 
375cafaa5aaSStefano Ceccherini 			object->UnlockDirect();
376cafaa5aaSStefano Ceccherini 		}
377cafaa5aaSStefano Ceccherini 
378cafaa5aaSStefano Ceccherini 		// The app_server then waits (with a timeout) on this sem.
379cafaa5aaSStefano Ceccherini 		// If we aren't quick enough to release this sem, our app
380cafaa5aaSStefano Ceccherini 		// will be terminated by the app_server
381*0f4fb801SAxel Dörfler 		if (release_sem(object->disable_sem_ack) != B_OK)
382*0f4fb801SAxel Dörfler 			return -1;
383cafaa5aaSStefano Ceccherini 	}
384cafaa5aaSStefano Ceccherini 
385cafaa5aaSStefano Ceccherini 	return 0;
386cafaa5aaSStefano Ceccherini }
387cafaa5aaSStefano Ceccherini 
388cafaa5aaSStefano Ceccherini 
38917495d0bSStefano Ceccherini // LockDirect() and UnlockDirect() are no-op on R5. I tried to call (R5's) LockDirect()
39017495d0bSStefano Ceccherini // repeatedly, from the same thread and from different threads, nothing happened.
39117495d0bSStefano Ceccherini // I implemented them anyway, as they were the first methods I wrote
39217495d0bSStefano Ceccherini // in this class (As you can see, I even needed to cast away their constness
39317495d0bSStefano Ceccherini // to make them do something useful).
39417495d0bSStefano Ceccherini // They're not needed though, as the direct_deamon_thread doesn't change
39517495d0bSStefano Ceccherini // any shared data. They are probably here for future enhancements (see also the
39617495d0bSStefano Ceccherini // comment in DriverSetup()
397cafaa5aaSStefano Ceccherini bool
398cafaa5aaSStefano Ceccherini BDirectWindow::LockDirect() const
399cafaa5aaSStefano Ceccherini {
400cafaa5aaSStefano Ceccherini 	status_t status = B_OK;
401cafaa5aaSStefano Ceccherini 
402cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING
403cafaa5aaSStefano Ceccherini 	BDirectWindow *casted = const_cast<BDirectWindow *>(this);
404cafaa5aaSStefano Ceccherini 
4055fdea13fSStefano Ceccherini 	if (atomic_add(&casted->direct_lock, 1) > 0) {
406cafaa5aaSStefano Ceccherini 		do {
407cafaa5aaSStefano Ceccherini 			status = acquire_sem(direct_sem);
408cafaa5aaSStefano Ceccherini 		} while (status == B_INTERRUPTED);
4095fdea13fSStefano Ceccherini 	}
410cafaa5aaSStefano Ceccherini 
411cafaa5aaSStefano Ceccherini 	if (status == B_OK) {
412cafaa5aaSStefano Ceccherini 		casted->direct_lock_owner = find_thread(NULL);
413cafaa5aaSStefano Ceccherini 		casted->direct_lock_count++;
414cafaa5aaSStefano Ceccherini 	}
415cafaa5aaSStefano Ceccherini #endif
416cafaa5aaSStefano Ceccherini 
417cafaa5aaSStefano Ceccherini 	return status == B_OK;
4180b4a36abSbeveloper }
4190b4a36abSbeveloper 
4200b4a36abSbeveloper 
4210b4a36abSbeveloper void
422cafaa5aaSStefano Ceccherini BDirectWindow::UnlockDirect() const
4230b4a36abSbeveloper {
424cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING
425cafaa5aaSStefano Ceccherini 	BDirectWindow *casted = const_cast<BDirectWindow *>(this);
426cafaa5aaSStefano Ceccherini 
427cafaa5aaSStefano Ceccherini 	if (atomic_add(&casted->direct_lock, -1) > 1)
428cafaa5aaSStefano Ceccherini 		release_sem(direct_sem);
429cafaa5aaSStefano Ceccherini 
430cafaa5aaSStefano Ceccherini 	casted->direct_lock_count--;
431cafaa5aaSStefano Ceccherini #endif
4320b4a36abSbeveloper }
4330b4a36abSbeveloper 
4340b4a36abSbeveloper 
4350b4a36abSbeveloper void
436cafaa5aaSStefano Ceccherini BDirectWindow::InitData()
4370b4a36abSbeveloper {
438cafaa5aaSStefano Ceccherini 	connection_enable = false;
439cafaa5aaSStefano Ceccherini 	full_screen_enable = false;
440cafaa5aaSStefano Ceccherini 	in_direct_connect = false;
441cafaa5aaSStefano Ceccherini 
442cafaa5aaSStefano Ceccherini 	dw_init_status = 0;
443cafaa5aaSStefano Ceccherini 
444cafaa5aaSStefano Ceccherini 	direct_driver_ready = false;
445cafaa5aaSStefano Ceccherini 	direct_driver_type = 0;
446cafaa5aaSStefano Ceccherini 	direct_driver_token = 0;
447cafaa5aaSStefano Ceccherini 	direct_driver = NULL;
448cafaa5aaSStefano Ceccherini 
4495fdea13fSStefano Ceccherini 	if (!Lock())
4505fdea13fSStefano Ceccherini 		return;
4515fdea13fSStefano Ceccherini 
45271b55088SAxel Dörfler 	struct direct_window_sync_data syncData;
4538575beb8SJérôme Duval 	status_t status = B_ERROR;
4548575beb8SJérôme Duval 
455764ac9e5SAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_BEOS
456cafaa5aaSStefano Ceccherini 	a_session->swrite_l(DW_GET_SYNC_DATA);
457cafaa5aaSStefano Ceccherini 	a_session->swrite_l(server_token);
4588575beb8SJérôme Duval 
459cafaa5aaSStefano Ceccherini 	Flush();
460cafaa5aaSStefano Ceccherini 
46171b55088SAxel Dörfler 	a_session->sread(sizeof(syncData), &syncData);
4628575beb8SJérôme Duval 	a_session->sread(sizeof(status), &status);
463764ac9e5SAxel Dörfler #else
464ab6a6bedSAxel Dörfler 	fLink->StartMessage(AS_DIRECT_WINDOW_GET_SYNC_DATA);
465feee8cf2SStefano Ceccherini 
466feee8cf2SStefano Ceccherini 	int32 reply;
467feee8cf2SStefano Ceccherini 	if (fLink->FlushWithReply(reply) == B_OK
468764ac9e5SAxel Dörfler 		&& reply == B_OK) {
46971b55088SAxel Dörfler 		fLink->Read<direct_window_sync_data>(&syncData);
470feee8cf2SStefano Ceccherini 		status = B_OK;
471feee8cf2SStefano Ceccherini 	}
472feee8cf2SStefano Ceccherini #endif
473feee8cf2SStefano Ceccherini 
474cafaa5aaSStefano Ceccherini 	Unlock();
475cafaa5aaSStefano Ceccherini 
4765fdea13fSStefano Ceccherini 	if (status < B_OK)
4775fdea13fSStefano Ceccherini 		return;
478cafaa5aaSStefano Ceccherini 
479cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING
480cafaa5aaSStefano Ceccherini 	direct_lock = 0;
481cafaa5aaSStefano Ceccherini 	direct_lock_count = 0;
4825fdea13fSStefano Ceccherini 	direct_lock_owner = -1;
483cafaa5aaSStefano Ceccherini 	direct_lock_stack = NULL;
484cafaa5aaSStefano Ceccherini 	direct_sem = create_sem(1, "direct sem");
485cafaa5aaSStefano Ceccherini 	if (direct_sem > 0)
486cafaa5aaSStefano Ceccherini 		dw_init_status |= DW_STATUS_SEM_CREATED;
487cafaa5aaSStefano Ceccherini #endif
488cafaa5aaSStefano Ceccherini 
48971b55088SAxel Dörfler 	source_clipping_area = syncData.area;
49071b55088SAxel Dörfler 	disable_sem = syncData.disable_sem;
49171b55088SAxel Dörfler 	disable_sem_ack = syncData.disable_sem_ack;
492cafaa5aaSStefano Ceccherini 
493cafaa5aaSStefano Ceccherini 	cloned_clipping_area = clone_area("Clone direct area", (void**)&buffer_desc,
494cafaa5aaSStefano Ceccherini 		B_ANY_ADDRESS, B_READ_AREA, source_clipping_area);
4955fdea13fSStefano Ceccherini 
496cafaa5aaSStefano Ceccherini 	if (cloned_clipping_area > 0) {
497cafaa5aaSStefano Ceccherini 		dw_init_status |= DW_STATUS_AREA_CLONED;
498cafaa5aaSStefano Ceccherini 
499cafaa5aaSStefano Ceccherini 		direct_deamon_id = spawn_thread(DirectDeamonFunc, "direct deamon",
500cafaa5aaSStefano Ceccherini 				B_DISPLAY_PRIORITY, this);
501cafaa5aaSStefano Ceccherini 
502cafaa5aaSStefano Ceccherini 		if (direct_deamon_id > 0) {
503cafaa5aaSStefano Ceccherini 			deamon_killer = false;
504cafaa5aaSStefano Ceccherini 			if (resume_thread(direct_deamon_id) == B_OK)
505cafaa5aaSStefano Ceccherini 				dw_init_status |= DW_STATUS_THREAD_STARTED;
506cafaa5aaSStefano Ceccherini 			else
507cafaa5aaSStefano Ceccherini 				kill_thread(direct_deamon_id);
508cafaa5aaSStefano Ceccherini 		}
509cafaa5aaSStefano Ceccherini 	}
510cafaa5aaSStefano Ceccherini }
5110b4a36abSbeveloper 
5120b4a36abSbeveloper 
5130b4a36abSbeveloper void
514cafaa5aaSStefano Ceccherini BDirectWindow::DisposeData()
5150b4a36abSbeveloper {
516cafaa5aaSStefano Ceccherini 	// wait until the connection terminates: we can't destroy
517cafaa5aaSStefano Ceccherini 	// the object until the client receives the B_DIRECT_STOP
518cafaa5aaSStefano Ceccherini 	// notification, or bad things will happen
519cafaa5aaSStefano Ceccherini 	while (connection_enable)
520cafaa5aaSStefano Ceccherini 		snooze(50000);
521cafaa5aaSStefano Ceccherini 
522cafaa5aaSStefano Ceccherini 	LockDirect();
523cafaa5aaSStefano Ceccherini 
524cafaa5aaSStefano Ceccherini 	if (dw_init_status & DW_STATUS_THREAD_STARTED) {
525cafaa5aaSStefano Ceccherini 		deamon_killer = true;
526cafaa5aaSStefano Ceccherini 		// Release this sem, otherwise the Direct deamon thread
527cafaa5aaSStefano Ceccherini 		// will wait forever on it
528cafaa5aaSStefano Ceccherini 		release_sem(disable_sem);
529cafaa5aaSStefano Ceccherini 		status_t retVal;
530cafaa5aaSStefano Ceccherini 		wait_for_thread(direct_deamon_id, &retVal);
531cafaa5aaSStefano Ceccherini 	}
532cafaa5aaSStefano Ceccherini 
533cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING
534cafaa5aaSStefano Ceccherini 	if (dw_init_status & DW_STATUS_SEM_CREATED)
535cafaa5aaSStefano Ceccherini 		delete_sem(direct_sem);
536cafaa5aaSStefano Ceccherini #endif
537cafaa5aaSStefano Ceccherini 
538cafaa5aaSStefano Ceccherini 	if (dw_init_status & DW_STATUS_AREA_CLONED)
539cafaa5aaSStefano Ceccherini 		delete_area(cloned_clipping_area);
5400b4a36abSbeveloper }
5410b4a36abSbeveloper 
5420b4a36abSbeveloper 
543cafaa5aaSStefano Ceccherini status_t
544cafaa5aaSStefano Ceccherini BDirectWindow::DriverSetup() const
5450b4a36abSbeveloper {
54617495d0bSStefano Ceccherini 	// Unimplemented in R5.
54709ea3092SStefano Ceccherini 	// This function is probably here because they wanted, in a future time,
54809ea3092SStefano Ceccherini 	// to implement graphic acceleration within BDirectWindow
54909ea3092SStefano Ceccherini 	// (in fact, there is also a BDirectDriver member in BDirectWindow,
55017495d0bSStefano Ceccherini 	// though it's not used).
55109ea3092SStefano Ceccherini 
552cafaa5aaSStefano Ceccherini 	return B_OK;
5530b4a36abSbeveloper }
5540b4a36abSbeveloper 
5550b4a36abSbeveloper 
556cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow1() {}
557cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow2() {}
558cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow3() {}
559cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow4() {}
560