xref: /haiku/src/kits/game/DirectWindow.cpp (revision af29432635a30071e66c3ab219a6cc4386b4f156)
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>
124fbc3f58SStefano Ceccherini #include <Screen.h>
1371b55088SAxel Dörfler 
14cafaa5aaSStefano Ceccherini #include <clipping.h>
15feee8cf2SStefano Ceccherini #include <AppServerLink.h>
162b6ac345SStefano Ceccherini #include <DirectWindowPrivate.h>
17feee8cf2SStefano Ceccherini #include <ServerProtocol.h>
18764ac9e5SAxel Dörfler 
19764ac9e5SAxel Dörfler 
20*af294326SPhilippe Houdoin // We don't need this kind of locking, since the directDaemonFunc
21cafaa5aaSStefano Ceccherini // doesn't access critical shared data.
22cafaa5aaSStefano Ceccherini #define DW_NEEDS_LOCKING 0
23cafaa5aaSStefano Ceccherini 
24cafaa5aaSStefano Ceccherini enum dw_status_bits {
2517495d0bSStefano Ceccherini 	DW_STATUS_AREA_CLONED	 = 0x1,
2617495d0bSStefano Ceccherini 	DW_STATUS_THREAD_STARTED = 0x2,
2717495d0bSStefano Ceccherini 	DW_STATUS_SEM_CREATED	 = 0x4
28cafaa5aaSStefano Ceccherini };
29cafaa5aaSStefano Ceccherini 
30cafaa5aaSStefano Ceccherini 
31764ac9e5SAxel Dörfler BDirectWindow::BDirectWindow(BRect frame, const char *title, window_type type,
32764ac9e5SAxel Dörfler 	uint32 flags, uint32 workspace)
33cafaa5aaSStefano Ceccherini 	: BWindow(frame, title, type, flags, workspace)
34cafaa5aaSStefano Ceccherini {
35cafaa5aaSStefano Ceccherini 	InitData();
360b4a36abSbeveloper }
370b4a36abSbeveloper 
380b4a36abSbeveloper 
39764ac9e5SAxel Dörfler BDirectWindow::BDirectWindow(BRect frame, const char *title, window_look look,
40764ac9e5SAxel Dörfler 	window_feel feel, uint32 flags, uint32 workspace)
41cafaa5aaSStefano Ceccherini 	: BWindow(frame, title, look, feel, flags, workspace)
420b4a36abSbeveloper {
43cafaa5aaSStefano Ceccherini 	InitData();
440b4a36abSbeveloper }
450b4a36abSbeveloper 
460b4a36abSbeveloper 
470b4a36abSbeveloper BDirectWindow::~BDirectWindow()
480b4a36abSbeveloper {
49cafaa5aaSStefano Ceccherini 	DisposeData();
500b4a36abSbeveloper }
510b4a36abSbeveloper 
520b4a36abSbeveloper 
53cafaa5aaSStefano Ceccherini // start of regular BWindow API
540b4a36abSbeveloper BArchivable *
550b4a36abSbeveloper BDirectWindow::Instantiate(BMessage *data)
560b4a36abSbeveloper {
570b4a36abSbeveloper 	return NULL;
580b4a36abSbeveloper }
590b4a36abSbeveloper 
600b4a36abSbeveloper 
610b4a36abSbeveloper status_t
62cafaa5aaSStefano Ceccherini BDirectWindow::Archive(BMessage *data, bool deep) const
630b4a36abSbeveloper {
64cafaa5aaSStefano Ceccherini 	return inherited::Archive(data, deep);
650b4a36abSbeveloper }
660b4a36abSbeveloper 
670b4a36abSbeveloper 
680b4a36abSbeveloper void
69cafaa5aaSStefano Ceccherini BDirectWindow::Quit()
700b4a36abSbeveloper {
71cafaa5aaSStefano Ceccherini 	inherited::Quit();
720b4a36abSbeveloper }
730b4a36abSbeveloper 
740b4a36abSbeveloper 
750b4a36abSbeveloper void
76cafaa5aaSStefano Ceccherini BDirectWindow::DispatchMessage(BMessage *message, BHandler *handler)
770b4a36abSbeveloper {
78cafaa5aaSStefano Ceccherini 	inherited::DispatchMessage(message, handler);
790b4a36abSbeveloper }
800b4a36abSbeveloper 
810b4a36abSbeveloper 
820b4a36abSbeveloper void
830b4a36abSbeveloper BDirectWindow::MessageReceived(BMessage *message)
840b4a36abSbeveloper {
85cafaa5aaSStefano Ceccherini 	inherited::MessageReceived(message);
860b4a36abSbeveloper }
870b4a36abSbeveloper 
880b4a36abSbeveloper 
890b4a36abSbeveloper void
900b4a36abSbeveloper BDirectWindow::FrameMoved(BPoint new_position)
910b4a36abSbeveloper {
92cafaa5aaSStefano Ceccherini 	inherited::FrameMoved(new_position);
930b4a36abSbeveloper }
940b4a36abSbeveloper 
950b4a36abSbeveloper 
960b4a36abSbeveloper void
97cafaa5aaSStefano Ceccherini BDirectWindow::WorkspacesChanged(uint32 old_ws, uint32 new_ws)
980b4a36abSbeveloper {
99cafaa5aaSStefano Ceccherini 	inherited::WorkspacesChanged(old_ws, new_ws);
1000b4a36abSbeveloper }
1010b4a36abSbeveloper 
1020b4a36abSbeveloper 
1030b4a36abSbeveloper void
104cafaa5aaSStefano Ceccherini BDirectWindow::WorkspaceActivated(int32 ws, bool state)
1050b4a36abSbeveloper {
106cafaa5aaSStefano Ceccherini 	inherited::WorkspaceActivated(ws, state);
1070b4a36abSbeveloper }
1080b4a36abSbeveloper 
1090b4a36abSbeveloper 
1100b4a36abSbeveloper void
111cafaa5aaSStefano Ceccherini BDirectWindow::FrameResized(float new_width, float new_height)
1120b4a36abSbeveloper {
113cafaa5aaSStefano Ceccherini 	inherited::FrameResized(new_width, new_height);
1140b4a36abSbeveloper }
1150b4a36abSbeveloper 
1160b4a36abSbeveloper 
1170b4a36abSbeveloper void
1180b4a36abSbeveloper BDirectWindow::Minimize(bool minimize)
1190b4a36abSbeveloper {
120cafaa5aaSStefano Ceccherini 	inherited::Minimize(minimize);
1210b4a36abSbeveloper }
1220b4a36abSbeveloper 
1230b4a36abSbeveloper 
1240b4a36abSbeveloper void
125cafaa5aaSStefano Ceccherini BDirectWindow::Zoom(BPoint rec_position, float rec_width, float rec_height)
1260b4a36abSbeveloper {
127cafaa5aaSStefano Ceccherini 	inherited::Zoom(rec_position, rec_width, rec_height);
1280b4a36abSbeveloper }
1290b4a36abSbeveloper 
1300b4a36abSbeveloper 
1310b4a36abSbeveloper void
132cafaa5aaSStefano Ceccherini BDirectWindow::ScreenChanged(BRect screen_size, color_space depth)
1330b4a36abSbeveloper {
134cafaa5aaSStefano Ceccherini 	inherited::ScreenChanged(screen_size, depth);
1350b4a36abSbeveloper }
1360b4a36abSbeveloper 
1370b4a36abSbeveloper 
1380b4a36abSbeveloper void
1390b4a36abSbeveloper BDirectWindow::MenusBeginning()
1400b4a36abSbeveloper {
141cafaa5aaSStefano Ceccherini 	inherited::MenusBeginning();
1420b4a36abSbeveloper }
1430b4a36abSbeveloper 
1440b4a36abSbeveloper 
1450b4a36abSbeveloper void
1460b4a36abSbeveloper BDirectWindow::MenusEnded()
1470b4a36abSbeveloper {
148cafaa5aaSStefano Ceccherini 	inherited::MenusEnded();
1490b4a36abSbeveloper }
1500b4a36abSbeveloper 
1510b4a36abSbeveloper 
1520b4a36abSbeveloper void
1530b4a36abSbeveloper BDirectWindow::WindowActivated(bool state)
1540b4a36abSbeveloper {
155cafaa5aaSStefano Ceccherini 	inherited::WindowActivated(state);
1560b4a36abSbeveloper }
1570b4a36abSbeveloper 
1580b4a36abSbeveloper 
1590b4a36abSbeveloper void
1600b4a36abSbeveloper BDirectWindow::Show()
1610b4a36abSbeveloper {
162cafaa5aaSStefano Ceccherini 	inherited::Show();
1630b4a36abSbeveloper }
1640b4a36abSbeveloper 
1650b4a36abSbeveloper 
1660b4a36abSbeveloper void
1670b4a36abSbeveloper BDirectWindow::Hide()
1680b4a36abSbeveloper {
169cafaa5aaSStefano Ceccherini 	inherited::Hide();
1700b4a36abSbeveloper }
1710b4a36abSbeveloper 
1720b4a36abSbeveloper 
1730b4a36abSbeveloper BHandler *
174cafaa5aaSStefano Ceccherini BDirectWindow::ResolveSpecifier(BMessage *msg, int32 index,
175cafaa5aaSStefano Ceccherini 	BMessage *specifier, int32 form, const char *property)
1760b4a36abSbeveloper {
177cafaa5aaSStefano Ceccherini 	return inherited::ResolveSpecifier(msg, index, specifier, form, property);
1780b4a36abSbeveloper }
1790b4a36abSbeveloper 
1800b4a36abSbeveloper 
1810b4a36abSbeveloper status_t
1820b4a36abSbeveloper BDirectWindow::GetSupportedSuites(BMessage *data)
1830b4a36abSbeveloper {
184cafaa5aaSStefano Ceccherini 	return inherited::GetSupportedSuites(data);
1850b4a36abSbeveloper }
1860b4a36abSbeveloper 
1870b4a36abSbeveloper 
1880b4a36abSbeveloper status_t
189cafaa5aaSStefano Ceccherini BDirectWindow::Perform(perform_code d, void *arg)
1900b4a36abSbeveloper {
191cafaa5aaSStefano Ceccherini 	return inherited::Perform(d, arg);
1920b4a36abSbeveloper }
1930b4a36abSbeveloper 
1940b4a36abSbeveloper 
195b816dc1eSIngo Weinhold void
196b816dc1eSIngo Weinhold BDirectWindow::task_looper()
197b816dc1eSIngo Weinhold {
198cafaa5aaSStefano Ceccherini 	inherited::task_looper();
199b816dc1eSIngo Weinhold }
200b816dc1eSIngo Weinhold 
201cafaa5aaSStefano Ceccherini 
202b816dc1eSIngo Weinhold BMessage *
203b816dc1eSIngo Weinhold BDirectWindow::ConvertToMessage(void *raw, int32 code)
204b816dc1eSIngo Weinhold {
205cafaa5aaSStefano Ceccherini 	return inherited::ConvertToMessage(raw, code);
206b816dc1eSIngo Weinhold }
2070b4a36abSbeveloper 
2080b4a36abSbeveloper 
209764ac9e5SAxel Dörfler //	#pragma mark - BDirectWindow specific API
210764ac9e5SAxel Dörfler 
211764ac9e5SAxel Dörfler 
2120b4a36abSbeveloper void
2130b4a36abSbeveloper BDirectWindow::DirectConnected(direct_buffer_info *info)
2140b4a36abSbeveloper {
215cafaa5aaSStefano Ceccherini 	// implemented in subclasses
2160b4a36abSbeveloper }
2170b4a36abSbeveloper 
2180b4a36abSbeveloper 
2190b4a36abSbeveloper status_t
220cafaa5aaSStefano Ceccherini BDirectWindow::GetClippingRegion(BRegion *region, BPoint *origin) const
2210b4a36abSbeveloper {
222cafaa5aaSStefano Ceccherini 	if (region == NULL)
223cafaa5aaSStefano Ceccherini 		return B_BAD_VALUE;
224cafaa5aaSStefano Ceccherini 
2254f6f70e0SStefano Ceccherini 	if (IsLocked() || !LockDirect())
2265fdea13fSStefano Ceccherini 		return B_ERROR;
2275fdea13fSStefano Ceccherini 
228cafaa5aaSStefano Ceccherini 	if (in_direct_connect) {
229cafaa5aaSStefano Ceccherini 		UnlockDirect();
230cafaa5aaSStefano Ceccherini 		return B_ERROR;
231cafaa5aaSStefano Ceccherini 	}
232cafaa5aaSStefano Ceccherini 
233cafaa5aaSStefano Ceccherini 	// BPoint's coordinates are floats. We can only work
234cafaa5aaSStefano Ceccherini 	// with integers.
235cafaa5aaSStefano Ceccherini 	int32 originX, originY;
236cafaa5aaSStefano Ceccherini 	if (origin == NULL) {
237cafaa5aaSStefano Ceccherini 		originX = 0;
238cafaa5aaSStefano Ceccherini 		originY = 0;
239cafaa5aaSStefano Ceccherini 	} else {
240cafaa5aaSStefano Ceccherini 		originX = (int32)origin->x;
241cafaa5aaSStefano Ceccherini 		originY = (int32)origin->y;
242cafaa5aaSStefano Ceccherini 	}
243cafaa5aaSStefano Ceccherini 
244764ac9e5SAxel Dörfler #ifndef HAIKU_TARGET_PLATFORM_DANO
245cafaa5aaSStefano Ceccherini 	// Since we are friend of BRegion, we can access its private members.
246cafaa5aaSStefano Ceccherini 	// Otherwise, we would need to call BRegion::Include(clipping_rect)
247cafaa5aaSStefano Ceccherini 	// for every clipping_rect in our clip_list, and that would be much
2485fdea13fSStefano Ceccherini 	// more overkill than this (tested ).
249cafaa5aaSStefano Ceccherini 	region->set_size(buffer_desc->clip_list_count);
250cafaa5aaSStefano Ceccherini 	region->count = buffer_desc->clip_list_count;
251cafaa5aaSStefano Ceccherini 	region->bound = buffer_desc->clip_bounds;
2524f6f70e0SStefano Ceccherini 	for (uint32 c = 0; c < buffer_desc->clip_list_count; c++)
2534f6f70e0SStefano Ceccherini 		region->data[c] = buffer_desc->clip_list[c];
254cafaa5aaSStefano Ceccherini 
255cafaa5aaSStefano Ceccherini 	// adjust bounds by the given origin point
2564f6f70e0SStefano Ceccherini 	region->OffsetBy(-originX, -originY);
257366fdcdfSMarcus Overhagen #endif
258366fdcdfSMarcus Overhagen 
259cafaa5aaSStefano Ceccherini 	UnlockDirect();
260cafaa5aaSStefano Ceccherini 
261cafaa5aaSStefano Ceccherini 	return B_OK;
262cafaa5aaSStefano Ceccherini 
2630b4a36abSbeveloper }
2640b4a36abSbeveloper 
2650b4a36abSbeveloper 
2660b4a36abSbeveloper status_t
2670b4a36abSbeveloper BDirectWindow::SetFullScreen(bool enable)
2680b4a36abSbeveloper {
269cafaa5aaSStefano Ceccherini 	status_t status = B_ERROR;
27009ea3092SStefano Ceccherini 	if (Lock()) {
271ab6a6bedSAxel Dörfler 		fLink->StartMessage(AS_DIRECT_WINDOW_SET_FULLSCREEN);
272feee8cf2SStefano Ceccherini 		fLink->Attach<bool>(enable);
273feee8cf2SStefano Ceccherini 
274ab6a6bedSAxel Dörfler 		if (fLink->FlushWithReply(status) == B_OK
275ab6a6bedSAxel Dörfler 			&& status == B_OK)
276feee8cf2SStefano Ceccherini 			full_screen_enable = enable;
27709ea3092SStefano Ceccherini 		Unlock();
27809ea3092SStefano Ceccherini 	}
279cafaa5aaSStefano Ceccherini 	return status;
2800b4a36abSbeveloper }
2810b4a36abSbeveloper 
2820b4a36abSbeveloper 
2830b4a36abSbeveloper bool
2840b4a36abSbeveloper BDirectWindow::IsFullScreen() const
2850b4a36abSbeveloper {
286cafaa5aaSStefano Ceccherini 	return full_screen_enable;
2870b4a36abSbeveloper }
2880b4a36abSbeveloper 
2890b4a36abSbeveloper 
2900f4fb801SAxel Dörfler /*static*/
2910b4a36abSbeveloper bool
292cafaa5aaSStefano Ceccherini BDirectWindow::SupportsWindowMode(screen_id id)
2930b4a36abSbeveloper {
294bf9071eeSStefano Ceccherini /*	display_mode mode;
2954fbc3f58SStefano Ceccherini 	status_t status = BScreen(id).GetMode(&mode);
2964fbc3f58SStefano Ceccherini 	if (status == B_OK)
2974fbc3f58SStefano Ceccherini 		return mode.flags & B_PARALLEL_ACCESS;
298feee8cf2SStefano Ceccherini 
299bf9071eeSStefano Ceccherini 	return false;*/
300bf9071eeSStefano Ceccherini 	// TODO: Apparently, the above is false for the vesa driver,
301bf9071eeSStefano Ceccherini 	// but enabling it doesn't do any harm... maybe we should just return always true.
302bf9071eeSStefano Ceccherini 	// At least, I can't see why window mode shouldn't be supported.
303bf9071eeSStefano Ceccherini 	return true;
304cafaa5aaSStefano Ceccherini }
305cafaa5aaSStefano Ceccherini 
306cafaa5aaSStefano Ceccherini 
3070f4fb801SAxel Dörfler //	#pragma mark - Private methods
3080f4fb801SAxel Dörfler 
3090f4fb801SAxel Dörfler 
310cafaa5aaSStefano Ceccherini int32
311*af294326SPhilippe Houdoin BDirectWindow::DirectDaemonFunc(void *arg)
312cafaa5aaSStefano Ceccherini {
313cafaa5aaSStefano Ceccherini 	BDirectWindow *object = static_cast<BDirectWindow *>(arg);
314cafaa5aaSStefano Ceccherini 
315*af294326SPhilippe Houdoin 	while (!object->daemon_killer) {
316cafaa5aaSStefano Ceccherini 		// This sem is released by the app_server when our
317cafaa5aaSStefano Ceccherini 		// clipping region changes, or when our window is moved,
318cafaa5aaSStefano Ceccherini 		// resized, etc. etc.
3190f4fb801SAxel Dörfler 		status_t status;
3200f4fb801SAxel Dörfler 		do {
3210f4fb801SAxel Dörfler 			status = acquire_sem(object->disable_sem);
3220f4fb801SAxel Dörfler 		} while (status == B_INTERRUPTED);
3230f4fb801SAxel Dörfler 
3240f4fb801SAxel Dörfler 		if (status < B_OK)
3250f4fb801SAxel Dörfler 			return -1;
326cafaa5aaSStefano Ceccherini 
327cafaa5aaSStefano Ceccherini 		if (object->LockDirect()) {
328cafaa5aaSStefano Ceccherini 			if ((object->buffer_desc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_START)
329cafaa5aaSStefano Ceccherini 				object->connection_enable = true;
330cafaa5aaSStefano Ceccherini 
331cafaa5aaSStefano Ceccherini 			object->in_direct_connect = true;
332cafaa5aaSStefano Ceccherini 			object->DirectConnected(object->buffer_desc);
333cafaa5aaSStefano Ceccherini 			object->in_direct_connect = false;
334cafaa5aaSStefano Ceccherini 
335cafaa5aaSStefano Ceccherini 			if ((object->buffer_desc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_STOP)
336cafaa5aaSStefano Ceccherini 				object->connection_enable = false;
337cafaa5aaSStefano Ceccherini 
338cafaa5aaSStefano Ceccherini 			object->UnlockDirect();
339cafaa5aaSStefano Ceccherini 		}
340cafaa5aaSStefano Ceccherini 
341cafaa5aaSStefano Ceccherini 		// The app_server then waits (with a timeout) on this sem.
342cafaa5aaSStefano Ceccherini 		// If we aren't quick enough to release this sem, our app
343cafaa5aaSStefano Ceccherini 		// will be terminated by the app_server
3440f4fb801SAxel Dörfler 		if (release_sem(object->disable_sem_ack) != B_OK)
3450f4fb801SAxel Dörfler 			return -1;
346cafaa5aaSStefano Ceccherini 	}
347cafaa5aaSStefano Ceccherini 
348cafaa5aaSStefano Ceccherini 	return 0;
349cafaa5aaSStefano Ceccherini }
350cafaa5aaSStefano Ceccherini 
351cafaa5aaSStefano Ceccherini 
35217495d0bSStefano Ceccherini // LockDirect() and UnlockDirect() are no-op on R5. I tried to call (R5's) LockDirect()
35317495d0bSStefano Ceccherini // repeatedly, from the same thread and from different threads, nothing happened.
35417495d0bSStefano Ceccherini // I implemented them anyway, as they were the first methods I wrote
35517495d0bSStefano Ceccherini // in this class (As you can see, I even needed to cast away their constness
35617495d0bSStefano Ceccherini // to make them do something useful).
357*af294326SPhilippe Houdoin // They're not needed though, as the direct_daemon_thread doesn't change
35817495d0bSStefano Ceccherini // any shared data. They are probably here for future enhancements (see also the
35917495d0bSStefano Ceccherini // comment in DriverSetup()
360cafaa5aaSStefano Ceccherini bool
361cafaa5aaSStefano Ceccherini BDirectWindow::LockDirect() const
362cafaa5aaSStefano Ceccherini {
363cafaa5aaSStefano Ceccherini 	status_t status = B_OK;
364cafaa5aaSStefano Ceccherini 
365cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING
366cafaa5aaSStefano Ceccherini 	BDirectWindow *casted = const_cast<BDirectWindow *>(this);
367cafaa5aaSStefano Ceccherini 
3685fdea13fSStefano Ceccherini 	if (atomic_add(&casted->direct_lock, 1) > 0) {
369cafaa5aaSStefano Ceccherini 		do {
370cafaa5aaSStefano Ceccherini 			status = acquire_sem(direct_sem);
371cafaa5aaSStefano Ceccherini 		} while (status == B_INTERRUPTED);
3725fdea13fSStefano Ceccherini 	}
373cafaa5aaSStefano Ceccherini 
374cafaa5aaSStefano Ceccherini 	if (status == B_OK) {
375cafaa5aaSStefano Ceccherini 		casted->direct_lock_owner = find_thread(NULL);
376cafaa5aaSStefano Ceccherini 		casted->direct_lock_count++;
377cafaa5aaSStefano Ceccherini 	}
378cafaa5aaSStefano Ceccherini #endif
379cafaa5aaSStefano Ceccherini 
380cafaa5aaSStefano Ceccherini 	return status == B_OK;
3810b4a36abSbeveloper }
3820b4a36abSbeveloper 
3830b4a36abSbeveloper 
3840b4a36abSbeveloper void
385cafaa5aaSStefano Ceccherini BDirectWindow::UnlockDirect() const
3860b4a36abSbeveloper {
387cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING
388cafaa5aaSStefano Ceccherini 	BDirectWindow *casted = const_cast<BDirectWindow *>(this);
389cafaa5aaSStefano Ceccherini 
390cafaa5aaSStefano Ceccherini 	if (atomic_add(&casted->direct_lock, -1) > 1)
391cafaa5aaSStefano Ceccherini 		release_sem(direct_sem);
392cafaa5aaSStefano Ceccherini 
393cafaa5aaSStefano Ceccherini 	casted->direct_lock_count--;
394cafaa5aaSStefano Ceccherini #endif
3950b4a36abSbeveloper }
3960b4a36abSbeveloper 
3970b4a36abSbeveloper 
3980b4a36abSbeveloper void
399cafaa5aaSStefano Ceccherini BDirectWindow::InitData()
4000b4a36abSbeveloper {
401cafaa5aaSStefano Ceccherini 	connection_enable = false;
402cafaa5aaSStefano Ceccherini 	full_screen_enable = false;
403cafaa5aaSStefano Ceccherini 	in_direct_connect = false;
404cafaa5aaSStefano Ceccherini 
405cafaa5aaSStefano Ceccherini 	dw_init_status = 0;
406cafaa5aaSStefano Ceccherini 
407cafaa5aaSStefano Ceccherini 	direct_driver_ready = false;
408cafaa5aaSStefano Ceccherini 	direct_driver_type = 0;
409cafaa5aaSStefano Ceccherini 	direct_driver_token = 0;
410cafaa5aaSStefano Ceccherini 	direct_driver = NULL;
411cafaa5aaSStefano Ceccherini 
4125fdea13fSStefano Ceccherini 	if (!Lock())
4135fdea13fSStefano Ceccherini 		return;
4145fdea13fSStefano Ceccherini 
41571b55088SAxel Dörfler 	struct direct_window_sync_data syncData;
4168575beb8SJérôme Duval 
417ab6a6bedSAxel Dörfler 	fLink->StartMessage(AS_DIRECT_WINDOW_GET_SYNC_DATA);
418feee8cf2SStefano Ceccherini 
4192b6ac345SStefano Ceccherini 	status_t status = B_ERROR;
4202b6ac345SStefano Ceccherini 	if (fLink->FlushWithReply(status) == B_OK
4212b6ac345SStefano Ceccherini 		&& status == B_OK) {
42271b55088SAxel Dörfler 		fLink->Read<direct_window_sync_data>(&syncData);
423feee8cf2SStefano Ceccherini 	}
424feee8cf2SStefano Ceccherini 
425cafaa5aaSStefano Ceccherini 	Unlock();
426cafaa5aaSStefano Ceccherini 
4275fdea13fSStefano Ceccherini 	if (status < B_OK)
4285fdea13fSStefano Ceccherini 		return;
429cafaa5aaSStefano Ceccherini 
430cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING
431cafaa5aaSStefano Ceccherini 	direct_lock = 0;
432cafaa5aaSStefano Ceccherini 	direct_lock_count = 0;
4335fdea13fSStefano Ceccherini 	direct_lock_owner = -1;
434cafaa5aaSStefano Ceccherini 	direct_lock_stack = NULL;
435cafaa5aaSStefano Ceccherini 	direct_sem = create_sem(1, "direct sem");
436cafaa5aaSStefano Ceccherini 	if (direct_sem > 0)
437cafaa5aaSStefano Ceccherini 		dw_init_status |= DW_STATUS_SEM_CREATED;
438cafaa5aaSStefano Ceccherini #endif
439cafaa5aaSStefano Ceccherini 
44071b55088SAxel Dörfler 	source_clipping_area = syncData.area;
44171b55088SAxel Dörfler 	disable_sem = syncData.disable_sem;
44271b55088SAxel Dörfler 	disable_sem_ack = syncData.disable_sem_ack;
443cafaa5aaSStefano Ceccherini 
444cafaa5aaSStefano Ceccherini 	cloned_clipping_area = clone_area("Clone direct area", (void**)&buffer_desc,
445cafaa5aaSStefano Ceccherini 		B_ANY_ADDRESS, B_READ_AREA, source_clipping_area);
4465fdea13fSStefano Ceccherini 
447cafaa5aaSStefano Ceccherini 	if (cloned_clipping_area > 0) {
448cafaa5aaSStefano Ceccherini 		dw_init_status |= DW_STATUS_AREA_CLONED;
449cafaa5aaSStefano Ceccherini 
450*af294326SPhilippe Houdoin 		direct_daemon_id = spawn_thread(DirectDaemonFunc, "direct daemon",
451cafaa5aaSStefano Ceccherini 				B_DISPLAY_PRIORITY, this);
452cafaa5aaSStefano Ceccherini 
453*af294326SPhilippe Houdoin 		if (direct_daemon_id > 0) {
454*af294326SPhilippe Houdoin 			daemon_killer = false;
455*af294326SPhilippe Houdoin 			if (resume_thread(direct_daemon_id) == B_OK)
456cafaa5aaSStefano Ceccherini 				dw_init_status |= DW_STATUS_THREAD_STARTED;
457cafaa5aaSStefano Ceccherini 			else
458*af294326SPhilippe Houdoin 				kill_thread(direct_daemon_id);
459cafaa5aaSStefano Ceccherini 		}
460cafaa5aaSStefano Ceccherini 	}
461cafaa5aaSStefano Ceccherini }
4620b4a36abSbeveloper 
4630b4a36abSbeveloper 
4640b4a36abSbeveloper void
465cafaa5aaSStefano Ceccherini BDirectWindow::DisposeData()
4660b4a36abSbeveloper {
467cafaa5aaSStefano Ceccherini 	// wait until the connection terminates: we can't destroy
468cafaa5aaSStefano Ceccherini 	// the object until the client receives the B_DIRECT_STOP
469cafaa5aaSStefano Ceccherini 	// notification, or bad things will happen
470cafaa5aaSStefano Ceccherini 	while (connection_enable)
471cafaa5aaSStefano Ceccherini 		snooze(50000);
472cafaa5aaSStefano Ceccherini 
473cafaa5aaSStefano Ceccherini 	LockDirect();
474cafaa5aaSStefano Ceccherini 
475cafaa5aaSStefano Ceccherini 	if (dw_init_status & DW_STATUS_THREAD_STARTED) {
476*af294326SPhilippe Houdoin 		daemon_killer = true;
477*af294326SPhilippe Houdoin 		// Release this sem, otherwise the Direct daemon thread
478cafaa5aaSStefano Ceccherini 		// will wait forever on it
479cafaa5aaSStefano Ceccherini 		release_sem(disable_sem);
480cafaa5aaSStefano Ceccherini 		status_t retVal;
481*af294326SPhilippe Houdoin 		wait_for_thread(direct_daemon_id, &retVal);
482cafaa5aaSStefano Ceccherini 	}
483cafaa5aaSStefano Ceccherini 
484cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING
485cafaa5aaSStefano Ceccherini 	if (dw_init_status & DW_STATUS_SEM_CREATED)
486cafaa5aaSStefano Ceccherini 		delete_sem(direct_sem);
487cafaa5aaSStefano Ceccherini #endif
488cafaa5aaSStefano Ceccherini 
489cafaa5aaSStefano Ceccherini 	if (dw_init_status & DW_STATUS_AREA_CLONED)
490cafaa5aaSStefano Ceccherini 		delete_area(cloned_clipping_area);
4910b4a36abSbeveloper }
4920b4a36abSbeveloper 
4930b4a36abSbeveloper 
494cafaa5aaSStefano Ceccherini status_t
495cafaa5aaSStefano Ceccherini BDirectWindow::DriverSetup() const
4960b4a36abSbeveloper {
49717495d0bSStefano Ceccherini 	// Unimplemented in R5.
49809ea3092SStefano Ceccherini 	// This function is probably here because they wanted, in a future time,
49909ea3092SStefano Ceccherini 	// to implement graphic acceleration within BDirectWindow
50009ea3092SStefano Ceccherini 	// (in fact, there is also a BDirectDriver member in BDirectWindow,
50117495d0bSStefano Ceccherini 	// though it's not used).
50209ea3092SStefano Ceccherini 
503cafaa5aaSStefano Ceccherini 	return B_OK;
5040b4a36abSbeveloper }
5050b4a36abSbeveloper 
5060b4a36abSbeveloper 
507cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow1() {}
508cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow2() {}
509cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow3() {}
510cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow4() {}
511