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