xref: /haiku/src/kits/game/DirectWindow.cpp (revision 302f62604763c95777d6d04cca456e876f471c4f)
109ea3092SStefano Ceccherini /*
2*302f6260SStefano Ceccherini  * Copyright 2003-2006, 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 
20af294326SPhilippe 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 
2282b73985eSStefano Ceccherini 	if (fInDirectConnect) {
229cafaa5aaSStefano Ceccherini 		UnlockDirect();
230cafaa5aaSStefano Ceccherini 		return B_ERROR;
231cafaa5aaSStefano Ceccherini 	}
232cafaa5aaSStefano Ceccherini 
233cafaa5aaSStefano Ceccherini 	// BPoint's coordinates are floats. We can only work
2342b73985eSStefano Ceccherini 	// with integers._DaemonStarter
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 ).
2492b73985eSStefano Ceccherini 	region->set_size(fBufferDesc->clip_list_count);
2502b73985eSStefano Ceccherini 	region->count = fBufferDesc->clip_list_count;
2512b73985eSStefano Ceccherini 	region->bound = fBufferDesc->clip_bounds;
2522b73985eSStefano Ceccherini 	for (uint32 c = 0; c < fBufferDesc->clip_list_count; c++)
2532b73985eSStefano Ceccherini 		region->data[c] = fBufferDesc->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 {
2692b73985eSStefano Ceccherini 	if (fIsFullScreen == enable)
2702b73985eSStefano Ceccherini 		return B_OK;
2712b73985eSStefano Ceccherini 
272cafaa5aaSStefano Ceccherini 	status_t status = B_ERROR;
27309ea3092SStefano Ceccherini 	if (Lock()) {
274ab6a6bedSAxel Dörfler 		fLink->StartMessage(AS_DIRECT_WINDOW_SET_FULLSCREEN);
275feee8cf2SStefano Ceccherini 		fLink->Attach<bool>(enable);
276feee8cf2SStefano Ceccherini 
277ab6a6bedSAxel Dörfler 		if (fLink->FlushWithReply(status) == B_OK
2789ecf9d1cSIngo Weinhold 			&& status == B_OK) {
2792b73985eSStefano Ceccherini 			fIsFullScreen = enable;
2809ecf9d1cSIngo Weinhold 		}
28109ea3092SStefano Ceccherini 		Unlock();
28209ea3092SStefano Ceccherini 	}
283cafaa5aaSStefano Ceccherini 	return status;
2840b4a36abSbeveloper }
2850b4a36abSbeveloper 
2860b4a36abSbeveloper 
2870b4a36abSbeveloper bool
2880b4a36abSbeveloper BDirectWindow::IsFullScreen() const
2890b4a36abSbeveloper {
2902b73985eSStefano Ceccherini 	return fIsFullScreen;
2910b4a36abSbeveloper }
2920b4a36abSbeveloper 
2930b4a36abSbeveloper 
2940f4fb801SAxel Dörfler /*static*/
2950b4a36abSbeveloper bool
296cafaa5aaSStefano Ceccherini BDirectWindow::SupportsWindowMode(screen_id id)
2970b4a36abSbeveloper {
298bf9071eeSStefano Ceccherini /*	display_mode mode;
2994fbc3f58SStefano Ceccherini 	status_t status = BScreen(id).GetMode(&mode);
3004fbc3f58SStefano Ceccherini 	if (status == B_OK)
3014fbc3f58SStefano Ceccherini 		return mode.flags & B_PARALLEL_ACCESS;
302feee8cf2SStefano Ceccherini 
303bf9071eeSStefano Ceccherini 	return false;*/
304bf9071eeSStefano Ceccherini 	// TODO: Apparently, the above is false for the vesa driver,
305bf9071eeSStefano Ceccherini 	// but enabling it doesn't do any harm... maybe we should just return always true.
306bf9071eeSStefano Ceccherini 	// At least, I can't see why window mode shouldn't be supported.
3079ecf9d1cSIngo Weinhold 	// additional NOTE: it probably depends on wether hardware cursor is supported or
3089ecf9d1cSIngo Weinhold 	// not
309bf9071eeSStefano Ceccherini 	return true;
310cafaa5aaSStefano Ceccherini }
311cafaa5aaSStefano Ceccherini 
312cafaa5aaSStefano Ceccherini 
3130f4fb801SAxel Dörfler //	#pragma mark - Private methods
3140f4fb801SAxel Dörfler 
3152b73985eSStefano Ceccherini /* static */
3162b73985eSStefano Ceccherini int32
3172b73985eSStefano Ceccherini BDirectWindow::_DaemonStarter(void *arg)
3182b73985eSStefano Ceccherini {
3192b73985eSStefano Ceccherini 	return static_cast<BDirectWindow *>(arg)->DirectDaemonFunc();
3202b73985eSStefano Ceccherini }
3212b73985eSStefano Ceccherini 
3220f4fb801SAxel Dörfler 
323cafaa5aaSStefano Ceccherini int32
3242b73985eSStefano Ceccherini BDirectWindow::DirectDaemonFunc()
325cafaa5aaSStefano Ceccherini {
3262b73985eSStefano Ceccherini 	while (!fDaemonKiller) {
327cafaa5aaSStefano Ceccherini 		// This sem is released by the app_server when our
328cafaa5aaSStefano Ceccherini 		// clipping region changes, or when our window is moved,
329cafaa5aaSStefano Ceccherini 		// resized, etc. etc.
3300f4fb801SAxel Dörfler 		status_t status;
3310f4fb801SAxel Dörfler 		do {
3322b73985eSStefano Ceccherini 			status = acquire_sem(fDisableSem);
3330f4fb801SAxel Dörfler 		} while (status == B_INTERRUPTED);
3340f4fb801SAxel Dörfler 
3350f4fb801SAxel Dörfler 		if (status < B_OK)
3360f4fb801SAxel Dörfler 			return -1;
337cafaa5aaSStefano Ceccherini 
3382b73985eSStefano Ceccherini 		if (LockDirect()) {
3392b73985eSStefano Ceccherini 			if ((fBufferDesc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_START)
3402b73985eSStefano Ceccherini 				fConnectionEnable = true;
341cafaa5aaSStefano Ceccherini 
3422b73985eSStefano Ceccherini 			fInDirectConnect = true;
3432b73985eSStefano Ceccherini 			DirectConnected(fBufferDesc);
3442b73985eSStefano Ceccherini 			fInDirectConnect = false;
345cafaa5aaSStefano Ceccherini 
3462b73985eSStefano Ceccherini 			if ((fBufferDesc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_STOP)
3472b73985eSStefano Ceccherini 				fConnectionEnable = false;
348cafaa5aaSStefano Ceccherini 
3492b73985eSStefano Ceccherini 			UnlockDirect();
350cafaa5aaSStefano Ceccherini 		}
351cafaa5aaSStefano Ceccherini 
352cafaa5aaSStefano Ceccherini 		// The app_server then waits (with a timeout) on this sem.
353cafaa5aaSStefano Ceccherini 		// If we aren't quick enough to release this sem, our app
354cafaa5aaSStefano Ceccherini 		// will be terminated by the app_server
3552b73985eSStefano Ceccherini 		if (release_sem(fDisableSemAck) != B_OK)
3560f4fb801SAxel Dörfler 			return -1;
357cafaa5aaSStefano Ceccherini 	}
358cafaa5aaSStefano Ceccherini 
359cafaa5aaSStefano Ceccherini 	return 0;
360cafaa5aaSStefano Ceccherini }
361cafaa5aaSStefano Ceccherini 
362cafaa5aaSStefano Ceccherini 
36317495d0bSStefano Ceccherini // LockDirect() and UnlockDirect() are no-op on R5. I tried to call (R5's) LockDirect()
36417495d0bSStefano Ceccherini // repeatedly, from the same thread and from different threads, nothing happened.
36517495d0bSStefano Ceccherini // I implemented them anyway, as they were the first methods I wrote
36617495d0bSStefano Ceccherini // in this class (As you can see, I even needed to cast away their constness
36717495d0bSStefano Ceccherini // to make them do something useful).
368af294326SPhilippe Houdoin // They're not needed though, as the direct_daemon_thread doesn't change
36917495d0bSStefano Ceccherini // any shared data. They are probably here for future enhancements (see also the
37017495d0bSStefano Ceccherini // comment in DriverSetup()
371cafaa5aaSStefano Ceccherini bool
372cafaa5aaSStefano Ceccherini BDirectWindow::LockDirect() const
373cafaa5aaSStefano Ceccherini {
374cafaa5aaSStefano Ceccherini 	status_t status = B_OK;
375cafaa5aaSStefano Ceccherini 
376cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING
377cafaa5aaSStefano Ceccherini 	BDirectWindow *casted = const_cast<BDirectWindow *>(this);
378cafaa5aaSStefano Ceccherini 
3792b73985eSStefano Ceccherini 	if (atomic_add(&casted->fDirectLock, 1) > 0) {
380cafaa5aaSStefano Ceccherini 		do {
3812b73985eSStefano Ceccherini 			status = acquire_sem(fDirectSem);
382cafaa5aaSStefano Ceccherini 		} while (status == B_INTERRUPTED);
3835fdea13fSStefano Ceccherini 	}
384cafaa5aaSStefano Ceccherini 
385cafaa5aaSStefano Ceccherini 	if (status == B_OK) {
3862b73985eSStefano Ceccherini 		casted->fDirectLockOwner = find_thread(NULL);
3872b73985eSStefano Ceccherini 		casted->fDirectLockCount++;
388cafaa5aaSStefano Ceccherini 	}
389cafaa5aaSStefano Ceccherini #endif
390cafaa5aaSStefano Ceccherini 
391cafaa5aaSStefano Ceccherini 	return status == B_OK;
3920b4a36abSbeveloper }
3930b4a36abSbeveloper 
3940b4a36abSbeveloper 
3950b4a36abSbeveloper void
396cafaa5aaSStefano Ceccherini BDirectWindow::UnlockDirect() const
3970b4a36abSbeveloper {
398cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING
399cafaa5aaSStefano Ceccherini 	BDirectWindow *casted = const_cast<BDirectWindow *>(this);
400cafaa5aaSStefano Ceccherini 
4012b73985eSStefano Ceccherini 	if (atomic_add(&casted->fDirectLock, -1) > 1)
4022b73985eSStefano Ceccherini 		release_sem(casted->fDirectSem);
403cafaa5aaSStefano Ceccherini 
4042b73985eSStefano Ceccherini 	casted->fDirectLockCount--;
405cafaa5aaSStefano Ceccherini #endif
4060b4a36abSbeveloper }
4070b4a36abSbeveloper 
4080b4a36abSbeveloper 
4090b4a36abSbeveloper void
410cafaa5aaSStefano Ceccherini BDirectWindow::InitData()
4110b4a36abSbeveloper {
4122b73985eSStefano Ceccherini 	fConnectionEnable = false;
4132b73985eSStefano Ceccherini 	fIsFullScreen = false;
4142b73985eSStefano Ceccherini 	fInDirectConnect = false;
415cafaa5aaSStefano Ceccherini 
4162b73985eSStefano Ceccherini 	fInitStatus = 0;
417cafaa5aaSStefano Ceccherini 
4182b73985eSStefano Ceccherini 	fDirectDriverReady = false;
4192b73985eSStefano Ceccherini 	fDirectDriverType = 0;
4202b73985eSStefano Ceccherini 	fDirectDriverToken = 0;
421cafaa5aaSStefano Ceccherini 	direct_driver = NULL;
422cafaa5aaSStefano Ceccherini 
4232b6ac345SStefano Ceccherini 	status_t status = B_ERROR;
4242b73985eSStefano Ceccherini 	struct direct_window_sync_data syncData;
4252b73985eSStefano Ceccherini 	if (Lock()) {
4262b73985eSStefano Ceccherini 		fLink->StartMessage(AS_DIRECT_WINDOW_GET_SYNC_DATA);
4272b6ac345SStefano Ceccherini 		if (fLink->FlushWithReply(status) == B_OK
4282b6ac345SStefano Ceccherini 			&& status == B_OK) {
42971b55088SAxel Dörfler 			fLink->Read<direct_window_sync_data>(&syncData);
430feee8cf2SStefano Ceccherini 		}
431cafaa5aaSStefano Ceccherini 		Unlock();
4322b73985eSStefano Ceccherini 	}
4335fdea13fSStefano Ceccherini 	if (status < B_OK)
4345fdea13fSStefano Ceccherini 		return;
435cafaa5aaSStefano Ceccherini 
436cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING
4372b73985eSStefano Ceccherini 	fDirectLock = 0;
4382b73985eSStefano Ceccherini 	fDirectLockCount = 0;
4392b73985eSStefano Ceccherini 	fDirectLockOwner = -1;
4402b73985eSStefano Ceccherini 	fDirectLockStack = NULL;
4412b73985eSStefano Ceccherini 	fDirectSem = create_sem(1, "direct sem");
4422b73985eSStefano Ceccherini 	if (fDirectSem > 0)
4432b73985eSStefano Ceccherini 		fInitStatus |= DW_STATUS_SEM_CREATED;
444cafaa5aaSStefano Ceccherini #endif
445cafaa5aaSStefano Ceccherini 
4462b73985eSStefano Ceccherini 	fSourceClippingArea = syncData.area;
4472b73985eSStefano Ceccherini 	fDisableSem = syncData.disable_sem;
4482b73985eSStefano Ceccherini 	fDisableSemAck = syncData.disable_sem_ack;
449cafaa5aaSStefano Ceccherini 
4502b73985eSStefano Ceccherini 	fClonedClippingArea = clone_area("Clone direct area", (void**)&fBufferDesc,
4512b73985eSStefano Ceccherini 		B_ANY_ADDRESS, B_READ_AREA, fSourceClippingArea);
4525fdea13fSStefano Ceccherini 
453*302f6260SStefano Ceccherini 	if (fClonedClippingArea > 0) {
4542b73985eSStefano Ceccherini 		fInitStatus |= DW_STATUS_AREA_CLONED;
455cafaa5aaSStefano Ceccherini 
4562b73985eSStefano Ceccherini 		fDirectDaemonId = spawn_thread(_DaemonStarter, "direct daemon",
457cafaa5aaSStefano Ceccherini 				B_DISPLAY_PRIORITY, this);
458cafaa5aaSStefano Ceccherini 
4592b73985eSStefano Ceccherini 		if (fDirectDaemonId > 0) {
4602b73985eSStefano Ceccherini 			fDaemonKiller = false;
4612b73985eSStefano Ceccherini 			if (resume_thread(fDirectDaemonId) == B_OK)
4622b73985eSStefano Ceccherini 				fInitStatus |= DW_STATUS_THREAD_STARTED;
463cafaa5aaSStefano Ceccherini 			else
4642b73985eSStefano Ceccherini 				kill_thread(fDirectDaemonId);
465cafaa5aaSStefano Ceccherini 		}
466cafaa5aaSStefano Ceccherini 	}
467cafaa5aaSStefano Ceccherini }
4680b4a36abSbeveloper 
4690b4a36abSbeveloper 
4700b4a36abSbeveloper void
471cafaa5aaSStefano Ceccherini BDirectWindow::DisposeData()
4720b4a36abSbeveloper {
473cafaa5aaSStefano Ceccherini 	// wait until the connection terminates: we can't destroy
474cafaa5aaSStefano Ceccherini 	// the object until the client receives the B_DIRECT_STOP
475cafaa5aaSStefano Ceccherini 	// notification, or bad things will happen
4762b73985eSStefano Ceccherini 	while (fConnectionEnable)
477cafaa5aaSStefano Ceccherini 		snooze(50000);
478cafaa5aaSStefano Ceccherini 
479cafaa5aaSStefano Ceccherini 	LockDirect();
480cafaa5aaSStefano Ceccherini 
4812b73985eSStefano Ceccherini 	if (fInitStatus & DW_STATUS_THREAD_STARTED) {
4822b73985eSStefano Ceccherini 		fDaemonKiller = true;
483af294326SPhilippe Houdoin 		// Release this sem, otherwise the Direct daemon thread
484cafaa5aaSStefano Ceccherini 		// will wait forever on it
4852b73985eSStefano Ceccherini 		release_sem(fDisableSem);
486cafaa5aaSStefano Ceccherini 		status_t retVal;
4872b73985eSStefano Ceccherini 		wait_for_thread(fDirectDaemonId, &retVal);
488cafaa5aaSStefano Ceccherini 	}
489cafaa5aaSStefano Ceccherini 
490cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING
4912b73985eSStefano Ceccherini 	if (fInitStatus & DW_STATUS_SEM_CREATED)
4922b73985eSStefano Ceccherini 		delete_sem(fDirectSem);
493cafaa5aaSStefano Ceccherini #endif
494cafaa5aaSStefano Ceccherini 
4952b73985eSStefano Ceccherini 	if (fInitStatus & DW_STATUS_AREA_CLONED)
4962b73985eSStefano Ceccherini 		delete_area(fClonedClippingArea);
4970b4a36abSbeveloper }
4980b4a36abSbeveloper 
4990b4a36abSbeveloper 
500cafaa5aaSStefano Ceccherini status_t
501cafaa5aaSStefano Ceccherini BDirectWindow::DriverSetup() const
5020b4a36abSbeveloper {
50317495d0bSStefano Ceccherini 	// Unimplemented in R5.
50409ea3092SStefano Ceccherini 	// This function is probably here because they wanted, in a future time,
50509ea3092SStefano Ceccherini 	// to implement graphic acceleration within BDirectWindow
50609ea3092SStefano Ceccherini 	// (in fact, there is also a BDirectDriver member in BDirectWindow,
50717495d0bSStefano Ceccherini 	// though it's not used).
50809ea3092SStefano Ceccherini 
509cafaa5aaSStefano Ceccherini 	return B_OK;
5100b4a36abSbeveloper }
5110b4a36abSbeveloper 
5120b4a36abSbeveloper 
513cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow1() {}
514cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow2() {}
515cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow3() {}
516cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow4() {}
517