12c704682SAxel Dörfler/*
237fedaf8SJohn Scipione * Copyright 2003-2009 Haiku, Inc. All rights reserved.
337fedaf8SJohn Scipione * Distributed under the terms of the MIT License.
437fedaf8SJohn Scipione *
517495d0bSStefano Ceccherini * Authors:
6d9cebac2SStefano Ceccherini *		Stefano Ceccherini <stefano.ceccherini@gmail.com>
7d9cebac2SStefano Ceccherini *		Carwyn Jones <turok2@currantbun.com>
809ea3092SStefano Ceccherini */
9cafaa5aaSStefano Ceccherini
102c704682SAxel Dörfler
11cafaa5aaSStefano Ceccherini#include <DirectWindow.h>
122c704682SAxel Dörfler
132c704682SAxel Dörfler#include <stdio.h>
142c704682SAxel Dörfler#include <string.h>
152c704682SAxel Dörfler
164fbc3f58SStefano Ceccherini#include <Screen.h>
1771b55088SAxel Dörfler
18cafaa5aaSStefano Ceccherini#include <clipping.h>
192b6ac345SStefano Ceccherini#include <AppServerLink.h>
2071b55088SAxel Dörfler#include <DirectWindowPrivate.h>
212b6ac345SStefano Ceccherini#include <ServerProtocol.h>
22366fdcdfSMarcus Overhagen
235115ca08SStefano Ceccherini
242c704682SAxel Dörfler//#define DEBUG		1
252c704682SAxel Dörfler#define OUTPUT		printf
262c704682SAxel Dörfler//#define OUTPUT	debug_printf
27366fdcdfSMarcus Overhagen
282c704682SAxel Dörfler
292c704682SAxel Dörfler// We don't need this kind of locking, since the directDaemonFunc
30cafaa5aaSStefano Ceccherini// doesn't access critical shared data.
31cafaa5aaSStefano Ceccherini#define DW_NEEDS_LOCKING 0
32cafaa5aaSStefano Ceccherini
33cafaa5aaSStefano Ceccherinienum dw_status_bits {
3417495d0bSStefano Ceccherini	DW_STATUS_AREA_CLONED	 = 0x1,
3517495d0bSStefano Ceccherini	DW_STATUS_THREAD_STARTED = 0x2,
3617495d0bSStefano Ceccherini	DW_STATUS_SEM_CREATED	 = 0x4
37cafaa5aaSStefano Ceccherini};
38cafaa5aaSStefano Ceccherini
39cafaa5aaSStefano Ceccherini
405115ca08SStefano Ceccherini#if DEBUG
412c704682SAxel Dörfler
422c704682SAxel Dörfler
435115ca08SStefano Ceccherinistatic void
445115ca08SStefano Ceccheriniprint_direct_buffer_state(const direct_buffer_state &state)
455115ca08SStefano Ceccherini{
465115ca08SStefano Ceccherini	char string[128];
475115ca08SStefano Ceccherini	int modeState = state & B_DIRECT_MODE_MASK;
48652f187eSStefano Ceccherini	if (modeState == B_DIRECT_START)
495115ca08SStefano Ceccherini		strcpy(string, "B_DIRECT_START");
50652f187eSStefano Ceccherini	else if (modeState == B_DIRECT_MODIFY)
512c704682SAxel Dörfler		strcpy(string, "B_DIRECT_MODIFY");
52652f187eSStefano Ceccherini	else if (modeState == B_DIRECT_STOP)
535115ca08SStefano Ceccherini		strcpy(string, "B_DIRECT_STOP");
545115ca08SStefano Ceccherini
555115ca08SStefano Ceccherini	if (state & B_CLIPPING_MODIFIED)
565115ca08SStefano Ceccherini		strcat(string, " | B_CLIPPING_MODIFIED");
575115ca08SStefano Ceccherini	if (state & B_BUFFER_RESIZED)
585115ca08SStefano Ceccherini		strcat(string, " | B_BUFFER_RESIZED");
595115ca08SStefano Ceccherini	if (state & B_BUFFER_MOVED)
605115ca08SStefano Ceccherini		strcat(string, " | B_BUFFER_MOVED");
615115ca08SStefano Ceccherini	if (state & B_BUFFER_RESET)
625115ca08SStefano Ceccherini		strcat(string, " | B_BUFFER_RESET");
632c704682SAxel Dörfler
642c704682SAxel Dörfler	OUTPUT("direct_buffer_state: %s\n", string);
655115ca08SStefano Ceccherini}
665115ca08SStefano Ceccherini
675115ca08SStefano Ceccherini
685115ca08SStefano Ceccherinistatic void
695115ca08SStefano Ceccheriniprint_direct_driver_state(const direct_driver_state &state)
705115ca08SStefano Ceccherini{
715115ca08SStefano Ceccherini	if (state == 0)
725115ca08SStefano Ceccherini		return;
735115ca08SStefano Ceccherini
745115ca08SStefano Ceccherini	char string[64];
755115ca08SStefano Ceccherini	if (state == B_DRIVER_CHANGED)
762c704682SAxel Dörfler		strcpy(string, "B_DRIVER_CHANGED");
775115ca08SStefano Ceccherini	else if (state == B_MODE_CHANGED)
785115ca08SStefano Ceccherini		strcpy(string, "B_MODE_CHANGED");
792c704682SAxel Dörfler
802c704682SAxel Dörfler	OUTPUT("direct_driver_state: %s\n", string);
815115ca08SStefano Ceccherini}
825115ca08SStefano Ceccherini
835115ca08SStefano Ceccherini
842c704682SAxel Dörfler#if DEBUG > 1
852c704682SAxel Dörfler
862c704682SAxel Dörfler
8728fa0645SStefano Ceccherinistatic void
8828fa0645SStefano Ceccheriniprint_direct_buffer_layout(const buffer_layout &layout)
892c704682SAxel Dörfler{
9028fa0645SStefano Ceccherini	char string[64];
9128fa0645SStefano Ceccherini	if (layout == B_BUFFER_NONINTERLEAVED)
922c704682SAxel Dörfler		strcpy(string, "B_BUFFER_NONINTERLEAVED");
9328fa0645SStefano Ceccherini	else
9428fa0645SStefano Ceccherini		strcpy(string, "unknown");
952c704682SAxel Dörfler
962c704682SAxel Dörfler	OUTPUT("layout: %s\n", string);
9728fa0645SStefano Ceccherini}
9828fa0645SStefano Ceccherini
9928fa0645SStefano Ceccherini
10028fa0645SStefano Ceccherinistatic void
10128fa0645SStefano Ceccheriniprint_direct_buffer_orientation(const buffer_orientation &orientation)
1022c704682SAxel Dörfler{
10328fa0645SStefano Ceccherini	char string[64];
10428fa0645SStefano Ceccherini	switch (orientation) {
10528fa0645SStefano Ceccherini		case B_BUFFER_TOP_TO_BOTTOM:
10628fa0645SStefano Ceccherini			strcpy(string, "B_BUFFER_TOP_TO_BOTTOM");
10728fa0645SStefano Ceccherini			break;
10828fa0645SStefano Ceccherini		case B_BUFFER_BOTTOM_TO_TOP:
10928fa0645SStefano Ceccherini			strcpy(string, "B_BUFFER_BOTTOM_TO_TOP");
11028fa0645SStefano Ceccherini			break;
11128fa0645SStefano Ceccherini		default:
11228fa0645SStefano Ceccherini			strcpy(string, "unknown");
11328fa0645SStefano Ceccherini			break;
11428fa0645SStefano Ceccherini	}
1152c704682SAxel Dörfler
1162c704682SAxel Dörfler	OUTPUT("orientation: %s\n", string);
11728fa0645SStefano Ceccherini}
11828fa0645SStefano Ceccherini
11928fa0645SStefano Ceccherini
1202c704682SAxel Dörfler#endif	// DEBUG > 2
1212c704682SAxel Dörfler
1222c704682SAxel Dörfler
1235115ca08SStefano Ceccherinistatic void
1245115ca08SStefano Ceccheriniprint_direct_buffer_info(const direct_buffer_info &info)
1255115ca08SStefano Ceccherini{
1265115ca08SStefano Ceccherini	print_direct_buffer_state(info.buffer_state);
1275115ca08SStefano Ceccherini	print_direct_driver_state(info.driver_state);
1282c704682SAxel Dörfler
1292c704682SAxel Dörfler#	if DEBUG > 1
1302c704682SAxel Dörfler	OUTPUT("bits: %p\n", info.bits);
1312c704682SAxel Dörfler	OUTPUT("pci_bits: %p\n", info.pci_bits);
1322c704682SAxel Dörfler	OUTPUT("bytes_per_row: %ld\n", info.bytes_per_row);
1332c704682SAxel Dörfler	OUTPUT("bits_per_pixel: %lu\n", info.bits_per_pixel);
1342c704682SAxel Dörfler	OUTPUT("pixel_format: %d\n", info.pixel_format);
13528fa0645SStefano Ceccherini	print_direct_buffer_layout(info.layout);
13628fa0645SStefano Ceccherini	print_direct_buffer_orientation(info.orientation);
13728fa0645SStefano Ceccherini
1382c704682SAxel Dörfler#		if DEBUG > 2
1392c704682SAxel Dörfler	// TODO: this won't work correctly with debug_printf()
14028fa0645SStefano Ceccherini	printf("CLIPPING INFO:\n");
14128fa0645SStefano Ceccherini	printf("clipping_rects count: %ld\n", info.clip_list_count);
1422c704682SAxel Dörfler
14328fa0645SStefano Ceccherini	printf("- window_bounds:\n");
14428fa0645SStefano Ceccherini	BRegion region;
14528fa0645SStefano Ceccherini	region.Set(info.window_bounds);
14628fa0645SStefano Ceccherini	region.PrintToStream();
1472c704682SAxel Dörfler
14828fa0645SStefano Ceccherini	region.MakeEmpty();
14928fa0645SStefano Ceccherini	for (uint32 i = 0; i < info.clip_list_count; i++)
15028fa0645SStefano Ceccherini		region.Include(info.clip_list[i]);
1512c704682SAxel Dörfler
15228fa0645SStefano Ceccherini	printf("- clip_list:\n");
15328fa0645SStefano Ceccherini	region.PrintToStream();
1542c704682SAxel Dörfler#		endif
1552c704682SAxel Dörfler#	endif
15628fa0645SStefano Ceccherini
1572c704682SAxel Dörfler	OUTPUT("\n");
1585115ca08SStefano Ceccherini}
1595115ca08SStefano Ceccherini
1602c704682SAxel Dörfler
1612c704682SAxel Dörfler#endif	// DEBUG
1622c704682SAxel Dörfler
1632c704682SAxel Dörfler
1642c704682SAxel Dörfler//	#pragma mark -
1655115ca08SStefano Ceccherini
16628fa0645SStefano Ceccherini
16737fedaf8SJohn ScipioneBDirectWindow::BDirectWindow(BRect frame, const char* title, window_type type,
1682c704682SAxel Dörfler		uint32 flags, uint32 workspace)
1692c704682SAxel Dörfler	:
1702c704682SAxel Dörfler	BWindow(frame, title, type, flags, workspace)
171cafaa5aaSStefano Ceccherini{
172d9cebac2SStefano Ceccherini	_InitData();
173cafaa5aaSStefano Ceccherini}
174cafaa5aaSStefano Ceccherini
175cafaa5aaSStefano Ceccherini
17637fedaf8SJohn ScipioneBDirectWindow::BDirectWindow(BRect frame, const char* title, window_look look,
1772c704682SAxel Dörfler		window_feel feel, uint32 flags, uint32 workspace)
1782c704682SAxel Dörfler	:
1792c704682SAxel Dörfler	BWindow(frame, title, look, feel, flags, workspace)
180cafaa5aaSStefano Ceccherini{
181d9cebac2SStefano Ceccherini	_InitData();
182cafaa5aaSStefano Ceccherini}
183cafaa5aaSStefano Ceccherini
184cafaa5aaSStefano Ceccherini
185cafaa5aaSStefano CeccheriniBDirectWindow::~BDirectWindow()
186cafaa5aaSStefano Ceccherini{
187d9cebac2SStefano Ceccherini	_DisposeData();
188cafaa5aaSStefano Ceccherini}
189cafaa5aaSStefano Ceccherini
190cafaa5aaSStefano Ceccherini
1912c704682SAxel Dörfler//	#pragma mark - BWindow API implementation
1922c704682SAxel Dörfler
1932c704682SAxel Dörfler
19437fedaf8SJohn ScipioneBArchivable*
19537fedaf8SJohn ScipioneBDirectWindow::Instantiate(BMessage* data)
196cafaa5aaSStefano Ceccherini{
197cafaa5aaSStefano Ceccherini	return NULL;
198cafaa5aaSStefano Ceccherini}
199cafaa5aaSStefano Ceccherini
200cafaa5aaSStefano Ceccherini
201cafaa5aaSStefano Ceccherinistatus_t
20237fedaf8SJohn ScipioneBDirectWindow::Archive(BMessage* data, bool deep) const
203cafaa5aaSStefano Ceccherini{
204cafaa5aaSStefano Ceccherini	return inherited::Archive(data, deep);
205cafaa5aaSStefano Ceccherini}
206cafaa5aaSStefano Ceccherini
207cafaa5aaSStefano Ceccherini
208cafaa5aaSStefano Ceccherinivoid
209cafaa5aaSStefano CeccheriniBDirectWindow::Quit()
210cafaa5aaSStefano Ceccherini{
211cafaa5aaSStefano Ceccherini	inherited::Quit();
212cafaa5aaSStefano Ceccherini}
213cafaa5aaSStefano Ceccherini
214cafaa5aaSStefano Ceccherini
215cafaa5aaSStefano Ceccherinivoid
21637fedaf8SJohn ScipioneBDirectWindow::DispatchMessage(BMessage* message, BHandler* handler)
217cafaa5aaSStefano Ceccherini{
218cafaa5aaSStefano Ceccherini	inherited::DispatchMessage(message, handler);
219cafaa5aaSStefano Ceccherini}
220cafaa5aaSStefano Ceccherini
221cafaa5aaSStefano Ceccherini
222cafaa5aaSStefano Ceccherinivoid
22337fedaf8SJohn ScipioneBDirectWindow::MessageReceived(BMessage* message)
224cafaa5aaSStefano Ceccherini{
225cafaa5aaSStefano Ceccherini	inherited::MessageReceived(message);
226cafaa5aaSStefano Ceccherini}
227cafaa5aaSStefano Ceccherini
228cafaa5aaSStefano Ceccherini
229cafaa5aaSStefano Ceccherinivoid
230d9cebac2SStefano CeccheriniBDirectWindow::FrameMoved(BPoint newPosition)
231cafaa5aaSStefano Ceccherini{
232d9cebac2SStefano Ceccherini	inherited::FrameMoved(newPosition);
233cafaa5aaSStefano Ceccherini}
234cafaa5aaSStefano Ceccherini
235cafaa5aaSStefano Ceccherini
236cafaa5aaSStefano Ceccherinivoid
237d9cebac2SStefano CeccheriniBDirectWindow::WorkspacesChanged(uint32 oldWorkspaces, uint32 newWorkspaces)
238cafaa5aaSStefano Ceccherini{
239d9cebac2SStefano Ceccherini	inherited::WorkspacesChanged(oldWorkspaces, newWorkspaces);
240cafaa5aaSStefano Ceccherini}
241cafaa5aaSStefano Ceccherini
242cafaa5aaSStefano Ceccherini
243cafaa5aaSStefano Ceccherinivoid
244d9cebac2SStefano CeccheriniBDirectWindow::WorkspaceActivated(int32 index, bool state)
245cafaa5aaSStefano Ceccherini{
246d9cebac2SStefano Ceccherini	inherited::WorkspaceActivated(index, state);
247cafaa5aaSStefano Ceccherini}
248cafaa5aaSStefano Ceccherini
249cafaa5aaSStefano Ceccherini
250cafaa5aaSStefano Ceccherinivoid
251d9cebac2SStefano CeccheriniBDirectWindow::FrameResized(float newWidth, float newHeight)
252cafaa5aaSStefano Ceccherini{
253d9cebac2SStefano Ceccherini	inherited::FrameResized(newWidth, newHeight);
254cafaa5aaSStefano Ceccherini}
255cafaa5aaSStefano Ceccherini
256cafaa5aaSStefano Ceccherini
257cafaa5aaSStefano Ceccherinivoid
258cafaa5aaSStefano CeccheriniBDirectWindow::Minimize(bool minimize)
259cafaa5aaSStefano Ceccherini{
260cafaa5aaSStefano Ceccherini	inherited::Minimize(minimize);
261cafaa5aaSStefano Ceccherini}
262cafaa5aaSStefano Ceccherini
263cafaa5aaSStefano Ceccherini
264cafaa5aaSStefano Ceccherinivoid
265d9cebac2SStefano CeccheriniBDirectWindow::Zoom(BPoint recPosition, float recWidth, float recHeight)
266cafaa5aaSStefano Ceccherini{
267d9cebac2SStefano Ceccherini	inherited::Zoom(recPosition, recWidth, recHeight);
268cafaa5aaSStefano Ceccherini}
269cafaa5aaSStefano Ceccherini
270cafaa5aaSStefano Ceccherini
271cafaa5aaSStefano Ceccherinivoid
272d9cebac2SStefano CeccheriniBDirectWindow::ScreenChanged(BRect screenFrame, color_space depth)
273cafaa5aaSStefano Ceccherini{
274d9cebac2SStefano Ceccherini	inherited::ScreenChanged(screenFrame, depth);
275cafaa5aaSStefano Ceccherini}
276cafaa5aaSStefano Ceccherini
277cafaa5aaSStefano Ceccherini
278cafaa5aaSStefano Ceccherinivoid
279cafaa5aaSStefano CeccheriniBDirectWindow::MenusBeginning()
280cafaa5aaSStefano Ceccherini{
281cafaa5aaSStefano Ceccherini	inherited::MenusBeginning();
282cafaa5aaSStefano Ceccherini}
283cafaa5aaSStefano Ceccherini
284cafaa5aaSStefano Ceccherini
285cafaa5aaSStefano Ceccherinivoid
286cafaa5aaSStefano CeccheriniBDirectWindow::MenusEnded()
287cafaa5aaSStefano Ceccherini{
288cafaa5aaSStefano Ceccherini	inherited::MenusEnded();
289cafaa5aaSStefano Ceccherini}
290cafaa5aaSStefano Ceccherini
291cafaa5aaSStefano Ceccherini
292cafaa5aaSStefano Ceccherinivoid
293cafaa5aaSStefano CeccheriniBDirectWindow::WindowActivated(bool state)
294cafaa5aaSStefano Ceccherini{
2952c704682SAxel Dörfler	inherited::WindowActivated(state);
296cafaa5aaSStefano Ceccherini}
297cafaa5aaSStefano Ceccherini
298cafaa5aaSStefano Ceccherini
299cafaa5aaSStefano Ceccherinivoid
300cafaa5aaSStefano CeccheriniBDirectWindow::Show()
301cafaa5aaSStefano Ceccherini{
302cafaa5aaSStefano Ceccherini	inherited::Show();
303cafaa5aaSStefano Ceccherini}
304cafaa5aaSStefano Ceccherini
305cafaa5aaSStefano Ceccherini
306cafaa5aaSStefano Ceccherinivoid
307cafaa5aaSStefano CeccheriniBDirectWindow::Hide()
308cafaa5aaSStefano Ceccherini{
309cafaa5aaSStefano Ceccherini	inherited::Hide();
310cafaa5aaSStefano Ceccherini}
311cafaa5aaSStefano Ceccherini
312cafaa5aaSStefano Ceccherini
31337fedaf8SJohn ScipioneBHandler*
31437fedaf8SJohn ScipioneBDirectWindow::ResolveSpecifier(BMessage* message, int32 index,
31537fedaf8SJohn Scipione	BMessage* specifier, int32 what, const char* property)
316cafaa5aaSStefano Ceccherini{
31737fedaf8SJohn Scipione	return inherited::ResolveSpecifier(message, index, specifier, what,
31837fedaf8SJohn Scipione		property);
319cafaa5aaSStefano Ceccherini}
320cafaa5aaSStefano Ceccherini
321cafaa5aaSStefano Ceccherini
322cafaa5aaSStefano Ceccherinistatus_t
32337fedaf8SJohn ScipioneBDirectWindow::GetSupportedSuites(BMessage* data)
324cafaa5aaSStefano Ceccherini{
325cafaa5aaSStefano Ceccherini	return inherited::GetSupportedSuites(data);
326cafaa5aaSStefano Ceccherini}
327cafaa5aaSStefano Ceccherini
328cafaa5aaSStefano Ceccherini
329cafaa5aaSStefano Ceccherinistatus_t
33037fedaf8SJohn ScipioneBDirectWindow::Perform(perform_code d, void* arg)
331cafaa5aaSStefano Ceccherini{
332cafaa5aaSStefano Ceccherini	return inherited::Perform(d, arg);
333cafaa5aaSStefano Ceccherini}
334cafaa5aaSStefano Ceccherini
335cafaa5aaSStefano Ceccherini
336cafaa5aaSStefano Ceccherinivoid
337cafaa5aaSStefano CeccheriniBDirectWindow::task_looper()
338cafaa5aaSStefano Ceccherini{
339cafaa5aaSStefano Ceccherini	inherited::task_looper();
340cafaa5aaSStefano Ceccherini}
341cafaa5aaSStefano Ceccherini
342cafaa5aaSStefano Ceccherini
34337fedaf8SJohn ScipioneBMessage*
34437fedaf8SJohn ScipioneBDirectWindow::ConvertToMessage(void* raw, int32 code)
345cafaa5aaSStefano Ceccherini{
346cafaa5aaSStefano Ceccherini	return inherited::ConvertToMessage(raw, code);
347cafaa5aaSStefano Ceccherini}
348cafaa5aaSStefano Ceccherini
349cafaa5aaSStefano Ceccherini
350764ac9e5SAxel Dörfler//	#pragma mark - BDirectWindow specific API
351764ac9e5SAxel Dörfler
352764ac9e5SAxel Dörfler
353cafaa5aaSStefano Ceccherinivoid
35437fedaf8SJohn ScipioneBDirectWindow::DirectConnected(direct_buffer_info* info)
355cafaa5aaSStefano Ceccherini{
356764ac9e5SAxel Dörfler	// implemented in subclasses
357cafaa5aaSStefano Ceccherini}
358cafaa5aaSStefano Ceccherini
359cafaa5aaSStefano Ceccherini
360cafaa5aaSStefano Ceccherinistatus_t
36137fedaf8SJohn ScipioneBDirectWindow::GetClippingRegion(BRegion* region, BPoint* origin) const
362cafaa5aaSStefano Ceccherini{
363cafaa5aaSStefano Ceccherini	if (region == NULL)
364cafaa5aaSStefano Ceccherini		return B_BAD_VALUE;
365cafaa5aaSStefano Ceccherini
366d9cebac2SStefano Ceccherini	if (IsLocked() || !_LockDirect())
3675fdea13fSStefano Ceccherini		return B_ERROR;
3682c704682SAxel Dörfler
36949d7857eSJulian Harnath	if (!fInDirectConnect) {
370d9cebac2SStefano Ceccherini		_UnlockDirect();
3715fdea13fSStefano Ceccherini		return B_ERROR;
3725fdea13fSStefano Ceccherini	}
3732c704682SAxel Dörfler
3745fdea13fSStefano Ceccherini	// BPoint's coordinates are floats. We can only work
3752b73985eSStefano Ceccherini	// with integers._DaemonStarter
3765fdea13fSStefano Ceccherini	int32 originX, originY;
3775fdea13fSStefano Ceccherini	if (origin == NULL) {
3785fdea13fSStefano Ceccherini		originX = 0;
3795fdea13fSStefano Ceccherini		originY = 0;
3805fdea13fSStefano Ceccherini	} else {
3815fdea13fSStefano Ceccherini		originX = (int32)origin->x;
3825fdea13fSStefano Ceccherini		originY = (int32)origin->y;
3835fdea13fSStefano Ceccherini	}
384366fdcdfSMarcus Overhagen
385764ac9e5SAxel Dörfler#ifndef HAIKU_TARGET_PLATFORM_DANO
3865fdea13fSStefano Ceccherini	// Since we are friend of BRegion, we can access its private members.
3875fdea13fSStefano Ceccherini	// Otherwise, we would need to call BRegion::Include(clipping_rect)
3885fdea13fSStefano Ceccherini	// for every clipping_rect in our clip_list, and that would be much
3895fdea13fSStefano Ceccherini	// more overkill than this (tested ).
390582da173SStephan Aßmus	if (!region->_SetSize(fBufferDesc->clip_list_count)) {
391d9cebac2SStefano Ceccherini		_UnlockDirect();
392582da173SStephan Aßmus		return B_NO_MEMORY;
393582da173SStephan Aßmus	}
394ed225430SStephan Aßmus	region->fCount = fBufferDesc->clip_list_count;
395ed225430SStephan Aßmus	region->fBounds = region->_ConvertToInternal(fBufferDesc->clip_bounds);
396ed225430SStephan Aßmus	for (uint32 c = 0; c < fBufferDesc->clip_list_count; c++) {
397ed225430SStephan Aßmus		region->fData[c] = region->_ConvertToInternal(
398ed225430SStephan Aßmus			fBufferDesc->clip_list[c]);
399ed225430SStephan Aßmus	}
4004f6f70e0SStefano Ceccherini
4012c704682SAxel Dörfler	// adjust bounds by the given origin point
4022c704682SAxel Dörfler	region->OffsetBy(-originX, -originY);
403366fdcdfSMarcus Overhagen#endif
404366fdcdfSMarcus Overhagen
405d9cebac2SStefano Ceccherini	_UnlockDirect();
4065fdea13fSStefano Ceccherini
4075fdea13fSStefano Ceccherini	return B_OK;
408cafaa5aaSStefano Ceccherini
409cafaa5aaSStefano Ceccherini}
410cafaa5aaSStefano Ceccherini
411cafaa5aaSStefano Ceccherini
412cafaa5aaSStefano Ceccherinistatus_t
413cafaa5aaSStefano CeccheriniBDirectWindow::SetFullScreen(bool enable)
414cafaa5aaSStefano Ceccherini{
4152b73985eSStefano Ceccherini	if (fIsFullScreen == enable)
4162b73985eSStefano Ceccherini		return B_OK;
4172b73985eSStefano Ceccherini
418cafaa5aaSStefano Ceccherini	status_t status = B_ERROR;
41909ea3092SStefano Ceccherini	if (Lock()) {
420ab6a6bedSAxel Dörfler		fLink->StartMessage(AS_DIRECT_WINDOW_SET_FULLSCREEN);
421feee8cf2SStefano Ceccherini		fLink->Attach<bool>(enable);
422764ac9e5SAxel Dörfler
423ab6a6bedSAxel Dörfler		if (fLink->FlushWithReply(status) == B_OK
4249ecf9d1cSIngo Weinhold			&& status == B_OK) {
4252b73985eSStefano Ceccherini			fIsFullScreen = enable;
4269ecf9d1cSIngo Weinhold		}
427feee8cf2SStefano Ceccherini		Unlock();
42809ea3092SStefano Ceccherini	}
429cafaa5aaSStefano Ceccherini	return status;
430cafaa5aaSStefano Ceccherini}
431cafaa5aaSStefano Ceccherini
432cafaa5aaSStefano Ceccherini
433cafaa5aaSStefano Ceccherinibool
434cafaa5aaSStefano CeccheriniBDirectWindow::IsFullScreen() const
435cafaa5aaSStefano Ceccherini{
4362b73985eSStefano Ceccherini	return fIsFullScreen;
437cafaa5aaSStefano Ceccherini}
438cafaa5aaSStefano Ceccherini
439cafaa5aaSStefano Ceccherini
4402c704682SAxel Dörfler/*static*/ bool
441cafaa5aaSStefano CeccheriniBDirectWindow::SupportsWindowMode(screen_id id)
442cafaa5aaSStefano Ceccherini{
4432c704682SAxel Dörfler	display_mode mode;
4444fbc3f58SStefano Ceccherini	status_t status = BScreen(id).GetMode(&mode);
4454fbc3f58SStefano Ceccherini	if (status == B_OK)
4462c704682SAxel Dörfler		return (mode.flags & B_PARALLEL_ACCESS) != 0;
4472c704682SAxel Dörfler
448fb984c13SStefano Ceccherini	return false;
449cafaa5aaSStefano Ceccherini}
450cafaa5aaSStefano Ceccherini
451cafaa5aaSStefano Ceccherini
4520f4fb801SAxel Dörfler//	#pragma mark - Private methods
4530f4fb801SAxel Dörfler
4542c704682SAxel Dörfler
4552c704682SAxel Dörfler/*static*/ int32
45637fedaf8SJohn ScipioneBDirectWindow::_daemon_thread(void* arg)
457cafaa5aaSStefano Ceccherini{
45837fedaf8SJohn Scipione	return static_cast<BDirectWindow*>(arg)->_DirectDaemon();
4592b73985eSStefano Ceccherini}
460cafaa5aaSStefano Ceccherini
4612b73985eSStefano Ceccherini
4622b73985eSStefano Ceccheriniint32
463d9cebac2SStefano CeccheriniBDirectWindow::_DirectDaemon()
4642b73985eSStefano Ceccherini{
4652b73985eSStefano Ceccherini	while (!fDaemonKiller) {
466cafaa5aaSStefano Ceccherini		// This sem is released by the app_server when our
467cafaa5aaSStefano Ceccherini		// clipping region changes, or when our window is moved,
4680f4fb801SAxel Dörfler		// resized, etc. etc.
4690f4fb801SAxel Dörfler		status_t status;
4700f4fb801SAxel Dörfler		do {
4712b73985eSStefano Ceccherini			status = acquire_sem(fDisableSem);
4720f4fb801SAxel Dörfler		} while (status == B_INTERRUPTED);
4730f4fb801SAxel Dörfler
4742c704682SAxel Dörfler		if (status != B_OK) {
475c9ad965cSStefano Ceccherini			//fprintf(stderr, "DirectDaemon: failed to acquire direct sem: %s\n",
476c9ad965cSStefano Ceccherini				// strerror(status));
4770f4fb801SAxel Dörfler			return -1;
47897cccf16SStefano Ceccherini		}
4790f4fb801SAxel Dörfler
4805115ca08SStefano Ceccherini#if DEBUG
4815115ca08SStefano Ceccherini		print_direct_buffer_info(*fBufferDesc);
4825115ca08SStefano Ceccherini#endif
4835115ca08SStefano Ceccherini
484d9cebac2SStefano Ceccherini		if (_LockDirect()) {
4852c704682SAxel Dörfler			if ((fBufferDesc->buffer_state & B_DIRECT_MODE_MASK)
4862c704682SAxel Dörfler					== B_DIRECT_START)
4872b73985eSStefano Ceccherini				fConnectionEnable = true;
4880f4fb801SAxel Dörfler
4892c704682SAxel Dörfler			fInDirectConnect = true;
4902c704682SAxel Dörfler			DirectConnected(fBufferDesc);
4912b73985eSStefano Ceccherini			fInDirectConnect = false;
4920f4fb801SAxel Dörfler
4932c704682SAxel Dörfler			if ((fBufferDesc->buffer_state & B_DIRECT_MODE_MASK)
4942c704682SAxel Dörfler					== B_DIRECT_STOP)
4952b73985eSStefano Ceccherini				fConnectionEnable = false;
4960f4fb801SAxel Dörfler
497d9cebac2SStefano Ceccherini			_UnlockDirect();
498cafaa5aaSStefano Ceccherini		}
4990f4fb801SAxel Dörfler
500cafaa5aaSStefano Ceccherini		// The app_server then waits (with a timeout) on this sem.
501cafaa5aaSStefano Ceccherini		// If we aren't quick enough to release this sem, our app
502cafaa5aaSStefano Ceccherini		// will be terminated by the app_server
50397cccf16SStefano Ceccherini		if ((status = release_sem(fDisableSemAck)) != B_OK) {
504c9ad965cSStefano Ceccherini			//fprintf(stderr, "DirectDaemon: failed to release sem: %s\n",
505c9ad965cSStefano Ceccherini				//strerror(status));
5060f4fb801SAxel Dörfler			return -1;
50797cccf16SStefano Ceccherini		}
508cafaa5aaSStefano Ceccherini	}
509cafaa5aaSStefano Ceccherini
510cafaa5aaSStefano Ceccherini	return 0;
511cafaa5aaSStefano Ceccherini}
512cafaa5aaSStefano Ceccherini
513cafaa5aaSStefano Ceccherini
514cafaa5aaSStefano Ceccherinibool
515d9cebac2SStefano CeccheriniBDirectWindow::_LockDirect() const
516cafaa5aaSStefano Ceccherini{
5172c704682SAxel Dörfler	// LockDirect() and UnlockDirect() are no-op on BeOS. I tried to call BeOS's
5182c704682SAxel Dörfler	// version repeatedly, from the same thread and from different threads,
5192c704682SAxel Dörfler	// nothing happened.
5202c704682SAxel Dörfler	// They're not needed though, as the direct_daemon_thread doesn't change
5212c704682SAxel Dörfler	// any shared data. They are probably here for future enhancements.
522cafaa5aaSStefano Ceccherini	status_t status = B_OK;
523cafaa5aaSStefano Ceccherini
524cafaa5aaSStefano Ceccherini#if DW_NEEDS_LOCKING
52537fedaf8SJohn Scipione	BDirectWindow* casted = const_cast<BDirectWindow*>(this);
5262c704682SAxel Dörfler
5272b73985eSStefano Ceccherini	if (atomic_add(&casted->fDirectLock, 1) > 0) {
528cafaa5aaSStefano Ceccherini		do {
529d9cebac2SStefano Ceccherini			status = acquire_sem(casted->fDirectSem);
530cafaa5aaSStefano Ceccherini		} while (status == B_INTERRUPTED);
5315fdea13fSStefano Ceccherini	}
5322c704682SAxel Dörfler
533cafaa5aaSStefano Ceccherini	if (status == B_OK) {
5342b73985eSStefano Ceccherini		casted->fDirectLockOwner = find_thread(NULL);
5352b73985eSStefano Ceccherini		casted->fDirectLockCount++;
536cafaa5aaSStefano Ceccherini	}
537cafaa5aaSStefano Ceccherini#endif
538cafaa5aaSStefano Ceccherini
539cafaa5aaSStefano Ceccherini	return status == B_OK;
540cafaa5aaSStefano Ceccherini}
541cafaa5aaSStefano Ceccherini
542cafaa5aaSStefano Ceccherini
543cafaa5aaSStefano Ceccherinivoid
544d9cebac2SStefano CeccheriniBDirectWindow::_UnlockDirect() const
545cafaa5aaSStefano Ceccherini{
546cafaa5aaSStefano Ceccherini#if DW_NEEDS_LOCKING
54737fedaf8SJohn Scipione	BDirectWindow* casted = const_cast<BDirectWindow*>(this);
5482c704682SAxel Dörfler
5492b73985eSStefano Ceccherini	if (atomic_add(&casted->fDirectLock, -1) > 1)
5502b73985eSStefano Ceccherini		release_sem(casted->fDirectSem);
5512c704682SAxel Dörfler
5522b73985eSStefano Ceccherini	casted->fDirectLockCount--;
553cafaa5aaSStefano Ceccherini#endif
554cafaa5aaSStefano Ceccherini}
555cafaa5aaSStefano Ceccherini
556cafaa5aaSStefano Ceccherini
557cafaa5aaSStefano Ceccherinivoid
558d9cebac2SStefano CeccheriniBDirectWindow::_InitData()
559cafaa5aaSStefano Ceccherini{
5602b73985eSStefano Ceccherini	fConnectionEnable = false;
5612b73985eSStefano Ceccherini	fIsFullScreen = false;
5622b73985eSStefano Ceccherini	fInDirectConnect = false;
5632c704682SAxel Dörfler
5642b73985eSStefano Ceccherini	fInitStatus = 0;
5652c704682SAxel Dörfler
5662b6ac345SStefano Ceccherini	status_t status = B_ERROR;
5672b73985eSStefano Ceccherini	struct direct_window_sync_data syncData;
5682c704682SAxel Dörfler
5699fe35223SAxel Dörfler	fLink->StartMessage(AS_DIRECT_WINDOW_GET_SYNC_DATA);
5709fe35223SAxel Dörfler	if (fLink->FlushWithReply(status) == B_OK && status == B_OK)
5719fe35223SAxel Dörfler		fLink->Read<direct_window_sync_data>(&syncData);
5729fe35223SAxel Dörfler
5739fe35223SAxel Dörfler	if (status != B_OK)
5745fdea13fSStefano Ceccherini		return;
57571b55088SAxel Dörfler
5762c704682SAxel Dörfler#if DW_NEEDS_LOCKING
5772b73985eSStefano Ceccherini	fDirectLock = 0;
5782b73985eSStefano Ceccherini	fDirectLockCount = 0;
5792b73985eSStefano Ceccherini	fDirectLockOwner = -1;
5802b73985eSStefano Ceccherini	fDirectLockStack = NULL;
58128fa0645SStefano Ceccherini	fDirectSem = create_sem(0, "direct sem");
5822b73985eSStefano Ceccherini	if (fDirectSem > 0)
5832b73985eSStefano Ceccherini		fInitStatus |= DW_STATUS_SEM_CREATED;
5842c704682SAxel Dörfler#endif
58571b55088SAxel Dörfler
5862b73985eSStefano Ceccherini	fSourceClippingArea = syncData.area;
5872b73985eSStefano Ceccherini	fDisableSem = syncData.disable_sem;
5882b73985eSStefano Ceccherini	fDisableSemAck = syncData.disable_sem_ack;
58971b55088SAxel Dörfler
59028fa0645SStefano Ceccherini	fClonedClippingArea = clone_area("cloned direct area", (void**)&fBufferDesc,
5912c704682SAxel Dörfler		B_ANY_ADDRESS, B_READ_AREA, fSourceClippingArea);
59271b55088SAxel Dörfler
5932c704682SAxel Dörfler	if (fClonedClippingArea > 0) {
5942b73985eSStefano Ceccherini		fInitStatus |= DW_STATUS_AREA_CLONED;
59571b55088SAxel Dörfler
596d9cebac2SStefano Ceccherini		fDirectDaemonId = spawn_thread(_daemon_thread, "direct daemon",
5972c704682SAxel Dörfler			B_DISPLAY_PRIORITY, this);
59871b55088SAxel Dörfler
5992b73985eSStefano Ceccherini		if (fDirectDaemonId > 0) {
6002b73985eSStefano Ceccherini			fDaemonKiller = false;
6012b73985eSStefano Ceccherini			if (resume_thread(fDirectDaemonId) == B_OK)
6022b73985eSStefano Ceccherini				fInitStatus |= DW_STATUS_THREAD_STARTED;
6035fdea13fSStefano Ceccherini			else
6042b73985eSStefano Ceccherini				kill_thread(fDirectDaemonId);
605cafaa5aaSStefano Ceccherini		}
606cafaa5aaSStefano Ceccherini	}
607cafaa5aaSStefano Ceccherini}
608cafaa5aaSStefano Ceccherini
609cafaa5aaSStefano Ceccherini
610cafaa5aaSStefano Ceccherinivoid
611d9cebac2SStefano CeccheriniBDirectWindow::_DisposeData()
612cafaa5aaSStefano Ceccherini{
613cafaa5aaSStefano Ceccherini	// wait until the connection terminates: we can't destroy
614cafaa5aaSStefano Ceccherini	// the object until the client receives the B_DIRECT_STOP
615cafaa5aaSStefano Ceccherini	// notification, or bad things will happen
6162b73985eSStefano Ceccherini	while (fConnectionEnable)
617cafaa5aaSStefano Ceccherini		snooze(50000);
6182c704682SAxel Dörfler
619d9cebac2SStefano Ceccherini	_LockDirect();
6202c704682SAxel Dörfler
6212b73985eSStefano Ceccherini	if (fInitStatus & DW_STATUS_THREAD_STARTED) {
6222b73985eSStefano Ceccherini		fDaemonKiller = true;
623020cbad9SStefano Ceccherini		// delete this sem, otherwise the Direct daemon thread
624cafaa5aaSStefano Ceccherini		// will wait forever on it
625020cbad9SStefano Ceccherini		delete_sem(fDisableSem);
626cafaa5aaSStefano Ceccherini		status_t retVal;
6272b73985eSStefano Ceccherini		wait_for_thread(fDirectDaemonId, &retVal);
628cafaa5aaSStefano Ceccherini	}
6292c704682SAxel Dörfler
630cafaa5aaSStefano Ceccherini#if DW_NEEDS_LOCKING
6312b73985eSStefano Ceccherini	if (fInitStatus & DW_STATUS_SEM_CREATED)
6322b73985eSStefano Ceccherini		delete_sem(fDirectSem);
6332c704682SAxel Dörfler#endif
634cafaa5aaSStefano Ceccherini
6352b73985eSStefano Ceccherini	if (fInitStatus & DW_STATUS_AREA_CLONED)
6362b73985eSStefano Ceccherini		delete_area(fClonedClippingArea);
637cafaa5aaSStefano Ceccherini}
638cafaa5aaSStefano Ceccherini
639cafaa5aaSStefano Ceccherini
640cafaa5aaSStefano Ceccherinivoid BDirectWindow::_ReservedDirectWindow1() {}
641cafaa5aaSStefano Ceccherinivoid BDirectWindow::_ReservedDirectWindow2() {}
642cafaa5aaSStefano Ceccherinivoid BDirectWindow::_ReservedDirectWindow3() {}
643cafaa5aaSStefano Ceccherinivoid BDirectWindow::_ReservedDirectWindow4() {}
644