168667bf4SMichael Lotz/*
268667bf4SMichael Lotz * Copyright 2009, Haiku, Inc.
368667bf4SMichael Lotz * Distributed under the terms of the MIT License.
468667bf4SMichael Lotz *
568667bf4SMichael Lotz * Authors:
668667bf4SMichael Lotz *		Michael Lotz <mmlr@mlotz.ch>
768667bf4SMichael Lotz */
868667bf4SMichael Lotz
968667bf4SMichael Lotz#include "RemoteHWInterface.h"
1068667bf4SMichael Lotz#include "RemoteDrawingEngine.h"
1168667bf4SMichael Lotz#include "RemoteEventStream.h"
1268667bf4SMichael Lotz#include "RemoteMessage.h"
1368667bf4SMichael Lotz
1468667bf4SMichael Lotz#include "NetReceiver.h"
1568667bf4SMichael Lotz#include "NetSender.h"
1668667bf4SMichael Lotz#include "StreamingRingBuffer.h"
1768667bf4SMichael Lotz
1877846915SMichael Lotz#include "SystemPalette.h"
1977846915SMichael Lotz
2068667bf4SMichael Lotz#include <Autolock.h>
2168667bf4SMichael Lotz#include <NetEndpoint.h>
2268667bf4SMichael Lotz
2368667bf4SMichael Lotz#include <new>
2468667bf4SMichael Lotz#include <string.h>
2568667bf4SMichael Lotz
2668667bf4SMichael Lotz
27ebf043b9SMichael Lotz#define TRACE(x...)				/*debug_printf("RemoteHWInterface: " x)*/
28ebf043b9SMichael Lotz#define TRACE_ALWAYS(x...)		debug_printf("RemoteHWInterface: " x)
29ad9b83adSMurai Takashi#define TRACE_ERROR(x...)		debug_printf("RemoteHWInterface: " x)
3068667bf4SMichael Lotz
3168667bf4SMichael Lotz
3268667bf4SMichael Lotzstruct callback_info {
3368667bf4SMichael Lotz	uint32				token;
3428b813dfSFrançois Revol	RemoteHWInterface::CallbackFunction	callback;
3568667bf4SMichael Lotz	void*				cookie;
3668667bf4SMichael Lotz};
3768667bf4SMichael Lotz
3868667bf4SMichael Lotz
3968667bf4SMichael LotzRemoteHWInterface::RemoteHWInterface(const char* target)
4068667bf4SMichael Lotz	:
4168667bf4SMichael Lotz	HWInterface(),
4268667bf4SMichael Lotz	fTarget(target),
4368667bf4SMichael Lotz	fIsConnected(false),
4468667bf4SMichael Lotz	fProtocolVersion(100),
4568667bf4SMichael Lotz	fConnectionSpeed(0),
4668667bf4SMichael Lotz	fListenPort(10901),
475ed41cffSMichael Lotz	fListenEndpoint(NULL),
4868667bf4SMichael Lotz	fSendBuffer(NULL),
4968667bf4SMichael Lotz	fReceiveBuffer(NULL),
5068667bf4SMichael Lotz	fSender(NULL),
5168667bf4SMichael Lotz	fReceiver(NULL),
5268667bf4SMichael Lotz	fEventThread(-1),
5368667bf4SMichael Lotz	fEventStream(NULL),
5468667bf4SMichael Lotz	fCallbackLocker("callback locker")
5568667bf4SMichael Lotz{
56f609f4faSMichael Lotz	memset(&fFallbackMode, 0, sizeof(fFallbackMode));
57f609f4faSMichael Lotz	fFallbackMode.virtual_width = 640;
58f609f4faSMichael Lotz	fFallbackMode.virtual_height = 480;
59f609f4faSMichael Lotz	fFallbackMode.space = B_RGB32;
60f609f4faSMichael Lotz	_FillDisplayModeTiming(fFallbackMode);
6168667bf4SMichael Lotz
62f609f4faSMichael Lotz	fCurrentMode = fClientMode = fFallbackMode;
6368667bf4SMichael Lotz
645ed41cffSMichael Lotz	if (sscanf(fTarget, "%" B_SCNu16, &fListenPort) != 1) {
655ed41cffSMichael Lotz		fInitStatus = B_BAD_VALUE;
6668667bf4SMichael Lotz		return;
6768667bf4SMichael Lotz	}
6868667bf4SMichael Lotz
695ed41cffSMichael Lotz	fListenEndpoint = new(std::nothrow) BNetEndpoint();
705ed41cffSMichael Lotz	if (fListenEndpoint == NULL) {
7168667bf4SMichael Lotz		fInitStatus = B_NO_MEMORY;
7268667bf4SMichael Lotz		return;
7368667bf4SMichael Lotz	}
7468667bf4SMichael Lotz
755ed41cffSMichael Lotz	fInitStatus = fListenEndpoint->Bind(fListenPort);
7668667bf4SMichael Lotz	if (fInitStatus != B_OK)
7768667bf4SMichael Lotz		return;
7868667bf4SMichael Lotz
7968667bf4SMichael Lotz	fSendBuffer = new(std::nothrow) StreamingRingBuffer(16 * 1024);
8068667bf4SMichael Lotz	if (fSendBuffer == NULL) {
8168667bf4SMichael Lotz		fInitStatus = B_NO_MEMORY;
8268667bf4SMichael Lotz		return;
8368667bf4SMichael Lotz	}
8468667bf4SMichael Lotz
8568667bf4SMichael Lotz	fInitStatus = fSendBuffer->InitCheck();
8668667bf4SMichael Lotz	if (fInitStatus != B_OK)
8768667bf4SMichael Lotz		return;
8868667bf4SMichael Lotz
8968667bf4SMichael Lotz	fReceiveBuffer = new(std::nothrow) StreamingRingBuffer(16 * 1024);
9068667bf4SMichael Lotz	if (fReceiveBuffer == NULL) {
9168667bf4SMichael Lotz		fInitStatus = B_NO_MEMORY;
9268667bf4SMichael Lotz		return;
9368667bf4SMichael Lotz	}
9468667bf4SMichael Lotz
9568667bf4SMichael Lotz	fInitStatus = fReceiveBuffer->InitCheck();
9668667bf4SMichael Lotz	if (fInitStatus != B_OK)
9768667bf4SMichael Lotz		return;
9868667bf4SMichael Lotz
995ed41cffSMichael Lotz	fReceiver = new(std::nothrow) NetReceiver(fListenEndpoint, fReceiveBuffer,
1005ed41cffSMichael Lotz		_NewConnectionCallback, this);
10168667bf4SMichael Lotz	if (fReceiver == NULL) {
10268667bf4SMichael Lotz		fInitStatus = B_NO_MEMORY;
10368667bf4SMichael Lotz		return;
10468667bf4SMichael Lotz	}
10568667bf4SMichael Lotz
10668667bf4SMichael Lotz	fEventStream = new(std::nothrow) RemoteEventStream();
10768667bf4SMichael Lotz	if (fEventStream == NULL) {
10868667bf4SMichael Lotz		fInitStatus = B_NO_MEMORY;
10968667bf4SMichael Lotz		return;
11068667bf4SMichael Lotz	}
11168667bf4SMichael Lotz
11268667bf4SMichael Lotz	fEventThread = spawn_thread(_EventThreadEntry, "remote event thread",
11368667bf4SMichael Lotz		B_NORMAL_PRIORITY, this);
11468667bf4SMichael Lotz	if (fEventThread < 0) {
11568667bf4SMichael Lotz		fInitStatus = fEventThread;
11668667bf4SMichael Lotz		return;
11768667bf4SMichael Lotz	}
11868667bf4SMichael Lotz
11968667bf4SMichael Lotz	resume_thread(fEventThread);
12068667bf4SMichael Lotz}
12168667bf4SMichael Lotz
12268667bf4SMichael Lotz
12368667bf4SMichael LotzRemoteHWInterface::~RemoteHWInterface()
12468667bf4SMichael Lotz{
12568667bf4SMichael Lotz	delete fReceiver;
12668667bf4SMichael Lotz	delete fReceiveBuffer;
12768667bf4SMichael Lotz
12868667bf4SMichael Lotz	delete fSendBuffer;
12968667bf4SMichael Lotz	delete fSender;
13068667bf4SMichael Lotz
1315ed41cffSMichael Lotz	delete fListenEndpoint;
13268667bf4SMichael Lotz
13368667bf4SMichael Lotz	delete fEventStream;
13468667bf4SMichael Lotz}
13568667bf4SMichael Lotz
13668667bf4SMichael Lotz
13768667bf4SMichael Lotzstatus_t
13868667bf4SMichael LotzRemoteHWInterface::Initialize()
13968667bf4SMichael Lotz{
14068667bf4SMichael Lotz	return fInitStatus;
14168667bf4SMichael Lotz}
14268667bf4SMichael Lotz
14368667bf4SMichael Lotz
14468667bf4SMichael Lotzstatus_t
14568667bf4SMichael LotzRemoteHWInterface::Shutdown()
14668667bf4SMichael Lotz{
14768667bf4SMichael Lotz	_Disconnect();
14868667bf4SMichael Lotz	return B_OK;
14968667bf4SMichael Lotz}
15068667bf4SMichael Lotz
15168667bf4SMichael Lotz
15268667bf4SMichael LotzDrawingEngine*
15368667bf4SMichael LotzRemoteHWInterface::CreateDrawingEngine()
15468667bf4SMichael Lotz{
15568667bf4SMichael Lotz	return new(std::nothrow) RemoteDrawingEngine(this);
15668667bf4SMichael Lotz}
15768667bf4SMichael Lotz
15868667bf4SMichael Lotz
15968667bf4SMichael LotzEventStream*
16068667bf4SMichael LotzRemoteHWInterface::CreateEventStream()
16168667bf4SMichael Lotz{
16268667bf4SMichael Lotz	return fEventStream;
16368667bf4SMichael Lotz}
16468667bf4SMichael Lotz
16568667bf4SMichael Lotz
16668667bf4SMichael Lotzstatus_t
16768667bf4SMichael LotzRemoteHWInterface::AddCallback(uint32 token, CallbackFunction callback,
16868667bf4SMichael Lotz	void* cookie)
16968667bf4SMichael Lotz{
17068667bf4SMichael Lotz	BAutolock lock(fCallbackLocker);
17168667bf4SMichael Lotz	int32 index = fCallbacks.BinarySearchIndexByKey(token, &_CallbackCompare);
17268667bf4SMichael Lotz	if (index >= 0)
17368667bf4SMichael Lotz		return B_NAME_IN_USE;
17468667bf4SMichael Lotz
17568667bf4SMichael Lotz	callback_info* info = new(std::nothrow) callback_info;
17668667bf4SMichael Lotz	if (info == NULL)
17768667bf4SMichael Lotz		return B_NO_MEMORY;
17868667bf4SMichael Lotz
17968667bf4SMichael Lotz	info->token = token;
18068667bf4SMichael Lotz	info->callback = callback;
18168667bf4SMichael Lotz	info->cookie = cookie;
18268667bf4SMichael Lotz
18368667bf4SMichael Lotz	fCallbacks.AddItem(info, -index - 1);
18468667bf4SMichael Lotz	return B_OK;
18568667bf4SMichael Lotz}
18668667bf4SMichael Lotz
18768667bf4SMichael Lotz
18868667bf4SMichael Lotzbool
18968667bf4SMichael LotzRemoteHWInterface::RemoveCallback(uint32 token)
19068667bf4SMichael Lotz{
19168667bf4SMichael Lotz	BAutolock lock(fCallbackLocker);
19268667bf4SMichael Lotz	int32 index = fCallbacks.BinarySearchIndexByKey(token, &_CallbackCompare);
19368667bf4SMichael Lotz	if (index < 0)
19468667bf4SMichael Lotz		return false;
19568667bf4SMichael Lotz
19668667bf4SMichael Lotz	delete fCallbacks.RemoveItemAt(index);
19768667bf4SMichael Lotz	return true;
19868667bf4SMichael Lotz}
19968667bf4SMichael Lotz
20068667bf4SMichael Lotz
20168667bf4SMichael Lotzcallback_info*
20268667bf4SMichael LotzRemoteHWInterface::_FindCallback(uint32 token)
20368667bf4SMichael Lotz{
20468667bf4SMichael Lotz	BAutolock lock(fCallbackLocker);
20568667bf4SMichael Lotz	return fCallbacks.BinarySearchByKey(token, &_CallbackCompare);
20668667bf4SMichael Lotz}
20768667bf4SMichael Lotz
20868667bf4SMichael Lotz
20968667bf4SMichael Lotzint
21068667bf4SMichael LotzRemoteHWInterface::_CallbackCompare(const uint32* key,
21168667bf4SMichael Lotz	const callback_info* info)
21268667bf4SMichael Lotz{
21368667bf4SMichael Lotz	if (info->token == *key)
21468667bf4SMichael Lotz		return 0;
21568667bf4SMichael Lotz
21668667bf4SMichael Lotz	if (info->token < *key)
21768667bf4SMichael Lotz		return -1;
21868667bf4SMichael Lotz
21968667bf4SMichael Lotz	return 1;
22068667bf4SMichael Lotz}
22168667bf4SMichael Lotz
22268667bf4SMichael Lotz
22368667bf4SMichael Lotzint32
22468667bf4SMichael LotzRemoteHWInterface::_EventThreadEntry(void* data)
22568667bf4SMichael Lotz{
22668667bf4SMichael Lotz	return ((RemoteHWInterface*)data)->_EventThread();
22768667bf4SMichael Lotz}
22868667bf4SMichael Lotz
22968667bf4SMichael Lotz
23068667bf4SMichael Lotzstatus_t
23168667bf4SMichael LotzRemoteHWInterface::_EventThread()
23268667bf4SMichael Lotz{
2334d9d6d7eSMichael Lotz	RemoteMessage message(fReceiveBuffer, NULL);
23468667bf4SMichael Lotz	while (true) {
23568667bf4SMichael Lotz		uint16 code;
23668667bf4SMichael Lotz		status_t result = message.NextMessage(code);
23768667bf4SMichael Lotz		if (result != B_OK) {
23868667bf4SMichael Lotz			TRACE_ERROR("failed to read message from receiver: %s\n",
23968667bf4SMichael Lotz				strerror(result));
24068667bf4SMichael Lotz			return result;
24168667bf4SMichael Lotz		}
24268667bf4SMichael Lotz
243ebf043b9SMichael Lotz		TRACE("got message code %" B_PRIu16 " with %" B_PRIu32 " bytes\n", code,
244ebf043b9SMichael Lotz			message.DataLeft());
24568667bf4SMichael Lotz
24668667bf4SMichael Lotz		if (code >= RP_MOUSE_MOVED && code <= RP_MODIFIERS_CHANGED) {
24768667bf4SMichael Lotz			// an input event, dispatch to the event stream
24868667bf4SMichael Lotz			if (fEventStream->EventReceived(message))
24968667bf4SMichael Lotz				continue;
25068667bf4SMichael Lotz		}
25168667bf4SMichael Lotz
25268667bf4SMichael Lotz		switch (code) {
2535ed41cffSMichael Lotz			case RP_INIT_CONNECTION:
2545ed41cffSMichael Lotz			{
2555ed41cffSMichael Lotz				RemoteMessage reply(NULL, fSendBuffer);
2565ed41cffSMichael Lotz				reply.Start(RP_INIT_CONNECTION);
2575ed41cffSMichael Lotz				status_t result = reply.Flush();
258e30d37ddSMichael Lotz				(void)result;
2595ed41cffSMichael Lotz				TRACE("init connection result: %s\n", strerror(result));
2605ed41cffSMichael Lotz				break;
2615ed41cffSMichael Lotz			}
2625ed41cffSMichael Lotz
26368667bf4SMichael Lotz			case RP_UPDATE_DISPLAY_MODE:
26468667bf4SMichael Lotz			{
2655ed41cffSMichael Lotz				int32 width, height;
2665ed41cffSMichael Lotz				message.Read(width);
2675ed41cffSMichael Lotz				result = message.Read(height);
2685ed41cffSMichael Lotz				if (result != B_OK) {
2695ed41cffSMichael Lotz					TRACE_ERROR("failed to read display mode\n");
2705ed41cffSMichael Lotz					break;
2715ed41cffSMichael Lotz				}
2725ed41cffSMichael Lotz
2735ed41cffSMichael Lotz				fIsConnected = true;
274f609f4faSMichael Lotz				fClientMode.virtual_width = width;
275f609f4faSMichael Lotz				fClientMode.virtual_height = height;
276f609f4faSMichael Lotz				_FillDisplayModeTiming(fClientMode);
277f609f4faSMichael Lotz				_NotifyScreenChanged();
278f609f4faSMichael Lotz				break;
27977846915SMichael Lotz			}
28077846915SMichael Lotz
28177846915SMichael Lotz			case RP_GET_SYSTEM_PALETTE:
28277846915SMichael Lotz			{
28377846915SMichael Lotz				RemoteMessage reply(NULL, fSendBuffer);
28477846915SMichael Lotz				reply.Start(RP_GET_SYSTEM_PALETTE_RESULT);
28577846915SMichael Lotz
28677846915SMichael Lotz				const color_map *map = SystemColorMap();
28777846915SMichael Lotz				uint32 count = (uint32)B_COUNT_OF(map->color_list);
28877846915SMichael Lotz
28977846915SMichael Lotz				reply.Add(count);
29077846915SMichael Lotz				for (size_t i = 0; i < count; i++) {
29177846915SMichael Lotz					const rgb_color &color = map->color_list[i];
29277846915SMichael Lotz					reply.Add(color.red);
29377846915SMichael Lotz					reply.Add(color.green);
29477846915SMichael Lotz					reply.Add(color.blue);
29577846915SMichael Lotz					reply.Add(color.alpha);
29677846915SMichael Lotz				}
29777846915SMichael Lotz
29868667bf4SMichael Lotz				break;
29968667bf4SMichael Lotz			}
30068667bf4SMichael Lotz
30168667bf4SMichael Lotz			default:
30268667bf4SMichael Lotz			{
30368667bf4SMichael Lotz				uint32 token;
30468667bf4SMichael Lotz				if (message.Read(token) == B_OK) {
30568667bf4SMichael Lotz					callback_info* info = _FindCallback(token);
30668667bf4SMichael Lotz					if (info != NULL && info->callback(info->cookie, message))
30768667bf4SMichael Lotz						break;
30868667bf4SMichael Lotz				}
30968667bf4SMichael Lotz
31068667bf4SMichael Lotz				TRACE_ERROR("unhandled remote event code %u\n", code);
31168667bf4SMichael Lotz				break;
31268667bf4SMichael Lotz			}
31368667bf4SMichael Lotz		}
31468667bf4SMichael Lotz	}
31568667bf4SMichael Lotz}
31668667bf4SMichael Lotz
31768667bf4SMichael Lotz
31868667bf4SMichael Lotzstatus_t
3195ed41cffSMichael LotzRemoteHWInterface::_NewConnectionCallback(void *cookie, BNetEndpoint &endpoint)
32068667bf4SMichael Lotz{
3215ed41cffSMichael Lotz	return ((RemoteHWInterface *)cookie)->_NewConnection(endpoint);
3225ed41cffSMichael Lotz}
32368667bf4SMichael Lotz
32468667bf4SMichael Lotz
3255ed41cffSMichael Lotzstatus_t
3265ed41cffSMichael LotzRemoteHWInterface::_NewConnection(BNetEndpoint &endpoint)
3275ed41cffSMichael Lotz{
3285ed41cffSMichael Lotz	if (fSender != NULL) {
3295ed41cffSMichael Lotz		delete fSender;
3305ed41cffSMichael Lotz		fSender = NULL;
33168667bf4SMichael Lotz	}
33268667bf4SMichael Lotz
3335ed41cffSMichael Lotz	fSendBuffer->MakeEmpty();
33468667bf4SMichael Lotz
3355ed41cffSMichael Lotz	BNetEndpoint *sendEndpoint = new(std::nothrow) BNetEndpoint(endpoint);
3365ed41cffSMichael Lotz	if (sendEndpoint == NULL)
3375ed41cffSMichael Lotz		return B_NO_MEMORY;
3385ed41cffSMichael Lotz
3395ed41cffSMichael Lotz	fSender = new(std::nothrow) NetSender(sendEndpoint, fSendBuffer);
3405ed41cffSMichael Lotz	if (fSender == NULL) {
3415ed41cffSMichael Lotz		delete sendEndpoint;
3425ed41cffSMichael Lotz		return B_NO_MEMORY;
34368667bf4SMichael Lotz	}
34468667bf4SMichael Lotz
34568667bf4SMichael Lotz	return B_OK;
34668667bf4SMichael Lotz}
34768667bf4SMichael Lotz
34868667bf4SMichael Lotz
34968667bf4SMichael Lotzvoid
35068667bf4SMichael LotzRemoteHWInterface::_Disconnect()
35168667bf4SMichael Lotz{
35268667bf4SMichael Lotz	if (fIsConnected) {
35368667bf4SMichael Lotz		RemoteMessage message(NULL, fSendBuffer);
35468667bf4SMichael Lotz		message.Start(RP_CLOSE_CONNECTION);
35568667bf4SMichael Lotz		message.Flush();
35668667bf4SMichael Lotz		fIsConnected = false;
35768667bf4SMichael Lotz	}
35868667bf4SMichael Lotz
3595ed41cffSMichael Lotz	if (fListenEndpoint != NULL)
3605ed41cffSMichael Lotz		fListenEndpoint->Close();
36168667bf4SMichael Lotz}
36268667bf4SMichael Lotz
36368667bf4SMichael Lotz
36468667bf4SMichael Lotzstatus_t
36568667bf4SMichael LotzRemoteHWInterface::SetMode(const display_mode& mode)
36668667bf4SMichael Lotz{
367f609f4faSMichael Lotz	TRACE("set mode: %" B_PRIu16 " %" B_PRIu16 "\n", mode.virtual_width,
368f609f4faSMichael Lotz		mode.virtual_height);
369f609f4faSMichael Lotz	fCurrentMode = mode;
370f609f4faSMichael Lotz	return B_OK;
37168667bf4SMichael Lotz}
37268667bf4SMichael Lotz
37368667bf4SMichael Lotz
37468667bf4SMichael Lotzvoid
37568667bf4SMichael LotzRemoteHWInterface::GetMode(display_mode* mode)
37668667bf4SMichael Lotz{
37768667bf4SMichael Lotz	if (mode == NULL || !ReadLock())
37868667bf4SMichael Lotz		return;
37968667bf4SMichael Lotz
380f609f4faSMichael Lotz	*mode = fCurrentMode;
38168667bf4SMichael Lotz	ReadUnlock();
382f609f4faSMichael Lotz
383f609f4faSMichael Lotz	TRACE("get mode: %" B_PRIu16 " %" B_PRIu16 "\n", mode->virtual_width,
384f609f4faSMichael Lotz		mode->virtual_height);
385f609f4faSMichael Lotz}
386f609f4faSMichael Lotz
387f609f4faSMichael Lotz
388f609f4faSMichael Lotzstatus_t
389f609f4faSMichael LotzRemoteHWInterface::GetPreferredMode(display_mode* mode)
390f609f4faSMichael Lotz{
391f609f4faSMichael Lotz	*mode = fClientMode;
392f609f4faSMichael Lotz	return B_OK;
39368667bf4SMichael Lotz}
39468667bf4SMichael Lotz
39568667bf4SMichael Lotz
39668667bf4SMichael Lotzstatus_t
39768667bf4SMichael LotzRemoteHWInterface::GetDeviceInfo(accelerant_device_info* info)
39868667bf4SMichael Lotz{
39968667bf4SMichael Lotz	if (!ReadLock())
40068667bf4SMichael Lotz		return B_ERROR;
40168667bf4SMichael Lotz
40268667bf4SMichael Lotz	info->version = fProtocolVersion;
40368667bf4SMichael Lotz	info->dac_speed = fConnectionSpeed;
40468667bf4SMichael Lotz	info->memory = 33554432; // 32MB
4055c3457ddSMichael Lotz	snprintf(info->name, sizeof(info->name), "Haiku, Inc. RemoteHWInterface");
4065c3457ddSMichael Lotz	snprintf(info->chipset, sizeof(info->chipset), "Haiku, Inc. Chipset");
4075c3457ddSMichael Lotz	snprintf(info->serial_no, sizeof(info->serial_no), fTarget);
40868667bf4SMichael Lotz
40968667bf4SMichael Lotz	ReadUnlock();
41068667bf4SMichael Lotz	return B_OK;
41168667bf4SMichael Lotz}
41268667bf4SMichael Lotz
41368667bf4SMichael Lotz
41468667bf4SMichael Lotzstatus_t
41568667bf4SMichael LotzRemoteHWInterface::GetFrameBufferConfig(frame_buffer_config& config)
41668667bf4SMichael Lotz{
41768667bf4SMichael Lotz	// We don't actually have a frame buffer.
41868667bf4SMichael Lotz	return B_UNSUPPORTED;
41968667bf4SMichael Lotz}
42068667bf4SMichael Lotz
42168667bf4SMichael Lotz
42268667bf4SMichael Lotzstatus_t
42368667bf4SMichael LotzRemoteHWInterface::GetModeList(display_mode** _modes, uint32* _count)
42468667bf4SMichael Lotz{
42568667bf4SMichael Lotz	AutoReadLocker _(this);
42668667bf4SMichael Lotz
427f609f4faSMichael Lotz	display_mode* modes = new(std::nothrow) display_mode[2];
42868667bf4SMichael Lotz	if (modes == NULL)
42968667bf4SMichael Lotz		return B_NO_MEMORY;
43068667bf4SMichael Lotz
431f609f4faSMichael Lotz	modes[0] = fFallbackMode;
432f609f4faSMichael Lotz	modes[1] = fClientMode;
43368667bf4SMichael Lotz	*_modes = modes;
434f609f4faSMichael Lotz	*_count = 2;
435f609f4faSMichael Lotz
43668667bf4SMichael Lotz	return B_OK;
43768667bf4SMichael Lotz}
43868667bf4SMichael Lotz
43968667bf4SMichael Lotz
44068667bf4SMichael Lotzstatus_t
44168667bf4SMichael LotzRemoteHWInterface::GetPixelClockLimits(display_mode* mode, uint32* low,
44268667bf4SMichael Lotz	uint32* high)
44368667bf4SMichael Lotz{
444f609f4faSMichael Lotz	TRACE("get pixel clock limits unsupported\n");
44568667bf4SMichael Lotz	return B_UNSUPPORTED;
44668667bf4SMichael Lotz}
44768667bf4SMichael Lotz
44868667bf4SMichael Lotz
44968667bf4SMichael Lotzstatus_t
45068667bf4SMichael LotzRemoteHWInterface::GetTimingConstraints(display_timing_constraints* constraints)
45168667bf4SMichael Lotz{
452f609f4faSMichael Lotz	TRACE("get timing constraints unsupported\n");
45368667bf4SMichael Lotz	return B_UNSUPPORTED;
45468667bf4SMichael Lotz}
45568667bf4SMichael Lotz
45668667bf4SMichael Lotz
45768667bf4SMichael Lotzstatus_t
45868667bf4SMichael LotzRemoteHWInterface::ProposeMode(display_mode* candidate, const display_mode* low,
45968667bf4SMichael Lotz	const display_mode* high)
46068667bf4SMichael Lotz{
461f609f4faSMichael Lotz	TRACE("propose mode: %" B_PRIu16 " %" B_PRIu16 "\n",
462f609f4faSMichael Lotz		candidate->virtual_width, candidate->virtual_height);
463f609f4faSMichael Lotz	return B_OK;
46468667bf4SMichael Lotz}
46568667bf4SMichael Lotz
46668667bf4SMichael Lotz
46768667bf4SMichael Lotzstatus_t
46868667bf4SMichael LotzRemoteHWInterface::SetDPMSMode(uint32 state)
46968667bf4SMichael Lotz{
47068667bf4SMichael Lotz	return B_UNSUPPORTED;
47168667bf4SMichael Lotz}
47268667bf4SMichael Lotz
47368667bf4SMichael Lotz
47468667bf4SMichael Lotzuint32
47568667bf4SMichael LotzRemoteHWInterface::DPMSMode()
47668667bf4SMichael Lotz{
47768667bf4SMichael Lotz	return B_UNSUPPORTED;
47868667bf4SMichael Lotz}
47968667bf4SMichael Lotz
48068667bf4SMichael Lotz
48168667bf4SMichael Lotzuint32
48268667bf4SMichael LotzRemoteHWInterface::DPMSCapabilities()
48368667bf4SMichael Lotz{
48468667bf4SMichael Lotz	return 0;
48568667bf4SMichael Lotz}
48668667bf4SMichael Lotz
48768667bf4SMichael Lotz
4883a2b67b5SAdrien Destuguesstatus_t
4893a2b67b5SAdrien DestuguesRemoteHWInterface::SetBrightness(float)
4903a2b67b5SAdrien Destugues{
4913a2b67b5SAdrien Destugues	return B_UNSUPPORTED;
4923a2b67b5SAdrien Destugues}
4933a2b67b5SAdrien Destugues
4943a2b67b5SAdrien Destugues
4953a2b67b5SAdrien Destuguesstatus_t
4963a2b67b5SAdrien DestuguesRemoteHWInterface::GetBrightness(float*)
4973a2b67b5SAdrien Destugues{
4983a2b67b5SAdrien Destugues	return B_UNSUPPORTED;
4993a2b67b5SAdrien Destugues}
5003a2b67b5SAdrien Destugues
5013a2b67b5SAdrien Destugues
50268667bf4SMichael Lotzsem_id
50368667bf4SMichael LotzRemoteHWInterface::RetraceSemaphore()
50468667bf4SMichael Lotz{
50568667bf4SMichael Lotz	return -1;
50668667bf4SMichael Lotz}
50768667bf4SMichael Lotz
50868667bf4SMichael Lotz
50968667bf4SMichael Lotzstatus_t
51068667bf4SMichael LotzRemoteHWInterface::WaitForRetrace(bigtime_t timeout)
51168667bf4SMichael Lotz{
51268667bf4SMichael Lotz	return B_UNSUPPORTED;
51368667bf4SMichael Lotz}
51468667bf4SMichael Lotz
51568667bf4SMichael Lotz
51668667bf4SMichael Lotzvoid
51768667bf4SMichael LotzRemoteHWInterface::SetCursor(ServerCursor* cursor)
51868667bf4SMichael Lotz{
51968667bf4SMichael Lotz	HWInterface::SetCursor(cursor);
52068667bf4SMichael Lotz	RemoteMessage message(NULL, fSendBuffer);
52168667bf4SMichael Lotz	message.Start(RP_SET_CURSOR);
52282873c6eSMichael Lotz	message.AddCursor(CursorAndDragBitmap().Get());
52368667bf4SMichael Lotz}
52468667bf4SMichael Lotz
52568667bf4SMichael Lotz
52668667bf4SMichael Lotzvoid
52768667bf4SMichael LotzRemoteHWInterface::SetCursorVisible(bool visible)
52868667bf4SMichael Lotz{
52968667bf4SMichael Lotz	HWInterface::SetCursorVisible(visible);
53068667bf4SMichael Lotz	RemoteMessage message(NULL, fSendBuffer);
53168667bf4SMichael Lotz	message.Start(RP_SET_CURSOR_VISIBLE);
53268667bf4SMichael Lotz	message.Add(visible);
53368667bf4SMichael Lotz}
53468667bf4SMichael Lotz
53568667bf4SMichael Lotz
53668667bf4SMichael Lotzvoid
53768667bf4SMichael LotzRemoteHWInterface::MoveCursorTo(float x, float y)
53868667bf4SMichael Lotz{
53968667bf4SMichael Lotz	HWInterface::MoveCursorTo(x, y);
54068667bf4SMichael Lotz	RemoteMessage message(NULL, fSendBuffer);
54168667bf4SMichael Lotz	message.Start(RP_MOVE_CURSOR_TO);
54268667bf4SMichael Lotz	message.Add(x);
54368667bf4SMichael Lotz	message.Add(y);
54468667bf4SMichael Lotz}
54568667bf4SMichael Lotz
54668667bf4SMichael Lotz
54768667bf4SMichael Lotzvoid
54868667bf4SMichael LotzRemoteHWInterface::SetDragBitmap(const ServerBitmap* bitmap,
54968667bf4SMichael Lotz	const BPoint& offsetFromCursor)
55068667bf4SMichael Lotz{
55168667bf4SMichael Lotz	HWInterface::SetDragBitmap(bitmap, offsetFromCursor);
55268667bf4SMichael Lotz	RemoteMessage message(NULL, fSendBuffer);
55368667bf4SMichael Lotz	message.Start(RP_SET_CURSOR);
554aeb68978SAxel Dörfler	message.AddCursor(CursorAndDragBitmap().Get());
55568667bf4SMichael Lotz}
55668667bf4SMichael Lotz
55768667bf4SMichael Lotz
55868667bf4SMichael LotzRenderingBuffer*
55968667bf4SMichael LotzRemoteHWInterface::FrontBuffer() const
56068667bf4SMichael Lotz{
56168667bf4SMichael Lotz	return NULL;
56268667bf4SMichael Lotz}
56368667bf4SMichael Lotz
56468667bf4SMichael Lotz
56568667bf4SMichael LotzRenderingBuffer*
56668667bf4SMichael LotzRemoteHWInterface::BackBuffer() const
56768667bf4SMichael Lotz{
56868667bf4SMichael Lotz	return NULL;
56968667bf4SMichael Lotz}
57068667bf4SMichael Lotz
57168667bf4SMichael Lotz
57268667bf4SMichael Lotzbool
57368667bf4SMichael LotzRemoteHWInterface::IsDoubleBuffered() const
57468667bf4SMichael Lotz{
57568667bf4SMichael Lotz	return false;
57668667bf4SMichael Lotz}
57768667bf4SMichael Lotz
57868667bf4SMichael Lotz
57968667bf4SMichael Lotzstatus_t
58068667bf4SMichael LotzRemoteHWInterface::InvalidateRegion(BRegion& region)
58168667bf4SMichael Lotz{
58268667bf4SMichael Lotz	RemoteMessage message(NULL, fSendBuffer);
58368667bf4SMichael Lotz	message.Start(RP_INVALIDATE_REGION);
58468667bf4SMichael Lotz	message.AddRegion(region);
58568667bf4SMichael Lotz	return B_OK;
58668667bf4SMichael Lotz}
58768667bf4SMichael Lotz
58868667bf4SMichael Lotz
58968667bf4SMichael Lotzstatus_t
59068667bf4SMichael LotzRemoteHWInterface::Invalidate(const BRect& frame)
59168667bf4SMichael Lotz{
59268667bf4SMichael Lotz	RemoteMessage message(NULL, fSendBuffer);
59368667bf4SMichael Lotz	message.Start(RP_INVALIDATE_RECT);
59468667bf4SMichael Lotz	message.Add(frame);
59568667bf4SMichael Lotz	return B_OK;
59668667bf4SMichael Lotz}
59768667bf4SMichael Lotz
59868667bf4SMichael Lotz
59968667bf4SMichael Lotzstatus_t
60068667bf4SMichael LotzRemoteHWInterface::CopyBackToFront(const BRect& frame)
60168667bf4SMichael Lotz{
60268667bf4SMichael Lotz	return B_OK;
60368667bf4SMichael Lotz}
604f609f4faSMichael Lotz
605f609f4faSMichael Lotz
606f609f4faSMichael Lotzvoid
607f609f4faSMichael LotzRemoteHWInterface::_FillDisplayModeTiming(display_mode &mode)
608f609f4faSMichael Lotz{
609f609f4faSMichael Lotz	mode.timing.pixel_clock
610f609f4faSMichael Lotz		= (uint64_t)mode.virtual_width * mode.virtual_height * 60 / 1000;
611f609f4faSMichael Lotz	mode.timing.h_display = mode.timing.h_sync_start = mode.timing.h_sync_end
612f609f4faSMichael Lotz		= mode.timing.h_total = mode.virtual_width;
613f609f4faSMichael Lotz	mode.timing.v_display = mode.timing.v_sync_start = mode.timing.v_sync_end
614f609f4faSMichael Lotz		= mode.timing.v_total = mode.virtual_height;
615f609f4faSMichael Lotz}
616