1a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
2a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  This file is called main.c, because it contains most of the new functions
3a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  for use with LibVNCServer.
4a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
5a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  LibVNCServer (C) 2001 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
6a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  Original OSXvnc (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
7a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  Original Xvnc (C) 1999 AT&T Laboratories Cambridge.
8a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  All Rights Reserved.
9a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *
10a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *  see GPL (latest version) for full details
11a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
12a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
13a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef __STRICT_ANSI__
14a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define _BSD_SOURCE
15a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
16a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <rfb/rfb.h>
17a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <rfb/rfbregion.h>
18a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "private.h"
19a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
20a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <stdarg.h>
21a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <errno.h>
22a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
23a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifndef false
24a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define false 0
25a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define true -1
26a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
27a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
28a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_SYS_TYPES_H
29a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <sys/types.h>
30a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
31a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
32a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifndef WIN32
33a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <sys/socket.h>
34a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <netinet/in.h>
35a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <unistd.h>
36a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
37a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
38a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <signal.h>
39a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <time.h>
40a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
41a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int extMutex_initialized = 0;
42a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int logMutex_initialized = 0;
43a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
44a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic MUTEX(logMutex);
45a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic MUTEX(extMutex);
46a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
47a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
48a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int rfbEnableLogging=1;
49a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
50a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_WORDS_BIGENDIAN
51a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar rfbEndianTest = (1==0);
52a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
53a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar rfbEndianTest = (1==1);
54a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
55a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
56a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
57a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Protocol extensions
58a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
59a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
60a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbProtocolExtension* rfbExtensionHead = NULL;
61a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
62a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
63a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This method registers a list of new extensions.
64a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * It avoids same extension getting registered multiple times.
65a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * The order is not preserved if multiple extensions are
66a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * registered at one-go.
67a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
68a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid
69a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbRegisterProtocolExtension(rfbProtocolExtension* extension)
70a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
71a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbProtocolExtension *head = rfbExtensionHead, *next = NULL;
72a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
73a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(extension == NULL)
74a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
75a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
76a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	next = extension->next;
77a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
78a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! extMutex_initialized) {
79a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		INIT_MUTEX(extMutex);
80a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		extMutex_initialized = 1;
81a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
82a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
83a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	LOCK(extMutex);
84a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
85a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while(head != NULL) {
86a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if(head == extension) {
87a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			UNLOCK(extMutex);
88a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbRegisterProtocolExtension(next);
89a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			return;
90a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
91a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
92a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		head = head->next;
93a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
94a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
95a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	extension->next = rfbExtensionHead;
96a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbExtensionHead = extension;
97a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
98a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	UNLOCK(extMutex);
99a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbRegisterProtocolExtension(next);
100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This method unregisters a list of extensions.
104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * These extensions won't be available for any new
105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * client connection.
106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid
108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbUnregisterProtocolExtension(rfbProtocolExtension* extension)
109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbProtocolExtension *cur = NULL, *pre = NULL;
112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(extension == NULL)
114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! extMutex_initialized) {
117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		INIT_MUTEX(extMutex);
118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		extMutex_initialized = 1;
119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	LOCK(extMutex);
122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(rfbExtensionHead == extension) {
124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbExtensionHead = rfbExtensionHead->next;
125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		UNLOCK(extMutex);
126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbUnregisterProtocolExtension(extension->next);
127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cur = pre = rfbExtensionHead;
131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while(cur) {
133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if(cur == extension) {
134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			pre->next = cur->next;
135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			break;
136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		pre = cur;
138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		cur = cur->next;
139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	UNLOCK(extMutex);
142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbUnregisterProtocolExtension(extension->next);
144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbProtocolExtension* rfbGetExtensionIterator()
147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! extMutex_initialized) {
149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		INIT_MUTEX(extMutex);
150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		extMutex_initialized = 1;
151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	LOCK(extMutex);
154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return rfbExtensionHead;
155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbReleaseExtensionIterator()
158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	UNLOCK(extMutex);
160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool rfbEnableExtension(rfbClientPtr cl, rfbProtocolExtension* extension,
163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	void* data)
164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbExtensionData* extData;
166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* make sure extension is not yet enabled. */
168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for(extData = cl->extensions; extData; extData = extData->next)
169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if(extData->extension == extension)
170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			return FALSE;
171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	extData = calloc(sizeof(rfbExtensionData),1);
173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	extData->extension = extension;
174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	extData->data = data;
175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	extData->next = cl->extensions;
176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cl->extensions = extData;
177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return TRUE;
179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool rfbDisableExtension(rfbClientPtr cl, rfbProtocolExtension* extension)
182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbExtensionData* extData;
184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbExtensionData* prevData = NULL;
185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for(extData = cl->extensions; extData; extData = extData->next) {
187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if(extData->extension == extension) {
188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if(extData->data)
189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				free(extData->data);
190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if(prevData == NULL)
191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				cl->extensions = extData->next;
192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			else
193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				prevData->next = extData->next;
194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			return TRUE;
195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		prevData = extData;
197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return FALSE;
200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid* rfbGetExtensionClientData(rfbClientPtr cl, rfbProtocolExtension* extension)
203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbExtensionData* data = cl->extensions;
205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    while(data && data->extension != extension)
207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	data = data->next;
208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if(data == NULL) {
210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbLog("Extension is not enabled !\n");
211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* rfbCloseClient(cl); */
212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return NULL;
213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return data->data;
216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Logging
220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbLogEnable(int enabled) {
223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbEnableLogging=enabled;
224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbLog prints a time-stamped message to the log file (stderr).
228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void
231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbDefaultLog(const char *format, ...)
232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    va_list args;
234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    char buf[256];
235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    time_t log_clock;
236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if(!rfbEnableLogging)
238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return;
239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (! logMutex_initialized) {
241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      INIT_MUTEX(logMutex);
242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      logMutex_initialized = 1;
243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    LOCK(logMutex);
246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    va_start(args, format);
247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    time(&log_clock);
249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    strftime(buf, 255, "%d/%m/%Y %X ", localtime(&log_clock));
250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    fprintf(stderr, "%s", buf);
251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    vfprintf(stderr, format, args);
253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    fflush(stderr);
254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    va_end(args);
256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    UNLOCK(logMutex);
257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbLogProc rfbLog=rfbDefaultLog;
260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbLogProc rfbErr=rfbDefaultLog;
261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbLogPerror(const char *str)
263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbErr("%s: %s\n", str, strerror(errno));
265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbScheduleCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy)
268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   rfbClientIteratorPtr iterator;
270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   rfbClientPtr cl;
271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   iterator=rfbGetClientIterator(rfbScreen);
273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   while((cl=rfbClientIteratorNext(iterator))) {
274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     LOCK(cl->updateMutex);
275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     if(cl->useCopyRect) {
276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       sraRegionPtr modifiedRegionBackup;
277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       if(!sraRgnEmpty(cl->copyRegion)) {
278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  if(cl->copyDX!=dx || cl->copyDY!=dy) {
279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	     /* if a copyRegion was not yet executed, treat it as a
280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	      * modifiedRegion. The idea: in this case it could be
281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	      * source of the new copyRect or modified anyway. */
282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	     sraRgnOr(cl->modifiedRegion,cl->copyRegion);
283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	     sraRgnMakeEmpty(cl->copyRegion);
284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  } else {
285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	     /* we have to set the intersection of the source of the copy
286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	      * and the old copy to modified. */
287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	     modifiedRegionBackup=sraRgnCreateRgn(copyRegion);
288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	     sraRgnOffset(modifiedRegionBackup,-dx,-dy);
289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	     sraRgnAnd(modifiedRegionBackup,cl->copyRegion);
290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	     sraRgnOr(cl->modifiedRegion,modifiedRegionBackup);
291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	     sraRgnDestroy(modifiedRegionBackup);
292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  }
293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       }
294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       sraRgnOr(cl->copyRegion,copyRegion);
296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       cl->copyDX = dx;
297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       cl->copyDY = dy;
298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       /* if there were modified regions, which are now copied,
300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	* mark them as modified, because the source of these can be overlapped
301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	* either by new modified or now copied regions. */
302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       modifiedRegionBackup=sraRgnCreateRgn(cl->modifiedRegion);
303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       sraRgnOffset(modifiedRegionBackup,dx,dy);
304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       sraRgnAnd(modifiedRegionBackup,cl->copyRegion);
305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       sraRgnOr(cl->modifiedRegion,modifiedRegionBackup);
306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       sraRgnDestroy(modifiedRegionBackup);
307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       if(!cl->enableCursorShapeUpdates) {
309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          /*
310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat           * n.b. (dx, dy) is the vector pointing in the direction the
311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat           * copyrect displacement will take place.  copyRegion is the
312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat           * destination rectangle (say), not the source rectangle.
313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat           */
314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          sraRegionPtr cursorRegion;
315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          int x = cl->cursorX - cl->screen->cursor->xhot;
316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          int y = cl->cursorY - cl->screen->cursor->yhot;
317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          int w = cl->screen->cursor->width;
318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          int h = cl->screen->cursor->height;
319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          cursorRegion = sraRgnCreateRect(x, y, x + w, y + h);
321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          sraRgnAnd(cursorRegion, cl->copyRegion);
322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          if(!sraRgnEmpty(cursorRegion)) {
323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat             /*
324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              * current cursor rect overlaps with the copy region *dest*,
325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              * mark it as modified since we won't copy-rect stuff to it.
326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              */
327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat             sraRgnOr(cl->modifiedRegion, cursorRegion);
328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          }
329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          sraRgnDestroy(cursorRegion);
330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          cursorRegion = sraRgnCreateRect(x, y, x + w, y + h);
332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          /* displace it to check for overlap with copy region source: */
333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          sraRgnOffset(cursorRegion, dx, dy);
334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          sraRgnAnd(cursorRegion, cl->copyRegion);
335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          if(!sraRgnEmpty(cursorRegion)) {
336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat             /*
337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              * current cursor rect overlaps with the copy region *source*,
338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              * mark the *displaced* cursorRegion as modified since we
339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              * won't copyrect stuff to it.
340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat              */
341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat             sraRgnOr(cl->modifiedRegion, cursorRegion);
342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          }
343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          sraRgnDestroy(cursorRegion);
344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       }
345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     } else {
347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       sraRgnOr(cl->modifiedRegion,copyRegion);
348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     }
349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     TSIGNAL(cl->updateCond);
350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     UNLOCK(cl->updateMutex);
351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   }
352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   rfbReleaseClientIterator(iterator);
354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbDoCopyRegion(rfbScreenInfoPtr screen,sraRegionPtr copyRegion,int dx,int dy)
357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   sraRectangleIterator* i;
359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   sraRect rect;
360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   int j,widthInBytes,bpp=screen->serverFormat.bitsPerPixel/8,
361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rowstride=screen->paddedWidthInBytes;
362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   char *in,*out;
363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   /* copy it, really */
365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   i = sraRgnGetReverseIterator(copyRegion,dx<0,dy<0);
366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   while(sraRgnIteratorNext(i,&rect)) {
367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     widthInBytes = (rect.x2-rect.x1)*bpp;
368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     out = screen->frameBuffer+rect.x1*bpp+rect.y1*rowstride;
369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     in = screen->frameBuffer+(rect.x1-dx)*bpp+(rect.y1-dy)*rowstride;
370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     if(dy<0)
371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       for(j=rect.y1;j<rect.y2;j++,out+=rowstride,in+=rowstride)
372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 memmove(out,in,widthInBytes);
373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     else {
374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       out += rowstride*(rect.y2-rect.y1-1);
375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       in += rowstride*(rect.y2-rect.y1-1);
376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       for(j=rect.y2-1;j>=rect.y1;j--,out-=rowstride,in-=rowstride)
377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 memmove(out,in,widthInBytes);
378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     }
379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   }
380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   sraRgnReleaseIterator(i);
381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   rfbScheduleCopyRegion(screen,copyRegion,dx,dy);
383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbDoCopyRect(rfbScreenInfoPtr screen,int x1,int y1,int x2,int y2,int dx,int dy)
386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  sraRegionPtr region = sraRgnCreateRect(x1,y1,x2,y2);
388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbDoCopyRegion(screen,region,dx,dy);
389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  sraRgnDestroy(region);
390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbScheduleCopyRect(rfbScreenInfoPtr screen,int x1,int y1,int x2,int y2,int dx,int dy)
393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  sraRegionPtr region = sraRgnCreateRect(x1,y1,x2,y2);
395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbScheduleCopyRegion(screen,region,dx,dy);
396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  sraRgnDestroy(region);
397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbMarkRegionAsModified(rfbScreenInfoPtr screen,sraRegionPtr modRegion)
400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   rfbClientIteratorPtr iterator;
402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   rfbClientPtr cl;
403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   iterator=rfbGetClientIterator(screen);
405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   while((cl=rfbClientIteratorNext(iterator))) {
406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     LOCK(cl->updateMutex);
407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     sraRgnOr(cl->modifiedRegion,modRegion);
408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     TSIGNAL(cl->updateCond);
409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     UNLOCK(cl->updateMutex);
410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   }
411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   rfbReleaseClientIterator(iterator);
413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbScaledScreenUpdate(rfbScreenInfoPtr screen, int x1, int y1, int x2, int y2);
416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbMarkRectAsModified(rfbScreenInfoPtr screen,int x1,int y1,int x2,int y2)
417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   sraRegionPtr region;
419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   int i;
420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   if(x1>x2) { i=x1; x1=x2; x2=i; }
422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   if(x1<0) x1=0;
423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   if(x2>screen->width) x2=screen->width;
424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   if(x1==x2) return;
425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   if(y1>y2) { i=y1; y1=y2; y2=i; }
427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   if(y1<0) y1=0;
428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   if(y2>screen->height) y2=screen->height;
429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   if(y1==y2) return;
430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   /* update scaled copies for this rectangle */
432a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   rfbScaledScreenUpdate(screen,x1,y1,x2,y2);
433a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
434a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   region = sraRgnCreateRect(x1,y1,x2,y2);
435a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   rfbMarkRegionAsModified(screen,region);
436a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   sraRgnDestroy(region);
437a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
438a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
439a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <unistd.h>
441a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
442a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void *
443a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatclientOutput(void *data)
444a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
445a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientPtr cl = (rfbClientPtr)data;
446a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbBool haveUpdate;
447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    sraRegion* updateRegion;
448a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
449a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    while (1) {
450a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        haveUpdate = false;
451a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        while (!haveUpdate) {
452a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (cl->sock == -1) {
453a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			/* Client has disconnected. */
454a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			return NULL;
455a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
456a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (cl->state != RFB_NORMAL || cl->onHold) {
457a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			/* just sleep until things get normal */
458a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			usleep(cl->screen->deferUpdateTime * 1000);
459a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			continue;
460a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
461a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
462a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		LOCK(cl->updateMutex);
463a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
464a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (sraRgnEmpty(cl->requestedRegion)) {
465a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			; /* always require a FB Update Request (otherwise can crash.) */
466a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
467a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			haveUpdate = FB_UPDATE_PENDING(cl);
468a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if(!haveUpdate) {
469a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				updateRegion = sraRgnCreateRgn(cl->modifiedRegion);
470a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				haveUpdate   = sraRgnAnd(updateRegion,cl->requestedRegion);
471a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				sraRgnDestroy(updateRegion);
472a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
473a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
474a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
475a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (!haveUpdate) {
476a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			WAIT(cl->updateCond, cl->updateMutex);
477a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
478a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
479a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		UNLOCK(cl->updateMutex);
480a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        }
481a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
482a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        /* OK, now, to save bandwidth, wait a little while for more
483a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat           updates to come along. */
484a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        usleep(cl->screen->deferUpdateTime * 1000);
485a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
486a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        /* Now, get the region we're going to update, and remove
487a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat           it from cl->modifiedRegion _before_ we send the update.
488a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat           That way, if anything that overlaps the region we're sending
489a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat           is updated, we'll be sure to do another update later. */
490a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        LOCK(cl->updateMutex);
491a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	updateRegion = sraRgnCreateRgn(cl->modifiedRegion);
492a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        UNLOCK(cl->updateMutex);
493a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
494a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        /* Now actually send the update. */
495a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbIncrClientRef(cl);
496a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        LOCK(cl->sendMutex);
497a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        rfbSendFramebufferUpdate(cl, updateRegion);
498a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        UNLOCK(cl->sendMutex);
499a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbDecrClientRef(cl);
500a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
501a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	sraRgnDestroy(updateRegion);
502a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
503a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
504a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* Not reached. */
505a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return NULL;
506a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
507a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
508a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void *
509a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatclientInput(void *data)
510a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
511a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientPtr cl = (rfbClientPtr)data;
512a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    pthread_t output_thread;
513a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    pthread_create(&output_thread, NULL, clientOutput, (void *)cl);
514a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
515a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    while (1) {
516a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fd_set rfds, wfds, efds;
517a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	struct timeval tv;
518a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int n;
519a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
520a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (cl->sock == -1) {
521a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  /* Client has disconnected. */
522a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            break;
523a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        }
524a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
525a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	FD_ZERO(&rfds);
526a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	FD_SET(cl->sock, &rfds);
527a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	FD_ZERO(&efds);
528a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	FD_SET(cl->sock, &efds);
529a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
530a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* Are we transferring a file in the background? */
531a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	FD_ZERO(&wfds);
532a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if ((cl->fileTransfer.fd!=-1) && (cl->fileTransfer.sending==1))
533a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    FD_SET(cl->sock, &wfds);
534a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
535a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	tv.tv_sec = 60; /* 1 minute */
536a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	tv.tv_usec = 0;
537a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	n = select(cl->sock + 1, &rfds, &wfds, &efds, &tv);
538a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (n < 0) {
539a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    rfbLogPerror("ReadExact: select");
540a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    break;
541a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
542a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (n == 0) /* timeout */
543a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	{
544a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            rfbSendFileTransferChunk(cl);
545a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    continue;
546a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        }
547a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
548a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        /* We have some space on the transmit queue, send some data */
549a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (FD_ISSET(cl->sock, &wfds))
550a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            rfbSendFileTransferChunk(cl);
551a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
552a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (FD_ISSET(cl->sock, &rfds) || FD_ISSET(cl->sock, &efds))
553a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            rfbProcessClientMessage(cl);
554a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
555a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
556a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* Get rid of the output thread. */
557a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    LOCK(cl->updateMutex);
558a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    TSIGNAL(cl->updateCond);
559a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    UNLOCK(cl->updateMutex);
560a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    IF_PTHREADS(pthread_join(output_thread, NULL));
561a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
562a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientConnectionGone(cl);
563a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
564a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return NULL;
565a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
566a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
567a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void*
568a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatlistenerRun(void *data)
569a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
570a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbScreenInfoPtr screen=(rfbScreenInfoPtr)data;
571a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    int client_fd;
572a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    struct sockaddr_storage peer;
573a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientPtr cl = NULL;
574a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    socklen_t len;
575a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    fd_set listen_fds;  /* temp file descriptor list for select() */
576a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
577a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* TODO: this thread wont die by restarting the server */
578a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* TODO: HTTP is not handled */
579a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    while (1) {
580a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        client_fd = -1;
581a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        FD_ZERO(&listen_fds);
582a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(screen->listenSock >= 0)
583a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  FD_SET(screen->listenSock, &listen_fds);
584a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(screen->listen6Sock >= 0)
585a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  FD_SET(screen->listen6Sock, &listen_fds);
586a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
587a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if (select(screen->maxFd+1, &listen_fds, NULL, NULL, NULL) == -1) {
588a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            rfbLogPerror("listenerRun: error in select");
589a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat            return NULL;
590a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        }
591a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
592a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* there is something on the listening sockets, handle new connections */
593a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	len = sizeof (peer);
594a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (FD_ISSET(screen->listenSock, &listen_fds))
595a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    client_fd = accept(screen->listenSock, (struct sockaddr*)&peer, &len);
596a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	else if (FD_ISSET(screen->listen6Sock, &listen_fds))
597a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    client_fd = accept(screen->listen6Sock, (struct sockaddr*)&peer, &len);
598a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
599a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if(client_fd >= 0)
600a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  cl = rfbNewClient(screen,client_fd);
601a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (cl && !cl->onHold )
602a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	  rfbStartOnHoldClient(cl);
603a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
604a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return(NULL);
605a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
606a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
607a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid
608a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbStartOnHoldClient(rfbClientPtr cl)
609a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
610a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    pthread_create(&cl->client_thread, NULL, clientInput, (void *)cl);
611a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
612a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
613a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
614a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
615a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid
616a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbStartOnHoldClient(rfbClientPtr cl)
617a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
618a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cl->onHold = FALSE;
619a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
620a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
621a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
622a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
623a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid
624a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbRefuseOnHoldClient(rfbClientPtr cl)
625a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
626a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbCloseClient(cl);
627a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientConnectionGone(cl);
628a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
629a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
630a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void
631a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbDefaultKbdAddEvent(rfbBool down, rfbKeySym keySym, rfbClientPtr cl)
632a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
633a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
634a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
635a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid
636a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbDefaultPtrAddEvent(int buttonMask, int x, int y, rfbClientPtr cl)
637a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
638a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientIteratorPtr iterator;
639a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientPtr other_client;
640a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbScreenInfoPtr s = cl->screen;
641a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
642a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (x != s->cursorX || y != s->cursorY) {
643a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    LOCK(s->cursorMutex);
644a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    s->cursorX = x;
645a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    s->cursorY = y;
646a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    UNLOCK(s->cursorMutex);
647a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
648a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* The cursor was moved by this client, so don't send CursorPos. */
649a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (cl->enableCursorPosUpdates)
650a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      cl->cursorWasMoved = FALSE;
651a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
652a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* But inform all remaining clients about this cursor movement. */
653a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    iterator = rfbGetClientIterator(s);
654a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    while ((other_client = rfbClientIteratorNext(iterator)) != NULL) {
655a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (other_client != cl && other_client->enableCursorPosUpdates) {
656a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	other_client->cursorWasMoved = TRUE;
657a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
658a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
659a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbReleaseClientIterator(iterator);
660a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
661a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
662a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
663a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void rfbDefaultSetXCutText(char* text, int len, rfbClientPtr cl)
664a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
665a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
666a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
667a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* TODO: add a nice VNC or RFB cursor */
668a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
669a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if defined(WIN32) || defined(sparc) || !defined(NO_STRICT_ANSI)
670a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbCursor myCursor =
671a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
672a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   FALSE, FALSE, FALSE, FALSE,
673a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   (unsigned char*)"\000\102\044\030\044\102\000",
674a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   (unsigned char*)"\347\347\176\074\176\347\347",
675a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   8, 7, 3, 3,
676a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   0, 0, 0,
677a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   0xffff, 0xffff, 0xffff,
678a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   NULL
679a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat};
680a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
681a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbCursor myCursor =
682a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
683a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   cleanup: FALSE,
684a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   cleanupSource: FALSE,
685a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   cleanupMask: FALSE,
686a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   cleanupRichSource: FALSE,
687a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   source: "\000\102\044\030\044\102\000",
688a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   mask:   "\347\347\176\074\176\347\347",
689a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   width: 8, height: 7, xhot: 3, yhot: 3,
690a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   foreRed: 0, foreGreen: 0, foreBlue: 0,
691a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   backRed: 0xffff, backGreen: 0xffff, backBlue: 0xffff,
692a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   richSource: NULL
693a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat};
694a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
695a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
696a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbCursorPtr rfbDefaultGetCursorPtr(rfbClientPtr cl)
697a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
698a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   return(cl->screen->cursor);
699a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
700a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
701a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* response is cl->authChallenge vncEncrypted with passwd */
702a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool rfbDefaultPasswordCheck(rfbClientPtr cl,const char* response,int len)
703a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
704a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  int i;
705a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  char *passwd=rfbDecryptPasswdFromFile(cl->screen->authPasswdData);
706a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
707a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if(!passwd) {
708a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbErr("Couldn't read password file: %s\n",cl->screen->authPasswdData);
709a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return(FALSE);
710a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
711a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
712a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbEncryptBytes(cl->authChallenge, passwd);
713a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
714a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* Lose the password from memory */
715a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  for (i = strlen(passwd); i >= 0; i--) {
716a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    passwd[i] = '\0';
717a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
718a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
719a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  free(passwd);
720a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
721a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (memcmp(cl->authChallenge, response, len) != 0) {
722a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbErr("authProcessClientMessage: authentication failed from %s\n",
723a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	   cl->host);
724a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return(FALSE);
725a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
726a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
727a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return(TRUE);
728a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
729a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
730a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* for this method, authPasswdData is really a pointer to an array
731a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   of char*'s, where the last pointer is 0. */
732a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool rfbCheckPasswordByList(rfbClientPtr cl,const char* response,int len)
733a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
734a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  char **passwds;
735a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  int i=0;
736a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
737a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  for(passwds=(char**)cl->screen->authPasswdData;*passwds;passwds++,i++) {
738a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    uint8_t auth_tmp[CHALLENGESIZE];
739a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    memcpy((char *)auth_tmp, (char *)cl->authChallenge, CHALLENGESIZE);
740a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbEncryptBytes(auth_tmp, *passwds);
741a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
742a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (memcmp(auth_tmp, response, len) == 0) {
743a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if(i>=cl->screen->authPasswdFirstViewOnly)
744a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	cl->viewOnly=TRUE;
745a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      return(TRUE);
746a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
747a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
748a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
749a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbErr("authProcessClientMessage: authentication failed from %s\n",
750a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 cl->host);
751a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return(FALSE);
752a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
753a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
754a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbDoNothingWithClient(rfbClientPtr cl)
755a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
756a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
757a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
758a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic enum rfbNewClientAction rfbDefaultNewClientHook(rfbClientPtr cl)
759a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
760a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return RFB_CLIENT_ACCEPT;
761a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
762a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
763a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
764a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Update server's pixel format in screenInfo structure. This
765a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * function is called from rfbGetScreen() and rfbNewFramebuffer().
766a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
767a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
768a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void rfbInitServerFormat(rfbScreenInfoPtr screen, int bitsPerSample)
769a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
770a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   rfbPixelFormat* format=&screen->serverFormat;
771a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
772a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   format->bitsPerPixel = screen->bitsPerPixel;
773a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   format->depth = screen->depth;
774a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   format->bigEndian = rfbEndianTest?FALSE:TRUE;
775a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   format->trueColour = TRUE;
776a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->colourMap.count = 0;
777a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->colourMap.is16 = 0;
778a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->colourMap.data.bytes = NULL;
779a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
780a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   if (format->bitsPerPixel == 8) {
781a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     format->redMax = 7;
782a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     format->greenMax = 7;
783a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     format->blueMax = 3;
784a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     format->redShift = 0;
785a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     format->greenShift = 3;
786a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     format->blueShift = 6;
787a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   } else {
788a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     format->redMax = (1 << bitsPerSample) - 1;
789a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     format->greenMax = (1 << bitsPerSample) - 1;
790a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     format->blueMax = (1 << bitsPerSample) - 1;
791a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     if(rfbEndianTest) {
792a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       format->redShift = 0;
793a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       format->greenShift = bitsPerSample;
794a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       format->blueShift = bitsPerSample * 2;
795a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     } else {
796a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       if(format->bitsPerPixel==8*3) {
797a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 format->redShift = bitsPerSample*2;
798a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 format->greenShift = bitsPerSample*1;
799a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 format->blueShift = 0;
800a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       } else {
801a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 format->redShift = bitsPerSample*3;
802a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 format->greenShift = bitsPerSample*2;
803a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	 format->blueShift = bitsPerSample;
804a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       }
805a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     }
806a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   }
807a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
808a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
809a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
810a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int width,int height,int bitsPerSample,int samplesPerPixel,
811a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int bytesPerPixel)
812a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
813a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   rfbScreenInfoPtr screen=calloc(sizeof(rfbScreenInfo),1);
814a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
815a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   if (! logMutex_initialized) {
816a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     INIT_MUTEX(logMutex);
817a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     logMutex_initialized = 1;
818a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   }
819a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
820a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
821a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   if(width&3)
822a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     rfbErr("WARNING: Width (%d) is not a multiple of 4. VncViewer has problems with that.\n",width);
823a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
824a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->autoPort=FALSE;
825a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->clientHead=NULL;
826a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->pointerClient=NULL;
827a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->port=5900;
828a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->ipv6port=5900;
829a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->socketState=RFB_SOCKET_INIT;
830a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
831a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->inetdInitDone = FALSE;
832a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->inetdSock=-1;
833a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
834a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->udpSock=-1;
835a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->udpSockConnected=FALSE;
836a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->udpPort=0;
837a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->udpClient=NULL;
838a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
839a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->maxFd=0;
840a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->listenSock=-1;
841a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->listen6Sock=-1;
842a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
843a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->httpInitDone=FALSE;
844a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->httpEnableProxyConnect=FALSE;
845a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->httpPort=0;
846a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->http6Port=0;
847a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->httpDir=NULL;
848a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->httpListenSock=-1;
849a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->httpListen6Sock=-1;
850a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->httpSock=-1;
851a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
852a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->desktopName = "LibVNCServer";
853a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->alwaysShared = FALSE;
854a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->neverShared = FALSE;
855a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->dontDisconnect = FALSE;
856a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->authPasswdData = NULL;
857a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->authPasswdFirstViewOnly = 1;
858a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
859a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->width = width;
860a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->height = height;
861a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->bitsPerPixel = screen->depth = 8*bytesPerPixel;
862a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
863a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->passwordCheck = rfbDefaultPasswordCheck;
864a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
865a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->ignoreSIGPIPE = TRUE;
866a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
867a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   /* disable progressive updating per default */
868a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->progressiveSliceHeight = 0;
869a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
870a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->listenInterface = htonl(INADDR_ANY);
871a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
872a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->deferUpdateTime=5;
873a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->maxRectsPerUpdate=50;
874a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
875a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->handleEventsEagerly = FALSE;
876a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
877a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->protocolMajorVersion = rfbProtocolMajorVersion;
878a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->protocolMinorVersion = rfbProtocolMinorVersion;
879a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
880a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->permitFileTransfer = FALSE;
881a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
882a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   if(!rfbProcessArguments(screen,argc,argv)) {
883a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     free(screen);
884a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat     return NULL;
885a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   }
886a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
887a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef WIN32
888a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   {
889a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	   DWORD dummy=255;
890a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	   GetComputerName(screen->thisHost,&dummy);
891a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   }
892a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
893a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   gethostname(screen->thisHost, 255);
894a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
895a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
896a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->paddedWidthInBytes = width*bytesPerPixel;
897a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
898a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   /* format */
899a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
900a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   rfbInitServerFormat(screen, bitsPerSample);
901a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
902a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   /* cursor */
903a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
904a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->cursorX=screen->cursorY=screen->underCursorBufferLen=0;
905a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->underCursorBuffer=NULL;
906a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->dontConvertRichCursorToXCursor = FALSE;
907a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->cursor = &myCursor;
908a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   INIT_MUTEX(screen->cursorMutex);
909a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
910a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   IF_PTHREADS(screen->backgroundLoop = FALSE);
911a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
912a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   /* proc's and hook's */
913a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
914a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->kbdAddEvent = rfbDefaultKbdAddEvent;
915a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->kbdReleaseAllKeys = rfbDoNothingWithClient;
916a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->ptrAddEvent = rfbDefaultPtrAddEvent;
917a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->setXCutText = rfbDefaultSetXCutText;
918a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->getCursorPtr = rfbDefaultGetCursorPtr;
919a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->setTranslateFunction = rfbSetTranslateFunction;
920a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->newClientHook = rfbDefaultNewClientHook;
921a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->displayHook = NULL;
922a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->displayFinishedHook = NULL;
923a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->getKeyboardLedStateHook = NULL;
924a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   screen->xvpHook = NULL;
925a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
926a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   /* initialize client list and iterator mutex */
927a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   rfbClientListInit(screen);
928a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
929a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   return(screen);
930a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
931a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
932a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
933a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Switch to another framebuffer (maybe of different size and color
934a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * format). Clients supporting NewFBSize pseudo-encoding will change
935a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * their local framebuffer dimensions if necessary.
936a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * NOTE: Rich cursor data should be converted to new pixel format by
937a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the caller.
938a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
939a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
940a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbNewFramebuffer(rfbScreenInfoPtr screen, char *framebuffer,
941a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                       int width, int height,
942a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                       int bitsPerSample, int samplesPerPixel,
943a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                       int bytesPerPixel)
944a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
945a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbPixelFormat old_format;
946a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbBool format_changed = FALSE;
947a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientIteratorPtr iterator;
948a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientPtr cl;
949a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
950a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* Update information in the screenInfo structure */
951a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
952a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  old_format = screen->serverFormat;
953a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
954a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (width & 3)
955a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbErr("WARNING: New width (%d) is not a multiple of 4.\n", width);
956a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
957a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  screen->width = width;
958a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  screen->height = height;
959a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  screen->bitsPerPixel = screen->depth = 8*bytesPerPixel;
960a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  screen->paddedWidthInBytes = width*bytesPerPixel;
961a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
962a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbInitServerFormat(screen, bitsPerSample);
963a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
964a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (memcmp(&screen->serverFormat, &old_format,
965a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat             sizeof(rfbPixelFormat)) != 0) {
966a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    format_changed = TRUE;
967a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
968a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
969a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  screen->frameBuffer = framebuffer;
970a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
971a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* Adjust pointer position if necessary */
972a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
973a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (screen->cursorX >= width)
974a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    screen->cursorX = width - 1;
975a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (screen->cursorY >= height)
976a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    screen->cursorY = height - 1;
977a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
978a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* For each client: */
979a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  iterator = rfbGetClientIterator(screen);
980a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  while ((cl = rfbClientIteratorNext(iterator)) != NULL) {
981a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
982a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* Re-install color translation tables if necessary */
983a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
984a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (format_changed)
985a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      screen->setTranslateFunction(cl);
986a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
987a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    /* Mark the screen contents as changed, and schedule sending
988a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       NewFBSize message if supported by this client. */
989a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
990a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    LOCK(cl->updateMutex);
991a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    sraRgnDestroy(cl->modifiedRegion);
992a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    cl->modifiedRegion = sraRgnCreateRect(0, 0, width, height);
993a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    sraRgnMakeEmpty(cl->copyRegion);
994a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    cl->copyDX = 0;
995a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    cl->copyDY = 0;
996a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
997a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (cl->useNewFBSize)
998a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      cl->newFBSizePending = TRUE;
999a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1000a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    TSIGNAL(cl->updateCond);
1001a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    UNLOCK(cl->updateMutex);
1002a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1003a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbReleaseClientIterator(iterator);
1004a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1005a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1006a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* hang up on all clients and free all reserved memory */
1007a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1008a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbScreenCleanup(rfbScreenInfoPtr screen)
1009a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1010a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientIteratorPtr i=rfbGetClientIterator(screen);
1011a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientPtr cl,cl1=rfbClientIteratorNext(i);
1012a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  while(cl1) {
1013a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    cl=rfbClientIteratorNext(i);
1014a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientConnectionGone(cl1);
1015a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    cl1=cl;
1016a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1017a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbReleaseClientIterator(i);
1018a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1019a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define FREE_IF(x) if(screen->x) free(screen->x)
1020a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  FREE_IF(colourMap.data.bytes);
1021a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  FREE_IF(underCursorBuffer);
1022a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  TINI_MUTEX(screen->cursorMutex);
1023a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if(screen->cursor && screen->cursor->cleanup)
1024a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbFreeCursor(screen->cursor);
1025a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1026a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ
1027a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbZlibCleanup(screen);
1028a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG
1029a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbTightCleanup(screen);
1030a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1031a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1032a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  /* free all 'scaled' versions of this screen */
1033a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  while (screen->scaledScreenNext!=NULL)
1034a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  {
1035a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbScreenInfoPtr ptr;
1036a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      ptr = screen->scaledScreenNext;
1037a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      screen->scaledScreenNext = ptr->scaledScreenNext;
1038a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      free(ptr->frameBuffer);
1039a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      free(ptr);
1040a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1041a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1042a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1043a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  free(screen);
1044a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1045a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1046a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbInitServer(rfbScreenInfoPtr screen)
1047a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1048a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef WIN32
1049a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  WSADATA trash;
1050a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  WSAStartup(MAKEWORD(2,2),&trash);
1051a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1052a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbInitSockets(screen);
1053a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbHttpInitSockets(screen);
1054a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifndef __MINGW32__
1055a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if(screen->ignoreSIGPIPE)
1056a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    signal(SIGPIPE,SIG_IGN);
1057a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1058a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1059a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1060a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbShutdownServer(rfbScreenInfoPtr screen,rfbBool disconnectClients) {
1061a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if(disconnectClients) {
1062a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientPtr cl;
1063a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbClientIteratorPtr iter = rfbGetClientIterator(screen);
1064a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    while( (cl = rfbClientIteratorNext(iter)) )
1065a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if (cl->sock > -1)
1066a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* we don't care about maxfd here, because the server goes away */
1067a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rfbCloseClient(cl);
1068a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbReleaseClientIterator(iter);
1069a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1070a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1071a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbShutdownSockets(screen);
1072a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbHttpShutdownSockets(screen);
1073a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1074a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1075a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifndef LIBVNCSERVER_HAVE_GETTIMEOFDAY
1076a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <fcntl.h>
1077a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <conio.h>
1078a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <sys/timeb.h>
1079a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1080a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid gettimeofday(struct timeval* tv,char* dummy)
1081a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1082a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   SYSTEMTIME t;
1083a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   GetSystemTime(&t);
1084a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   tv->tv_sec=t.wHour*3600+t.wMinute*60+t.wSecond;
1085a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   tv->tv_usec=t.wMilliseconds*1000;
1086a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1087a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1088a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1089a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool
1090a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbProcessEvents(rfbScreenInfoPtr screen,long usec)
1091a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1092a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientIteratorPtr i;
1093a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbClientPtr cl,clPrev;
1094a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbBool result=FALSE;
1095a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  extern rfbClientIteratorPtr
1096a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbGetClientIteratorWithClosed(rfbScreenInfoPtr rfbScreen);
1097a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1098a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if(usec<0)
1099a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    usec=screen->deferUpdateTime*1000;
1100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbCheckFds(screen,usec);
1102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbHttpCheckFds(screen);
1103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  i = rfbGetClientIteratorWithClosed(screen);
1105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  cl=rfbClientIteratorHead(i);
1106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  while(cl) {
1107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    result = rfbUpdateClient(cl);
1108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    clPrev=cl;
1109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    cl=rfbClientIteratorNext(i);
1110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if(clPrev->sock==-1) {
1111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      rfbClientConnectionGone(clPrev);
1112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      result=TRUE;
1113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
1114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbReleaseClientIterator(i);
1116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return result;
1118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool
1121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbUpdateClient(rfbClientPtr cl)
1122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  struct timeval tv;
1124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbBool result=FALSE;
1125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  rfbScreenInfoPtr screen = cl->screen;
1126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if (cl->sock >= 0 && !cl->onHold && FB_UPDATE_PENDING(cl) &&
1128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        !sraRgnEmpty(cl->requestedRegion)) {
1129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      result=TRUE;
1130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if(screen->deferUpdateTime == 0) {
1131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          rfbSendFramebufferUpdate(cl,cl->modifiedRegion);
1132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else if(cl->startDeferring.tv_usec == 0) {
1133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        gettimeofday(&cl->startDeferring,NULL);
1134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if(cl->startDeferring.tv_usec == 0)
1135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          cl->startDeferring.tv_usec++;
1136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else {
1137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        gettimeofday(&tv,NULL);
1138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if(tv.tv_sec < cl->startDeferring.tv_sec /* at midnight */
1139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat           || ((tv.tv_sec-cl->startDeferring.tv_sec)*1000
1140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat               +(tv.tv_usec-cl->startDeferring.tv_usec)/1000)
1141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat             > screen->deferUpdateTime) {
1142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          cl->startDeferring.tv_usec = 0;
1143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          rfbSendFramebufferUpdate(cl,cl->modifiedRegion);
1144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        }
1145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
1146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
1147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    if (!cl->viewOnly && cl->lastPtrX >= 0) {
1149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      if(cl->startPtrDeferring.tv_usec == 0) {
1150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        gettimeofday(&cl->startPtrDeferring,NULL);
1151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if(cl->startPtrDeferring.tv_usec == 0)
1152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          cl->startPtrDeferring.tv_usec++;
1153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      } else {
1154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        struct timeval tv;
1155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        gettimeofday(&tv,NULL);
1156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        if(tv.tv_sec < cl->startPtrDeferring.tv_sec /* at midnight */
1157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat           || ((tv.tv_sec-cl->startPtrDeferring.tv_sec)*1000
1158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat           +(tv.tv_usec-cl->startPtrDeferring.tv_usec)/1000)
1159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat           > cl->screen->deferPtrUpdateTime) {
1160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          cl->startPtrDeferring.tv_usec = 0;
1161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          cl->screen->ptrAddEvent(cl->lastPtrButtons,
1162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                                  cl->lastPtrX,
1163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat                                  cl->lastPtrY, cl);
1164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat          cl->lastPtrX = -1;
1165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat        }
1166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat      }
1167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    }
1168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return result;
1170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool rfbIsActive(rfbScreenInfoPtr screenInfo) {
1173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  return screenInfo->socketState!=RFB_SOCKET_SHUTDOWN || screenInfo->clientHead!=NULL;
1174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbRunEventLoop(rfbScreenInfoPtr screen, long usec, rfbBool runInBackground)
1177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{
1178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if(runInBackground) {
1179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
1180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       pthread_t listener_thread;
1181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       screen->backgroundLoop = TRUE;
1183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat       pthread_create(&listener_thread, NULL, listenerRun, screen);
1185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return;
1186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
1187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbErr("Can't run in background, because I don't have PThreads!\n");
1188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    return;
1189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
1190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  }
1191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  if(usec<0)
1193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    usec=screen->deferUpdateTime*1000;
1194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
1195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat  while(rfbIsActive(screen))
1196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    rfbProcessEvents(screen,usec);
1197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
1198