rfbserver.c revision 1d80c6a8d34f59543f7df1963c22d7efa292bcb0
1a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 2a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbserver.c - deal with server-side of the RFB protocol. 3a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 4a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 5a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 6a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Copyright (C) 2011-2012 D. R. Commander 7a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Copyright (C) 2005 Rohit Kumar, Johannes E. Schindelin 8a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Copyright (C) 2002 RealVNC Ltd. 9a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>. 10a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. 11a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * All Rights Reserved. 12a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 13a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This is free software; you can redistribute it and/or modify 14a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * it under the terms of the GNU General Public License as published by 15a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the Free Software Foundation; either version 2 of the License, or 16a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * (at your option) any later version. 17a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 18a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This software is distributed in the hope that it will be useful, 19a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * but WITHOUT ANY WARRANTY; without even the implied warranty of 20a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * GNU General Public License for more details. 22a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 23a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * You should have received a copy of the GNU General Public License 24a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * along with this software; if not, write to the Free Software 25a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 26a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * USA. 27a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 28a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 29a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef __STRICT_ANSI__ 30a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define _BSD_SOURCE 311d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#define _POSIX_SOURCE 321d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#define _XOPEN_SOURCE 600 33a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 341d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman 351d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#include <stdio.h> 36a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <string.h> 37a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <rfb/rfb.h> 38a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <rfb/rfbregion.h> 39a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "private.h" 40a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 41a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_FCNTL_H 42a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <fcntl.h> 43a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 44a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 45a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef WIN32 461d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#include <winsock2.h> 471d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#include <ws2tcpip.h> 481d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#include <io.h> 49a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define write(sock,buf,len) send(sock,buf,len,0) 50a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 51a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_UNISTD_H 52a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <unistd.h> 53a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 54a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <pwd.h> 55a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_SYS_SOCKET_H 56a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <sys/socket.h> 57a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 58a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_NETINET_IN_H 59a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <netinet/in.h> 60a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <netinet/tcp.h> 61a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <netdb.h> 62a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <arpa/inet.h> 63a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 64a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 65a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 66a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef DEBUGPROTO 67a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef DEBUGPROTO 68a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define DEBUGPROTO(x) x 69a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 70a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define DEBUGPROTO(x) 71a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 72a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <stdarg.h> 73a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <scale.h> 74a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* stst() */ 75a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <sys/types.h> 76a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <sys/stat.h> 77a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <unistd.h> 781d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman 791d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#ifndef WIN32 80a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* readdir() */ 81a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <dirent.h> 821d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif 831d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman 84a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* errno */ 85a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <errno.h> 86a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* strftime() */ 87a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <time.h> 88a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 89a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_WITH_WEBSOCKETS 90a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "rfbssl.h" 91a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 92a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 931d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#ifdef _MSC_VER 941d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#define snprintf _snprintf /* Missing in MSVC */ 951d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman/* Prevent POSIX deprecation warnings */ 961d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#define close _close 971d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#define strdup _strdup 981d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif 991d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman 1001d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#ifdef WIN32 101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef __MINGW32__ 1021d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#define mkdir(path, perms) mkdir(path) /* Omit the perms argument to match POSIX signature */ 1031d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#else /* MSVC and other windows compilers */ 1041d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#define mkdir(path, perms) _mkdir(path) /* Omit the perms argument to match POSIX signature */ 1051d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif /* __MINGW32__ else... */ 1061d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#define S_ISDIR(m) (((m) & S_IFDIR) == S_IFDIR) 1071d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#include <direct.h> 108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG 111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Map of quality levels to provide compatibility with TightVNC/TigerVNC 113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * clients. This emulates the behavior of the TigerVNC Server. 114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic const int tight2turbo_qual[10] = { 117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 15, 29, 41, 42, 62, 77, 79, 86, 92, 100 118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}; 119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic const int tight2turbo_subsamp[10] = { 121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1, 1, 1, 2, 2, 2, 0, 0, 0, 0 122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}; 123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void rfbProcessClientProtocolVersion(rfbClientPtr cl); 126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void rfbProcessClientNormalMessage(rfbClientPtr cl); 127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void rfbProcessClientInitMessage(rfbClientPtr cl); 128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD 130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbIncrClientRef(rfbClientPtr cl) 131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(cl->refCountMutex); 133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->refCount++; 134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->refCountMutex); 135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbDecrClientRef(rfbClientPtr cl) 138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(cl->refCountMutex); 140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->refCount--; 141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(cl->refCount<=0) /* just to be sure also < 0 */ 142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat TSIGNAL(cl->deleteCond); 143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->refCountMutex); 144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbIncrClientRef(rfbClientPtr cl) {} 147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid rfbDecrClientRef(rfbClientPtr cl) {} 148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD 151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic MUTEX(rfbClientListMutex); 152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstruct rfbClientIterator { 155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientPtr next; 156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreenInfoPtr screen; 157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbBool closedToo; 158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}; 159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbClientListInit(rfbScreenInfoPtr rfbScreen) 162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(sizeof(rfbBool)!=1) { 164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* a sanity check */ 165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fprintf(stderr,"rfbBool's size is not 1 (%d)!\n",(int)sizeof(rfbBool)); 166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* we cannot continue, because rfbBool is supposed to be char everywhere */ 167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat exit(1); 168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreen->clientHead = NULL; 170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat INIT_MUTEX(rfbClientListMutex); 171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbClientIteratorPtr 174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbGetClientIterator(rfbScreenInfoPtr rfbScreen) 175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientIteratorPtr i = 177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (rfbClientIteratorPtr)malloc(sizeof(struct rfbClientIterator)); 178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i->next = NULL; 179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i->screen = rfbScreen; 180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i->closedToo = FALSE; 181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return i; 182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbClientIteratorPtr 185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbGetClientIteratorWithClosed(rfbScreenInfoPtr rfbScreen) 186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientIteratorPtr i = 188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (rfbClientIteratorPtr)malloc(sizeof(struct rfbClientIterator)); 189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i->next = NULL; 190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i->screen = rfbScreen; 191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i->closedToo = TRUE; 192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return i; 193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbClientPtr 196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbClientIteratorHead(rfbClientIteratorPtr i) 197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD 199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(i->next != 0) { 200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbDecrClientRef(i->next); 201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbIncrClientRef(i->screen->clientHead); 202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(rfbClientListMutex); 205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i->next = i->screen->clientHead; 206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(rfbClientListMutex); 207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return i->next; 208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbClientPtr 211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbClientIteratorNext(rfbClientIteratorPtr i) 212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(i->next == 0) { 214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(rfbClientListMutex); 215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i->next = i->screen->clientHead; 216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(rfbClientListMutex); 217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat IF_PTHREADS(rfbClientPtr cl = i->next); 219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i->next = i->next->next; 220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat IF_PTHREADS(rfbDecrClientRef(cl)); 221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD 224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(!i->closedToo) 225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while(i->next && i->next->sock<0) 226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i->next = i->next->next; 227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(i->next) 228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbIncrClientRef(i->next); 229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return i->next; 232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbReleaseClientIterator(rfbClientIteratorPtr iterator) 236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat IF_PTHREADS(if(iterator->next) rfbDecrClientRef(iterator->next)); 238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(iterator); 239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbNewClientConnection is called from sockets.c when a new connection 244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * comes in. 245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbNewClientConnection(rfbScreenInfoPtr rfbScreen, 249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int sock) 250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbNewClient(rfbScreen,sock); 252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbReverseConnection is called to make an outward 257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * connection to a "listening" RFB client. 258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbClientPtr 261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbReverseConnection(rfbScreenInfoPtr rfbScreen, 262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *host, 263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int port) 264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int sock; 266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientPtr cl; 267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((sock = rfbConnect(rfbScreen, host, port)) < 0) 269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return (rfbClientPtr)NULL; 270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl = rfbNewClient(rfbScreen, sock); 272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl) { 274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->reverseConnection = TRUE; 275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return cl; 278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbSetProtocolVersion(rfbScreenInfoPtr rfbScreen, int major_, int minor_) 283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Permit the server to set the version to report */ 285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* TODO: sanity checking */ 286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((major_==3) && (minor_ > 2 && minor_ < 9)) 287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreen->protocolMajorVersion = major_; 289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreen->protocolMinorVersion = minor_; 290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbSetProtocolVersion(%d,%d) set to invalid values\n", major_, minor_); 293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbNewClient is called when a new connection has been made by whatever 297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * means. 298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbClientPtr 301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen, 302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int sock, 303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbBool isUDP) 304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbProtocolVersionMsg pv; 306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientIteratorPtr iterator; 307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientPtr cl,cl_; 308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_IPv6 309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct sockaddr_storage addr; 310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct sockaddr_in addr; 312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat socklen_t addrlen = sizeof(addr); 314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbProtocolExtension* extension; 315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl = (rfbClientPtr)calloc(sizeof(rfbClientRec),1); 317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen = rfbScreen; 319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->sock = sock; 320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->viewOnly = FALSE; 321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* setup pseudo scaling */ 322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->scaledScreen = rfbScreen; 323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->scaledScreen->scaledScreenRefCount++; 324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbResetStats(cl); 326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->clientData = NULL; 328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->clientGoneHook = rfbDoNothingWithClient; 329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(isUDP) { 331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" accepted UDP client\n"); 3321d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman } else { 3331d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#ifdef LIBVNCSERVER_IPv6 3341d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman char host[1024]; 3351d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif 336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int one=1; 337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat getpeername(sock, (struct sockaddr *)&addr, &addrlen); 339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_IPv6 340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(getnameinfo((struct sockaddr*)&addr, addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST) != 0) { 341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbNewClient: error in getnameinfo"); 342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->host = strdup(""); 343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->host = strdup(host); 346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->host = strdup(inet_ntoa(addr.sin_addr)); 348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" other clients:\n"); 351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat iterator = rfbGetClientIterator(rfbScreen); 352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while ((cl_ = rfbClientIteratorNext(iterator)) != NULL) { 353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" %s\n",cl_->host); 354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbReleaseClientIterator(iterator); 356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(!rfbSetNonBlocking(sock)) { 358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(sock); 359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return NULL; 360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, 363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (char *)&one, sizeof(one)) < 0) { 364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("setsockopt failed"); 365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(sock); 366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return NULL; 367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FD_SET(sock,&(rfbScreen->allFds)); 370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreen->maxFd = max(sock,rfbScreen->maxFd); 371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat INIT_MUTEX(cl->outputMutex); 373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat INIT_MUTEX(cl->refCountMutex); 374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat INIT_MUTEX(cl->sendMutex); 375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat INIT_COND(cl->deleteCond); 376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->state = RFB_PROTOCOL_VERSION; 378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->reverseConnection = FALSE; 380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->readyForSetColourMapEntries = FALSE; 381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->useCopyRect = FALSE; 382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->preferredEncoding = -1; 383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->correMaxWidth = 48; 384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->correMaxHeight = 48; 385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ 386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->zrleData = NULL; 387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->copyRegion = sraRgnCreate(); 390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->copyDX = 0; 391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->copyDY = 0; 392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->modifiedRegion = 394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnCreateRect(0,0,rfbScreen->width,rfbScreen->height); 395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat INIT_MUTEX(cl->updateMutex); 397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat INIT_COND(cl->updateCond); 398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->requestedRegion = sraRgnCreate(); 400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->format = cl->screen->serverFormat; 402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->translateFn = rfbTranslateNone; 403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->translateLookupTable = NULL; 404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(rfbClientListMutex); 406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat IF_PTHREADS(cl->refCount = 0); 408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->next = rfbScreen->clientHead; 409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->prev = NULL; 410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbScreen->clientHead) 411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreen->clientHead->prev = cl; 412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreen->clientHead = cl; 414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(rfbClientListMutex); 415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if defined(LIBVNCSERVER_HAVE_LIBZ) || defined(LIBVNCSERVER_HAVE_LIBPNG) 417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->tightQualityLevel = -1; 418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG 419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->tightCompressLevel = TIGHT_DEFAULT_COMPRESSION; 420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->turboSubsampLevel = TURBO_DEFAULT_SUBSAMP; 421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i; 423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < 4; i++) 424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->zsActive[i] = FALSE; 425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.fd = -1; 430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableCursorShapeUpdates = FALSE; 432a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableCursorPosUpdates = FALSE; 433a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->useRichCursorEncoding = FALSE; 434a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableLastRectEncoding = FALSE; 435a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableKeyboardLedState = FALSE; 436a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableSupportedMessages = FALSE; 437a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableSupportedEncodings = FALSE; 438a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableServerIdentity = FALSE; 439a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->lastKeyboardLedState = -1; 440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->cursorX = rfbScreen->cursorX; 441a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->cursorY = rfbScreen->cursorY; 442a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->useNewFBSize = FALSE; 443a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 444a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ 445a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->compStreamInited = FALSE; 446a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->compStream.total_in = 0; 447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->compStream.total_out = 0; 448a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->compStream.zalloc = Z_NULL; 449a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->compStream.zfree = Z_NULL; 450a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->compStream.opaque = Z_NULL; 451a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 452a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->zlibCompressLevel = 5; 453a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 454a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 455a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->progressiveSliceY = 0; 456a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 457a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->extensions = NULL; 458a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 459a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->lastPtrX = -1; 460a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 461a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_WITH_WEBSOCKETS 462a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 463a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Wait a few ms for the client to send one of: 464a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * - Flash policy request 465a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * - WebSockets connection (TLS/SSL or plain) 466a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 467a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!webSocketsCheck(cl)) { 468a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Error reporting handled in webSocketsHandshake */ 469a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 470a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientConnectionGone(cl); 471a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return NULL; 472a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 473a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 474a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 475a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sprintf(pv,rfbProtocolVersionFormat,rfbScreen->protocolMajorVersion, 476a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreen->protocolMinorVersion); 477a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 478a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, pv, sz_rfbProtocolVersionMsg) < 0) { 479a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbNewClient: write"); 480a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 481a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientConnectionGone(cl); 482a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return NULL; 483a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 484a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 485a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 486a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(extension = rfbGetExtensionIterator(); extension; 487a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat extension=extension->next) { 488a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat void* data = NULL; 489a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* if the extension does not have a newClient method, it wants 490a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * to be initialized later. */ 491a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(extension->newClient && extension->newClient(cl, &data)) 492a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEnableExtension(cl, extension, data); 493a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 494a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbReleaseExtensionIterator(); 495a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 496a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat switch (cl->screen->newClientHook(cl)) { 497a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case RFB_CLIENT_ON_HOLD: 498a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->onHold = TRUE; 499a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 500a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case RFB_CLIENT_ACCEPT: 501a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->onHold = FALSE; 502a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 503a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case RFB_CLIENT_REFUSE: 504a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 505a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientConnectionGone(cl); 506a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl = NULL; 507a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 508a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 509a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return cl; 510a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 511a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 512a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbClientPtr 513a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbNewClient(rfbScreenInfoPtr rfbScreen, 514a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int sock) 515a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 516a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return(rfbNewTCPOrUDPClient(rfbScreen,sock,FALSE)); 517a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 518a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 519a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbClientPtr 520a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbNewUDPClient(rfbScreenInfoPtr rfbScreen) 521a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 522a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return((rfbScreen->udpClient= 523a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbNewTCPOrUDPClient(rfbScreen,rfbScreen->udpSock,TRUE))); 524a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 525a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 526a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 527a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbClientConnectionGone is called from sockets.c just after a connection 528a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * has gone away. 529a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 530a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 531a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 532a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbClientConnectionGone(rfbClientPtr cl) 533a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 534a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if defined(LIBVNCSERVER_HAVE_LIBZ) && defined(LIBVNCSERVER_HAVE_LIBJPEG) 535a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i; 536a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 537a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 538a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(rfbClientListMutex); 539a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 540a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->prev) 541a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->prev->next = cl->next; 542a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 543a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->clientHead = cl->next; 544a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->next) 545a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->next->prev = cl->prev; 546a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 547a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(rfbClientListMutex); 548a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 549a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD 550a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(cl->screen->backgroundLoop != FALSE) { 551a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i; 552a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat do { 553a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(cl->refCountMutex); 554a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i=cl->refCount; 555a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(i>0) 556a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat WAIT(cl->deleteCond,cl->refCountMutex); 557a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->refCountMutex); 558a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } while(i>0); 559a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 560a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 561a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 562a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(cl->sock>=0) 563a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(cl->sock); 564a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 565a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->scaledScreen!=NULL) 566a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->scaledScreen->scaledScreenRefCount--; 567a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 568a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ 569a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbFreeZrleData(cl); 570a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 571a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 572a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbFreeUltraData(cl); 573a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 574a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* free buffers holding pixel data before and after encoding */ 575a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(cl->beforeEncBuf); 576a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(cl->afterEncBuf); 577a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 578a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(cl->sock>=0) 579a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FD_CLR(cl->sock,&(cl->screen->allFds)); 580a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 581a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->clientGoneHook(cl); 582a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 583a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Client %s gone\n",cl->host); 584a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(cl->host); 585a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 586a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ 587a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Release the compression state structures if any. */ 588a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( cl->compStreamInited ) { 589a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat deflateEnd( &(cl->compStream) ); 590a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 591a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 592a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG 593a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < 4; i++) { 594a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->zsActive[i]) 595a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat deflateEnd(&cl->zsStruct[i]); 596a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 597a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 598a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 599a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 600a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->screen->pointerClient == cl) 601a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->pointerClient = NULL; 602a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 603a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnDestroy(cl->modifiedRegion); 604a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnDestroy(cl->requestedRegion); 605a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnDestroy(cl->copyRegion); 606a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 607a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->translateLookupTable) free(cl->translateLookupTable); 608a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 609a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat TINI_COND(cl->updateCond); 610a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat TINI_MUTEX(cl->updateMutex); 611a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 612a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* make sure outputMutex is unlocked before destroying */ 613a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(cl->outputMutex); 614a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->outputMutex); 615a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat TINI_MUTEX(cl->outputMutex); 616a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 617a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(cl->sendMutex); 618a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->sendMutex); 619a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat TINI_MUTEX(cl->sendMutex); 620a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 621a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbPrintStats(cl); 622a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbResetStats(cl); 623a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 624a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(cl); 625a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 626a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 627a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 628a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 629a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbProcessClientMessage is called when there is data to read from a client. 630a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 631a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 632a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 633a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbProcessClientMessage(rfbClientPtr cl) 634a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 635a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat switch (cl->state) { 636a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case RFB_PROTOCOL_VERSION: 637a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbProcessClientProtocolVersion(cl); 638a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 639a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case RFB_SECURITY_TYPE: 640a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbProcessClientSecurityType(cl); 641a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 642a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case RFB_AUTHENTICATION: 643a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbAuthProcessClientMessage(cl); 644a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 645a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case RFB_INITIALISATION: 646a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case RFB_INITIALISATION_SHARED: 647a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbProcessClientInitMessage(cl); 648a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 649a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat default: 650a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbProcessClientNormalMessage(cl); 651a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 652a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 653a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 654a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 655a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 656a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 657a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbProcessClientProtocolVersion is called when the client sends its 658a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * protocol version. 659a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 660a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 661a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void 662a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbProcessClientProtocolVersion(rfbClientPtr cl) 663a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 664a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbProtocolVersionMsg pv; 665a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int n, major_, minor_; 666a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 667a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, pv, sz_rfbProtocolVersionMsg)) <= 0) { 668a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n == 0) 669a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessClientProtocolVersion: client gone\n"); 670a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 671a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientProtocolVersion: read"); 672a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 673a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 674a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 675a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 676a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat pv[sz_rfbProtocolVersionMsg] = 0; 677a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sscanf(pv,rfbProtocolVersionFormat,&major_,&minor_) != 2) { 678a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbErr("rfbProcessClientProtocolVersion: not a valid RFB client: %s\n", pv); 679a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 680a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 681a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 682a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Client Protocol Version %d.%d\n", major_, minor_); 683a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 684a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (major_ != rfbProtocolMajorVersion) { 685a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbErr("RFB protocol version mismatch - server %d.%d, client %d.%d", 686a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->protocolMajorVersion, cl->screen->protocolMinorVersion, 687a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat major_,minor_); 688a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 689a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 690a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 691a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 692a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Check for the minor version use either of the two standard version of RFB */ 693a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 694a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * UltraVNC Viewer detects FileTransfer compatible servers via rfb versions 695a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 3.4, 3.6, 3.14, 3.16 696a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * It's a bad method, but it is what they use to enable features... 697a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * maintaining RFB version compatibility across multiple servers is a pain 698a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Should use something like ServerIdentity encoding 699a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 700a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->protocolMajorVersion = major_; 701a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->protocolMinorVersion = minor_; 702a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 703a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Protocol version sent %d.%d, using %d.%d\n", 704a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat major_, minor_, rfbProtocolMajorVersion, cl->protocolMinorVersion); 705a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 706a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbAuthNewClient(cl); 707a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 708a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 709a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 710a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 711a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbClientSendString(rfbClientPtr cl, const char *reason) 712a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 713a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *buf; 714a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int len = strlen(reason); 715a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 716a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbClientSendString(\"%s\")\n", reason); 717a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 718a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buf = (char *)malloc(4 + len); 719a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ((uint32_t *)buf)[0] = Swap32IfLE(len); 720a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy(buf + 4, reason, len); 721a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 722a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, buf, 4 + len) < 0) 723a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbClientSendString: write"); 724a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(buf); 725a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 726a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 727a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 728a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 729a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 730a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbClientConnFailed is called when a client connection has failed either 731a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * because it talks the wrong protocol or it has failed authentication. 732a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 733a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 734a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 735a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbClientConnFailed(rfbClientPtr cl, 736a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat const char *reason) 737a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 738a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *buf; 739a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int len = strlen(reason); 740a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 741a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbClientConnFailed(\"%s\")\n", reason); 742a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 743a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buf = (char *)malloc(8 + len); 744a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ((uint32_t *)buf)[0] = Swap32IfLE(rfbConnFailed); 745a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ((uint32_t *)buf)[1] = Swap32IfLE(len); 746a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy(buf + 8, reason, len); 747a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 748a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, buf, 8 + len) < 0) 749a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbClientConnFailed: write"); 750a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(buf); 751a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 752a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 753a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 754a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 755a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 756a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 757a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbProcessClientInitMessage is called when the client sends its 758a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * initialisation message. 759a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 760a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 761a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void 762a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbProcessClientInitMessage(rfbClientPtr cl) 763a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 764a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientInitMsg ci; 765a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat union { 766a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char buf[256]; 767a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbServerInitMsg si; 768a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } u; 769a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int len, n; 770a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientIteratorPtr iterator; 771a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientPtr otherCl; 772a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbExtensionData* extension; 773a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 774a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->state == RFB_INITIALISATION_SHARED) { 775a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* In this case behave as though an implicit ClientInit message has 776a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * already been received with a shared-flag of true. */ 777a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ci.shared = 1; 778a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Avoid the possibility of exposing the RFB_INITIALISATION_SHARED 779a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * state to calling software. */ 780a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->state = RFB_INITIALISATION; 781a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 782a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, (char *)&ci,sz_rfbClientInitMsg)) <= 0) { 783a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n == 0) 784a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessClientInitMessage: client gone\n"); 785a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 786a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientInitMessage: read"); 787a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 788a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 789a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 790a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 791a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 792a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memset(u.buf,0,sizeof(u.buf)); 793a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 794a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat u.si.framebufferWidth = Swap16IfLE(cl->screen->width); 795a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat u.si.framebufferHeight = Swap16IfLE(cl->screen->height); 796a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat u.si.format = cl->screen->serverFormat; 797a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat u.si.format.redMax = Swap16IfLE(u.si.format.redMax); 798a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat u.si.format.greenMax = Swap16IfLE(u.si.format.greenMax); 799a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat u.si.format.blueMax = Swap16IfLE(u.si.format.blueMax); 800a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 801a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat strncpy(u.buf + sz_rfbServerInitMsg, cl->screen->desktopName, 127); 802a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat len = strlen(u.buf + sz_rfbServerInitMsg); 803a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat u.si.nameLength = Swap32IfLE(len); 804a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 805a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, u.buf, sz_rfbServerInitMsg + len) < 0) { 806a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientInitMessage: write"); 807a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 808a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 809a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 810a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 811a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(extension = cl->extensions; extension;) { 812a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbExtensionData* next = extension->next; 813a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(extension->extension->init && 814a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat !extension->extension->init(cl, extension->data)) 815a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* extension requested that it be removed */ 816a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbDisableExtension(cl, extension->extension); 817a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat extension = next; 818a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 819a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 820a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->state = RFB_NORMAL; 821a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 822a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!cl->reverseConnection && 823a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (cl->screen->neverShared || (!cl->screen->alwaysShared && !ci.shared))) { 824a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 825a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->screen->dontDisconnect) { 826a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat iterator = rfbGetClientIterator(cl->screen); 827a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while ((otherCl = rfbClientIteratorNext(iterator)) != NULL) { 828a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((otherCl != cl) && (otherCl->state == RFB_NORMAL)) { 829a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("-dontdisconnect: Not shared & existing client\n"); 830a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" refusing new client %s\n", cl->host); 831a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 832a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbReleaseClientIterator(iterator); 833a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 834a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 835a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 836a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbReleaseClientIterator(iterator); 837a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 838a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat iterator = rfbGetClientIterator(cl->screen); 839a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while ((otherCl = rfbClientIteratorNext(iterator)) != NULL) { 840a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((otherCl != cl) && (otherCl->state == RFB_NORMAL)) { 841a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Not shared - closing connection to client %s\n", 842a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat otherCl->host); 843a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(otherCl); 844a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 845a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 846a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbReleaseClientIterator(iterator); 847a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 848a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 849a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 850a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 851a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* The values come in based on the scaled screen, we need to convert them to 852a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * values based on the man screen's coordinate system 853a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 854a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool rectSwapIfLEAndClip(uint16_t* x,uint16_t* y,uint16_t* w,uint16_t* h, 855a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientPtr cl) 856a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 857a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int x1=Swap16IfLE(*x); 858a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int y1=Swap16IfLE(*y); 859a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int w1=Swap16IfLE(*w); 860a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int h1=Swap16IfLE(*h); 861a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 862a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScaledCorrection(cl->scaledScreen, cl->screen, &x1, &y1, &w1, &h1, "rectSwapIfLEAndClip"); 863a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *x = x1; 864a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *y = y1; 865a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *w = w1; 866a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *h = h1; 867a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 868a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(*w>cl->screen->width-*x) 869a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *w=cl->screen->width-*x; 870a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* possible underflow */ 871a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(*w>cl->screen->width-*x) 872a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 873a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(*h>cl->screen->height-*y) 874a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *h=cl->screen->height-*y; 875a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(*h>cl->screen->height-*y) 876a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 877a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 878a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 879a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 880a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 881a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 882a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Send keyboard state (PointerPos pseudo-encoding). 883a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 884a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 885a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool 886a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbSendKeyboardLedState(rfbClientPtr cl) 887a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 888a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbFramebufferUpdateRectHeader rect; 889a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 890a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) { 891a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendUpdateBuf(cl)) 892a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 893a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 894a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 895a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.encoding = Swap32IfLE(rfbEncodingKeyboardLedState); 896a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.x = Swap16IfLE(cl->lastKeyboardLedState); 897a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.y = 0; 898a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.w = 0; 899a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.h = 0; 900a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 901a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy(&cl->updateBuf[cl->ublen], (char *)&rect, 902a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbFramebufferUpdateRectHeader); 903a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->ublen += sz_rfbFramebufferUpdateRectHeader; 904a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 905a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordEncodingSent(cl, rfbEncodingKeyboardLedState, sz_rfbFramebufferUpdateRectHeader, sz_rfbFramebufferUpdateRectHeader); 906a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 907a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendUpdateBuf(cl)) 908a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 909a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 910a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 911a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 912a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 913a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 914a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define rfbSetBit(buffer, position) (buffer[(position & 255) / 8] |= (1 << (position % 8))) 915a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 916a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 917a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Send rfbEncodingSupportedMessages. 918a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 919a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 920a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool 921a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbSendSupportedMessages(rfbClientPtr cl) 922a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 923a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbFramebufferUpdateRectHeader rect; 924a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSupportedMessages msgs; 925a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 926a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->ublen + sz_rfbFramebufferUpdateRectHeader 927a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat + sz_rfbSupportedMessages > UPDATE_BUF_SIZE) { 928a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendUpdateBuf(cl)) 929a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 930a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 931a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 932a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.encoding = Swap32IfLE(rfbEncodingSupportedMessages); 933a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.x = 0; 934a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.y = 0; 935a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.w = Swap16IfLE(sz_rfbSupportedMessages); 936a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.h = 0; 937a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 938a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy(&cl->updateBuf[cl->ublen], (char *)&rect, 939a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbFramebufferUpdateRectHeader); 940a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->ublen += sz_rfbFramebufferUpdateRectHeader; 941a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 942a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memset((char *)&msgs, 0, sz_rfbSupportedMessages); 943a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetBit(msgs.client2server, rfbSetPixelFormat); 944a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetBit(msgs.client2server, rfbFixColourMapEntries); 945a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetBit(msgs.client2server, rfbSetEncodings); 946a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetBit(msgs.client2server, rfbFramebufferUpdateRequest); 947a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetBit(msgs.client2server, rfbKeyEvent); 948a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetBit(msgs.client2server, rfbPointerEvent); 949a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetBit(msgs.client2server, rfbClientCutText); 950a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetBit(msgs.client2server, rfbFileTransfer); 951a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetBit(msgs.client2server, rfbSetScale); 952a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /*rfbSetBit(msgs.client2server, rfbSetServerInput); */ 953a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /*rfbSetBit(msgs.client2server, rfbSetSW); */ 9541d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman /*rfbSetBit(msgs.client2server, rfbTextChat); */ 955a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetBit(msgs.client2server, rfbPalmVNCSetScaleFactor); 956a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetBit(msgs.client2server, rfbXvp); 957a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 958a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetBit(msgs.server2client, rfbFramebufferUpdate); 959a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetBit(msgs.server2client, rfbSetColourMapEntries); 960a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetBit(msgs.server2client, rfbBell); 961a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetBit(msgs.server2client, rfbServerCutText); 962a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetBit(msgs.server2client, rfbResizeFrameBuffer); 963a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetBit(msgs.server2client, rfbPalmVNCReSizeFrameBuffer); 964a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetBit(msgs.server2client, rfbXvp); 965a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 966a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy(&cl->updateBuf[cl->ublen], (char *)&msgs, sz_rfbSupportedMessages); 967a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->ublen += sz_rfbSupportedMessages; 968a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 969a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordEncodingSent(cl, rfbEncodingSupportedMessages, 970a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbFramebufferUpdateRectHeader+sz_rfbSupportedMessages, 971a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbFramebufferUpdateRectHeader+sz_rfbSupportedMessages); 972a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendUpdateBuf(cl)) 973a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 974a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 975a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 976a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 977a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 978a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 979a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 980a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 981a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Send rfbEncodingSupportedEncodings. 982a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 983a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 984a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool 985a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbSendSupportedEncodings(rfbClientPtr cl) 986a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 987a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbFramebufferUpdateRectHeader rect; 988a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat static uint32_t supported[] = { 989a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingRaw, 990a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingCopyRect, 991a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingRRE, 992a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingCoRRE, 993a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingHextile, 994a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ 995a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingZlib, 996a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingZRLE, 997a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingZYWRLE, 998a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 999a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG 1000a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingTight, 1001a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 1002a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBPNG 1003a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingTightPng, 1004a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 1005a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingUltra, 1006a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingUltraZip, 1007a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingXCursor, 1008a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingRichCursor, 1009a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingPointerPos, 1010a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingLastRect, 1011a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingNewFBSize, 1012a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingKeyboardLedState, 1013a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingSupportedMessages, 1014a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingSupportedEncodings, 1015a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEncodingServerIdentity, 1016a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat }; 1017a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint32_t nEncodings = sizeof(supported) / sizeof(supported[0]), i; 1018a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1019a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* think rfbSetEncodingsMsg */ 1020a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1021a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->ublen + sz_rfbFramebufferUpdateRectHeader 1022a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat + (nEncodings * sizeof(uint32_t)) > UPDATE_BUF_SIZE) { 1023a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendUpdateBuf(cl)) 1024a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 1025a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1026a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1027a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.encoding = Swap32IfLE(rfbEncodingSupportedEncodings); 1028a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.x = 0; 1029a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.y = 0; 1030a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.w = Swap16IfLE(nEncodings * sizeof(uint32_t)); 1031a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.h = Swap16IfLE(nEncodings); 1032a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1033a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy(&cl->updateBuf[cl->ublen], (char *)&rect, 1034a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbFramebufferUpdateRectHeader); 1035a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->ublen += sz_rfbFramebufferUpdateRectHeader; 1036a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1037a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < nEncodings; i++) { 1038a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint32_t encoding = Swap32IfLE(supported[i]); 1039a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy(&cl->updateBuf[cl->ublen], (char *)&encoding, sizeof(encoding)); 1040a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->ublen += sizeof(encoding); 1041a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1042a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1043a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordEncodingSent(cl, rfbEncodingSupportedEncodings, 1044a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbFramebufferUpdateRectHeader+(nEncodings * sizeof(uint32_t)), 1045a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbFramebufferUpdateRectHeader+(nEncodings * sizeof(uint32_t))); 1046a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1047a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendUpdateBuf(cl)) 1048a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 1049a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1050a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 1051a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 1052a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1053a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1054a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 1055a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbSetServerVersionIdentity(rfbScreenInfoPtr screen, char *fmt, ...) 1056a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 1057a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char buffer[256]; 1058a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat va_list ap; 1059a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1060a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat va_start(ap, fmt); 1061a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat vsnprintf(buffer, sizeof(buffer)-1, fmt, ap); 1062a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat va_end(ap); 1063a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1064a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (screen->versionString!=NULL) free(screen->versionString); 1065a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat screen->versionString = strdup(buffer); 1066a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 1067a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1068a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 1069a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Send rfbEncodingServerIdentity. 1070a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1071a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1072a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool 1073a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbSendServerIdentity(rfbClientPtr cl) 1074a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 1075a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbFramebufferUpdateRectHeader rect; 1076a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char buffer[512]; 1077a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1078a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* tack on our library version */ 1079a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat snprintf(buffer,sizeof(buffer)-1, "%s (%s)", 1080a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (cl->screen->versionString==NULL ? "unknown" : cl->screen->versionString), 1081a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LIBVNCSERVER_PACKAGE_STRING); 1082a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1083a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->ublen + sz_rfbFramebufferUpdateRectHeader 1084a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat + (strlen(buffer)+1) > UPDATE_BUF_SIZE) { 1085a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendUpdateBuf(cl)) 1086a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 1087a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1088a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1089a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.encoding = Swap32IfLE(rfbEncodingServerIdentity); 1090a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.x = 0; 1091a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.y = 0; 1092a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.w = Swap16IfLE(strlen(buffer)+1); 1093a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.h = 0; 1094a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1095a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy(&cl->updateBuf[cl->ublen], (char *)&rect, 1096a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbFramebufferUpdateRectHeader); 1097a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->ublen += sz_rfbFramebufferUpdateRectHeader; 1098a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1099a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy(&cl->updateBuf[cl->ublen], buffer, strlen(buffer)+1); 1100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->ublen += strlen(buffer)+1; 1101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordEncodingSent(cl, rfbEncodingServerIdentity, 1103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbFramebufferUpdateRectHeader+strlen(buffer)+1, 1104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbFramebufferUpdateRectHeader+strlen(buffer)+1); 1105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendUpdateBuf(cl)) 1108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 1109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 1111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 1112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 1114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Send an xvp server message 1115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool 1118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbSendXvp(rfbClientPtr cl, uint8_t version, uint8_t code) 1119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 1120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbXvpMsg xvp; 1121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xvp.type = rfbXvp; 1123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xvp.pad = 0; 1124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xvp.version = version; 1125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat xvp.code = code; 1126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(cl->sendMutex); 1128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, (char *)&xvp, sz_rfbXvpMsg) < 0) { 1129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbSendXvp: write"); 1130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 1131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->sendMutex); 1133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageSent(cl, rfbXvp, sz_rfbXvpMsg, sz_rfbXvpMsg); 1135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 1137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 1138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool rfbSendTextChatMessage(rfbClientPtr cl, uint32_t length, char *buffer) 1141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 1142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbTextChatMsg tc; 1143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int bytesToSend=0; 1144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memset((char *)&tc, 0, sizeof(tc)); 1146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tc.type = rfbTextChat; 1147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tc.length = Swap32IfLE(length); 1148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat switch(length) { 1150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbTextChatOpen: 1151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbTextChatClose: 1152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbTextChatFinished: 1153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat bytesToSend=0; 1154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat default: 1156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat bytesToSend=length; 1157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (bytesToSend>rfbTextMaxSize) 1158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat bytesToSend=rfbTextMaxSize; 1159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->ublen + sz_rfbTextChatMsg + bytesToSend > UPDATE_BUF_SIZE) { 1162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendUpdateBuf(cl)) 1163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 1164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy(&cl->updateBuf[cl->ublen], (char *)&tc, sz_rfbTextChatMsg); 1167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->ublen += sz_rfbTextChatMsg; 1168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (bytesToSend>0) { 1169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy(&cl->updateBuf[cl->ublen], buffer, bytesToSend); 1170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->ublen += bytesToSend; 1171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageSent(cl, rfbTextChat, sz_rfbTextChatMsg+bytesToSend, sz_rfbTextChatMsg+bytesToSend); 1173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendUpdateBuf(cl)) 1175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 1176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 1178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 1179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define FILEXFER_ALLOWED_OR_CLOSE_AND_RETURN(msg, cl, ret) \ 1181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((cl->screen->getFileTransferPermission != NULL \ 1182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat && cl->screen->getFileTransferPermission(cl) != TRUE) \ 1183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat || cl->screen->permitFileTransfer != TRUE) { \ 1184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("%sUltra File Transfer is disabled, dropping client: %s\n", msg, cl->host); \ 1185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); \ 1186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return ret; \ 1187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint DB = 1; 1190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool rfbSendFileTransferMessage(rfbClientPtr cl, uint8_t contentType, uint8_t contentParam, uint32_t size, uint32_t length, const char *buffer) 1192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 1193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbFileTransferMsg ft; 1194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ft.type = rfbFileTransfer; 1195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ft.contentType = contentType; 1196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ft.contentParam = contentParam; 1197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ft.pad = 0; /* UltraVNC did not Swap16LE(ft.contentParam) (Looks like it might be BigEndian) */ 1198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ft.size = Swap32IfLE(size); 1199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ft.length = Swap32IfLE(length); 1200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FILEXFER_ALLOWED_OR_CLOSE_AND_RETURN("", cl, FALSE); 1202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbSendFileTransferMessage( %dtype, %dparam, %dsize, %dlen, %p)\n", contentType, contentParam, size, length, buffer); 1204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(cl->sendMutex); 1206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, (char *)&ft, sz_rfbFileTransferMsg) < 0) { 1207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbSendFileTransferMessage: write"); 1208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 1209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->sendMutex); 1210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 1211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (length>0) 1214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, buffer, length) < 0) { 1216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbSendFileTransferMessage: write"); 1217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 1218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->sendMutex); 1219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 1220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->sendMutex); 1223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageSent(cl, rfbFileTransfer, sz_rfbFileTransferMsg+length, sz_rfbFileTransferMsg+length); 1225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 1227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 1228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 1231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * UltraVNC uses Windows Structures 1232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define MAX_PATH 260 1234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehattypedef struct { 1236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint32_t dwLowDateTime; 1237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint32_t dwHighDateTime; 1238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} RFB_FILETIME; 1239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehattypedef struct { 1241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint32_t dwFileAttributes; 1242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RFB_FILETIME ftCreationTime; 1243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RFB_FILETIME ftLastAccessTime; 1244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RFB_FILETIME ftLastWriteTime; 1245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint32_t nFileSizeHigh; 1246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint32_t nFileSizeLow; 1247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint32_t dwReserved0; 1248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint32_t dwReserved1; 1249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint8_t cFileName[ MAX_PATH ]; 1250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint8_t cAlternateFileName[ 14 ]; 1251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} RFB_FIND_DATA; 1252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define RFB_FILE_ATTRIBUTE_READONLY 0x1 1254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define RFB_FILE_ATTRIBUTE_HIDDEN 0x2 1255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define RFB_FILE_ATTRIBUTE_SYSTEM 0x4 1256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define RFB_FILE_ATTRIBUTE_DIRECTORY 0x10 1257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define RFB_FILE_ATTRIBUTE_ARCHIVE 0x20 1258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define RFB_FILE_ATTRIBUTE_NORMAL 0x80 1259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define RFB_FILE_ATTRIBUTE_TEMPORARY 0x100 1260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define RFB_FILE_ATTRIBUTE_COMPRESSED 0x800 1261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 12621d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg HartmanrfbBool rfbFilenameTranslate2UNIX(rfbClientPtr cl, /* in */ char *path, /* out */ char *unixPath, size_t unixPathMaxLen) 1263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 1264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int x; 1265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *home=NULL; 1266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FILEXFER_ALLOWED_OR_CLOSE_AND_RETURN("", cl, FALSE); 1268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 12691d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman /* 12701d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman * Do not use strncpy() - truncating the file name would probably have undesirable side effects 12711d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman * Instead check if destination buffer is big enough 12721d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman */ 12731d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman if (strlen(path) >= unixPathMaxLen) 12741d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman return FALSE; 12751d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman 1276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* C: */ 1277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (path[0]=='C' && path[1]==':') 1278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat strcpy(unixPath, &path[2]); 1279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 1280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat home = getenv("HOME"); 1282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (home!=NULL) 1283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 12841d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman /* Re-check buffer size */ 12851d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman if ((strlen(path) + strlen(home) + 1) >= unixPathMaxLen) 12861d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman return FALSE; 12871d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman 1288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat strcpy(unixPath, home); 1289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat strcat(unixPath,"/"); 1290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat strcat(unixPath, path); 1291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 1293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat strcpy(unixPath, path); 1294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (x=0;x<strlen(unixPath);x++) 1296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (unixPath[x]=='\\') unixPath[x]='/'; 1297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 1298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 1299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool rfbFilenameTranslate2DOS(rfbClientPtr cl, char *unixPath, char *path) 1301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 1302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int x; 1303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FILEXFER_ALLOWED_OR_CLOSE_AND_RETURN("", cl, FALSE); 1305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sprintf(path,"C:%s", unixPath); 1307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (x=2;x<strlen(path);x++) 1308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (path[x]=='/') path[x]='\\'; 1309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 1310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 1311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer) 1313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 1314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char retfilename[MAX_PATH]; 1315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char path[MAX_PATH]; 1316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct stat statbuf; 1317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat RFB_FIND_DATA win32filename; 1318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int nOptLen = 0, retval=0; 13191d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#ifdef WIN32 13201d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman WIN32_FIND_DATAA winFindData; 13211d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman HANDLE findHandle; 13221d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman int pathLen, basePathLength; 13231d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman char *basePath; 13241d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#else 1325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat DIR *dirp=NULL; 1326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct dirent *direntp=NULL; 13271d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif 1328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FILEXFER_ALLOWED_OR_CLOSE_AND_RETURN("", cl, FALSE); 1330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Client thinks we are Winblows */ 13321d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman if (!rfbFilenameTranslate2UNIX(cl, buffer, path, sizeof(path))) 13331d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman return FALSE; 1334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (DB) rfbLog("rfbProcessFileTransfer() rfbDirContentRequest: rfbRDirContent: \"%s\"->\"%s\"\n",buffer, path); 1336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 13371d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#ifdef WIN32 13381d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman // Create a search string, like C:\folder\* 13391d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman 13401d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman pathLen = strlen(path); 13411d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman basePath = malloc(pathLen + 3); 13421d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman memcpy(basePath, path, pathLen); 13431d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman basePathLength = pathLen; 13441d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman basePath[basePathLength] = '\\'; 13451d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman basePath[basePathLength + 1] = '*'; 13461d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman basePath[basePathLength + 2] = '\0'; 13471d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman 13481d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman // Start a search 13491d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman memset(&winFindData, 0, sizeof(winFindData)); 13501d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman findHandle = FindFirstFileA(path, &winFindData); 13511d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman free(basePath); 13521d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman 13531d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman if (findHandle == INVALID_HANDLE_VALUE) 13541d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#else 1355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dirp=opendir(path); 1356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (dirp==NULL) 13571d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif 1358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return rfbSendFileTransferMessage(cl, rfbDirPacket, rfbADirectory, 0, 0, NULL); 13591d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman 1360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* send back the path name (necessary for links) */ 1361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbSendFileTransferMessage(cl, rfbDirPacket, rfbADirectory, 0, length, buffer)==FALSE) return FALSE; 13621d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman 13631d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#ifdef WIN32 13641d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman while (findHandle != INVALID_HANDLE_VALUE) 13651d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#else 1366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (direntp=readdir(dirp); direntp!=NULL; direntp=readdir(dirp)) 13671d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif 1368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* get stats */ 13701d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#ifdef WIN32 13711d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman snprintf(retfilename,sizeof(retfilename),"%s/%s", path, winFindData.cFileName); 13721d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#else 13731d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman snprintf(retfilename,sizeof(retfilename),"%s/%s", path, direntp->d_name); 13741d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif 1375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat retval = stat(retfilename, &statbuf); 1376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (retval==0) 1378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memset((char *)&win32filename, 0, sizeof(win32filename)); 13801d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#ifdef WIN32 13811d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman win32filename.dwFileAttributes = winFindData.dwFileAttributes; 13821d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman win32filename.ftCreationTime.dwLowDateTime = winFindData.ftCreationTime.dwLowDateTime; 13831d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman win32filename.ftCreationTime.dwHighDateTime = winFindData.ftCreationTime.dwHighDateTime; 13841d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman win32filename.ftLastAccessTime.dwLowDateTime = winFindData.ftLastAccessTime.dwLowDateTime; 13851d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman win32filename.ftLastAccessTime.dwHighDateTime = winFindData.ftLastAccessTime.dwHighDateTime; 13861d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman win32filename.ftLastWriteTime.dwLowDateTime = winFindData.ftLastWriteTime.dwLowDateTime; 13871d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman win32filename.ftLastWriteTime.dwHighDateTime = winFindData.ftLastWriteTime.dwHighDateTime; 13881d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman win32filename.nFileSizeLow = winFindData.nFileSizeLow; 13891d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman win32filename.nFileSizeHigh = winFindData.nFileSizeHigh; 13901d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman win32filename.dwReserved0 = winFindData.dwReserved0; 13911d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman win32filename.dwReserved1 = winFindData.dwReserved1; 13921d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman strcpy((char *)win32filename.cFileName, winFindData.cFileName); 13931d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman strcpy((char *)win32filename.cAlternateFileName, winFindData.cAlternateFileName); 13941d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#else 1395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat win32filename.dwFileAttributes = Swap32IfBE(RFB_FILE_ATTRIBUTE_NORMAL); 1396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (S_ISDIR(statbuf.st_mode)) 13971d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman win32filename.dwFileAttributes = Swap32IfBE(RFB_FILE_ATTRIBUTE_DIRECTORY); 1398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat win32filename.ftCreationTime.dwLowDateTime = Swap32IfBE(statbuf.st_ctime); /* Intel Order */ 1399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat win32filename.ftCreationTime.dwHighDateTime = 0; 1400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat win32filename.ftLastAccessTime.dwLowDateTime = Swap32IfBE(statbuf.st_atime); /* Intel Order */ 1401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat win32filename.ftLastAccessTime.dwHighDateTime = 0; 1402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat win32filename.ftLastWriteTime.dwLowDateTime = Swap32IfBE(statbuf.st_mtime); /* Intel Order */ 1403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat win32filename.ftLastWriteTime.dwHighDateTime = 0; 1404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat win32filename.nFileSizeLow = Swap32IfBE(statbuf.st_size); /* Intel Order */ 1405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat win32filename.nFileSizeHigh = 0; 1406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat win32filename.dwReserved0 = 0; 1407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat win32filename.dwReserved1 = 0; 1408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* If this had the full path, we would need to translate to DOS format ("C:\") */ 1410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* rfbFilenameTranslate2DOS(cl, retfilename, win32filename.cFileName); */ 1411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat strcpy((char *)win32filename.cFileName, direntp->d_name); 14121d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif 1413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Do not show hidden files (but show how to move up the tree) */ 14151d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman if ((strcmp((char *)win32filename.cFileName, "..")==0) || (win32filename.cFileName[0]!='.')) 1416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nOptLen = sizeof(RFB_FIND_DATA) - MAX_PATH - 14 + strlen((char *)win32filename.cFileName); 1418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() rfbDirContentRequest: rfbRDirContent: Sending \"%s\"\n", (char *)win32filename.cFileName); 1420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbSendFileTransferMessage(cl, rfbDirPacket, rfbADirectory, 0, nOptLen, (char *)&win32filename)==FALSE) 1422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 14231d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#ifdef WIN32 14241d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman FindClose(findHandle); 14251d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#else 1426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat closedir(dirp); 14271d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif 1428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 1429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 14321d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman 14331d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#ifdef WIN32 14341d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman if (FindNextFileA(findHandle, &winFindData) == 0) 14351d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman { 14361d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman FindClose(findHandle); 14371d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman findHandle = INVALID_HANDLE_VALUE; 14381d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman } 14391d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif 1440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 14411d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#ifdef WIN32 14421d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman if (findHandle != INVALID_HANDLE_VALUE) 14431d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman { 14441d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman FindClose(findHandle); 14451d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman } 14461d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#else 1447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat closedir(dirp); 14481d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman#endif 1449a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* End of the transfer */ 1450a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return rfbSendFileTransferMessage(cl, rfbDirPacket, 0, 0, 0, NULL); 1451a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 1452a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1453a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1454a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatchar *rfbProcessFileTransferReadBuffer(rfbClientPtr cl, uint32_t length) 1455a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 1456a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *buffer=NULL; 1457a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int n=0; 1458a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1459a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FILEXFER_ALLOWED_OR_CLOSE_AND_RETURN("", cl, NULL); 1460a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1461a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransferReadBuffer(%dlen)\n", length); 1462a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1463a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (length>0) { 1464a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buffer=malloc(length+1); 1465a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (buffer!=NULL) { 1466a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, (char *)buffer, length)) <= 0) { 1467a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 1468a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessFileTransferReadBuffer: read"); 1469a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 1470a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* NOTE: don't forget to free(buffer) if you return early! */ 1471a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (buffer!=NULL) free(buffer); 1472a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return NULL; 1473a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1474a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Null Terminate */ 1475a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buffer[length]=0; 1476a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1477a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1478a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return buffer; 1479a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 1480a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1481a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1482a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool rfbSendFileTransferChunk(rfbClientPtr cl) 1483a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 1484a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Allocate buffer for compression */ 1485a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat unsigned char readBuf[sz_rfbBlockSize]; 1486a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int bytesRead=0; 1487a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int retval=0; 1488a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fd_set wfds; 1489a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct timeval tv; 1490a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int n; 1491a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ 1492a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat unsigned char compBuf[sz_rfbBlockSize + 1024]; 1493a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat unsigned long nMaxCompSize = sizeof(compBuf); 1494a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int nRetC = 0; 1495a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 1496a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1497a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1498a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Don't close the client if we get into this one because 1499a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * it is called from many places to service file transfers. 1500a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Note that permitFileTransfer is checked first. 1501a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1502a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->screen->permitFileTransfer != TRUE || 1503a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (cl->screen->getFileTransferPermission != NULL 1504a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat && cl->screen->getFileTransferPermission(cl) != TRUE)) { 1505a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 1506a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1507a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1508a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* If not sending, or no file open... Return as if we sent something! */ 1509a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((cl->fileTransfer.fd!=-1) && (cl->fileTransfer.sending==1)) 1510a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1511a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FD_ZERO(&wfds); 1512a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FD_SET(cl->sock, &wfds); 1513a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1514a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* return immediately */ 1515a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tv.tv_sec = 0; 1516a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tv.tv_usec = 0; 1517a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat n = select(cl->sock + 1, NULL, &wfds, NULL, &tv); 1518a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1519a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n<0) { 1520a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef WIN32 1521a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat errno=WSAGetLastError(); 1522a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 1523a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbSendFileTransferChunk() select failed: %s\n", strerror(errno)); 1524a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1525a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* We have space on the transmit queue */ 1526a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n > 0) 1527a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1528a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat bytesRead = read(cl->fileTransfer.fd, readBuf, sz_rfbBlockSize); 1529a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat switch (bytesRead) { 1530a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case 0: 1531a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1532a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbSendFileTransferChunk(): End-Of-File Encountered\n"); 1533a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1534a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat retval = rfbSendFileTransferMessage(cl, rfbEndOfFile, 0, 0, 0, NULL); 1535a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(cl->fileTransfer.fd); 1536a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.fd = -1; 1537a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.sending = 0; 1538a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.receiving = 0; 1539a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return retval; 1540a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case -1: 1541a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* TODO : send an error msg to the client... */ 1542a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef WIN32 1543a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat errno=WSAGetLastError(); 1544a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 1545a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbSendFileTransferChunk(): %s\n",strerror(errno)); 1546a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat retval = rfbSendFileTransferMessage(cl, rfbAbortFileTransfer, 0, 0, 0, NULL); 1547a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(cl->fileTransfer.fd); 1548a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.fd = -1; 1549a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.sending = 0; 1550a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.receiving = 0; 1551a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return retval; 1552a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat default: 1553a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1554a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbSendFileTransferChunk(): Read %d bytes\n", bytesRead); 1555a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1556a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!cl->fileTransfer.compressionEnabled) 1557a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return rfbSendFileTransferMessage(cl, rfbFilePacket, 0, 0, bytesRead, (char *)readBuf); 1558a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 1559a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1560a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ 1561a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nRetC = compress(compBuf, &nMaxCompSize, readBuf, bytesRead); 1562a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1563a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Compressed the packet from %d -> %d bytes\n", nMaxCompSize, bytesRead); 1564a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1565a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1566a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((nRetC==0) && (nMaxCompSize<bytesRead)) 1567a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return rfbSendFileTransferMessage(cl, rfbFilePacket, 0, 1, nMaxCompSize, (char *)compBuf); 1568a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 1569a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return rfbSendFileTransferMessage(cl, rfbFilePacket, 0, 0, bytesRead, (char *)readBuf); 1570a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 1571a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* We do not support compression of the data stream */ 1572a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return rfbSendFileTransferMessage(cl, rfbFilePacket, 0, 0, bytesRead, (char *)readBuf); 1573a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 1574a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1575a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1576a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1577a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1578a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 1579a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 1580a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1581a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool rfbProcessFileTransfer(rfbClientPtr cl, uint8_t contentType, uint8_t contentParam, uint32_t size, uint32_t length) 1582a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 1583a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *buffer=NULL, *p=NULL; 1584a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int retval=0; 1585a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char filename1[MAX_PATH]; 1586a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char filename2[MAX_PATH]; 1587a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char szFileTime[MAX_PATH]; 1588a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct stat statbuf; 1589a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint32_t sizeHtmp=0; 1590a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int n=0; 1591a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char timespec[64]; 1592a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ 1593a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat unsigned char compBuff[sz_rfbBlockSize]; 1594a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat unsigned long nRawBytes = sz_rfbBlockSize; 1595a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int nRet = 0; 1596a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 1597a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1598a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FILEXFER_ALLOWED_OR_CLOSE_AND_RETURN("", cl, FALSE); 1599a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1600a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1601a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer(%dtype, %dparam, %dsize, %dlen)\n", contentType, contentParam, size, length); 1602a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1603a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1604a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat switch (contentType) { 1605a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbDirContentRequest: 1606a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat switch (contentParam) { 1607a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbRDrivesList: /* Client requests the List of Local Drives */ 1608a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1609a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() rfbDirContentRequest: rfbRDrivesList:\n"); 1610a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1611a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Format when filled : "C:\<NULL>D:\<NULL>....Z:\<NULL><NULL> 1612a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 1613a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * We replace the "\" char following the drive letter and ":" 1614a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * with a char corresponding to the type of drive 1615a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * We obtain something like "C:l<NULL>D:c<NULL>....Z:n\<NULL><NULL>" 1616a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Isn't it ugly ? 1617a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * DRIVE_FIXED = 'l' (local?) 1618a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * DRIVE_REMOVABLE = 'f' (floppy?) 1619a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * DRIVE_CDROM = 'c' 1620a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * DRIVE_REMOTE = 'n' 1621a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1622a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1623a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* in unix, there are no 'drives' (We could list mount points though) 1624a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * We fake the root as a "C:" for the Winblows users 1625a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1626a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat filename2[0]='C'; 1627a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat filename2[1]=':'; 1628a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat filename2[2]='l'; 1629a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat filename2[3]=0; 1630a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat filename2[4]=0; 1631a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat retval = rfbSendFileTransferMessage(cl, rfbDirPacket, rfbADrivesList, 0, 5, filename2); 1632a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (buffer!=NULL) free(buffer); 1633a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return retval; 1634a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1635a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbRDirContent: /* Client requests the content of a directory */ 1636a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1637a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() rfbDirContentRequest: rfbRDirContent\n"); 1638a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1639a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((buffer = rfbProcessFileTransferReadBuffer(cl, length))==NULL) return FALSE; 1640a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat retval = rfbSendDirContent(cl, length, buffer); 1641a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (buffer!=NULL) free(buffer); 1642a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return retval; 1643a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1644a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1645a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1646a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbDirPacket: 1647a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() rfbDirPacket\n"); 1648a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1649a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbFileAcceptHeader: 1650a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() rfbFileAcceptHeader\n"); 1651a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1652a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbCommandReturn: 1653a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() rfbCommandReturn\n"); 1654a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1655a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbFileChecksums: 1656a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Destination file already exists - the viewer sends the checksums */ 1657a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() rfbFileChecksums\n"); 1658a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1659a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbFileTransferAccess: 1660a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() rfbFileTransferAccess\n"); 1661a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1662a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1663a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1664a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * sending from the server to the viewer 1665a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1666a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1667a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbFileTransferRequest: 1668a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1669a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() rfbFileTransferRequest:\n"); 1670a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1671a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* add some space to the end of the buffer as we will be adding a timespec to it */ 1672a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((buffer = rfbProcessFileTransferReadBuffer(cl, length))==NULL) return FALSE; 1673a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* The client requests a File */ 16741d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman if (!rfbFilenameTranslate2UNIX(cl, buffer, filename1, sizeof(filename1))) 16751d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman goto fail; 1676a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.fd=open(filename1, O_RDONLY, 0744); 1677a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1678a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1679a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1680a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (DB) rfbLog("rfbProcessFileTransfer() rfbFileTransferRequest(\"%s\"->\"%s\") Open: %s fd=%d\n", buffer, filename1, (cl->fileTransfer.fd==-1?"Failed":"Success"), cl->fileTransfer.fd); 1681a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1682a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->fileTransfer.fd!=-1) { 1683a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (fstat(cl->fileTransfer.fd, &statbuf)!=0) { 1684a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(cl->fileTransfer.fd); 1685a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.fd=-1; 1686a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1687a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 1688a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1689a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Add the File Time Stamp to the filename */ 1690a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat strftime(timespec, sizeof(timespec), "%m/%d/%Y %H:%M",gmtime(&statbuf.st_ctime)); 1691a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buffer=realloc(buffer, length + strlen(timespec) + 2); /* comma, and Null term */ 1692a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (buffer==NULL) { 1693a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() rfbFileTransferRequest: Failed to malloc %d bytes\n", length + strlen(timespec) + 2); 1694a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 1695a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1696a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat strcat(buffer,","); 1697a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat strcat(buffer, timespec); 1698a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat length = strlen(buffer); 1699a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (DB) rfbLog("rfbProcessFileTransfer() buffer is now: \"%s\"\n", buffer); 1700a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1701a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1702a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1703a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* The viewer supports compression if size==1 */ 1704a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.compressionEnabled = (size==1); 1705a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1706a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1707a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() rfbFileTransferRequest(\"%s\"->\"%s\")%s\n", buffer, filename1, (size==1?" <Compression Enabled>":"")); 1708a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1709a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1710a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* File Size in bytes, 0xFFFFFFFF (-1) means error */ 1711a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat retval = rfbSendFileTransferMessage(cl, rfbFileHeader, 0, (cl->fileTransfer.fd==-1 ? -1 : statbuf.st_size), length, buffer); 1712a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1713a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->fileTransfer.fd==-1) 1714a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1715a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (buffer!=NULL) free(buffer); 1716a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return retval; 1717a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1718a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* setup filetransfer stuff */ 1719a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.fileSize = statbuf.st_size; 1720a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.numPackets = statbuf.st_size / sz_rfbBlockSize; 1721a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.receiving = 0; 1722a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.sending = 0; /* set when we receive a rfbFileHeader: */ 1723a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1724a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* TODO: finish 64-bit file size support */ 1725a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sizeHtmp = 0; 1726a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(cl->sendMutex); 1727a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, (char *)&sizeHtmp, 4) < 0) { 1728a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessFileTransfer: write"); 1729a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 1730a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->sendMutex); 1731a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (buffer!=NULL) free(buffer); 1732a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 1733a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1734a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->sendMutex); 1735a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1736a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1737a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbFileHeader: 1738a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Destination file (viewer side) is ready for reception (size > 0) or not (size = -1) */ 1739a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (size==-1) { 1740a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() rfbFileHeader (error, aborting)\n"); 1741a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(cl->fileTransfer.fd); 1742a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.fd=-1; 1743a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 1744a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1745a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1746a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1747a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() rfbFileHeader (%d bytes of a file)\n", size); 1748a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1749a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1750a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Starts the transfer! */ 1751a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.sending=1; 1752a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return rfbSendFileTransferChunk(cl); 1753a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1754a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1755a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1756a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1757a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * sending from the viewer to the server 1758a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1759a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1760a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbFileTransferOffer: 1761a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* client is sending a file to us */ 1762a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* buffer contains full path name (plus FileTime) */ 1763a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* size contains size of the file */ 1764a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1765a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() rfbFileTransferOffer:\n"); 1766a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1767a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((buffer = rfbProcessFileTransferReadBuffer(cl, length))==NULL) return FALSE; 1768a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1769a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Parse the FileTime */ 1770a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p = strrchr(buffer, ','); 1771a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (p!=NULL) { 1772a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *p = '\0'; 17731d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman strncpy(szFileTime, p+1, sizeof(szFileTime)); 17741d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman szFileTime[sizeof(szFileTime)-1] = '\x00'; /* ensure NULL terminating byte is present, even if copy overflowed */ 1775a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else 1776a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat szFileTime[0]=0; 1777a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1778a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1779a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1780a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Need to read in sizeHtmp */ 1781a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, (char *)&sizeHtmp, 4)) <= 0) { 1782a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 1783a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessFileTransfer: read sizeHtmp"); 1784a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 1785a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* NOTE: don't forget to free(buffer) if you return early! */ 1786a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (buffer!=NULL) free(buffer); 1787a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 1788a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1789a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sizeHtmp = Swap32IfLE(sizeHtmp); 1790a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 17911d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman if (!rfbFilenameTranslate2UNIX(cl, buffer, filename1, sizeof(filename1))) 17921d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman goto fail; 1793a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1794a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* If the file exists... We can send a rfbFileChecksums back to the client before we send an rfbFileAcceptHeader */ 1795a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* TODO: Delta Transfer */ 1796a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1797a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.fd=open(filename1, O_CREAT|O_WRONLY|O_TRUNC, 0744); 1798a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (DB) rfbLog("rfbProcessFileTransfer() rfbFileTransferOffer(\"%s\"->\"%s\") %s %s fd=%d\n", buffer, filename1, (cl->fileTransfer.fd==-1?"Failed":"Success"), (cl->fileTransfer.fd==-1?strerror(errno):""), cl->fileTransfer.fd); 1799a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1800a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1801a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1802a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* File Size in bytes, 0xFFFFFFFF (-1) means error */ 1803a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat retval = rfbSendFileTransferMessage(cl, rfbFileAcceptHeader, 0, (cl->fileTransfer.fd==-1 ? -1 : 0), length, buffer); 1804a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->fileTransfer.fd==-1) { 1805a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(buffer); 1806a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return retval; 1807a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1808a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1809a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* setup filetransfer stuff */ 1810a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.fileSize = size; 1811a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.numPackets = size / sz_rfbBlockSize; 1812a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.receiving = 1; 1813a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.sending = 0; 1814a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1815a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1816a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbFilePacket: 1817a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1818a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() rfbFilePacket:\n"); 1819a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1820a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((buffer = rfbProcessFileTransferReadBuffer(cl, length))==NULL) return FALSE; 1821a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->fileTransfer.fd!=-1) { 1822a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* buffer contains the contents of the file */ 1823a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (size==0) 1824a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat retval=write(cl->fileTransfer.fd, buffer, length); 1825a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 1826a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1827a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ 1828a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* compressed packet */ 1829a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nRet = uncompress(compBuff,&nRawBytes,(const unsigned char*)buffer, length); 1830a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(nRet == Z_OK) 1831a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat retval=write(cl->fileTransfer.fd, (char*)compBuff, nRawBytes); 1832a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 1833a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat retval = -1; 1834a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 1835a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Write the file out as received... */ 1836a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat retval=write(cl->fileTransfer.fd, buffer, length); 1837a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 1838a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1839a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (retval==-1) 1840a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1841a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(cl->fileTransfer.fd); 1842a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.fd=-1; 1843a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.sending = 0; 1844a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.receiving = 0; 1845a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1846a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1847a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1848a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1849a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEndOfFile: 1850a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (DB) rfbLog("rfbProcessFileTransfer() rfbEndOfFile\n"); 1851a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1852a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1853a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->fileTransfer.fd!=-1) 1854a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(cl->fileTransfer.fd); 1855a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.fd=-1; 1856a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.sending = 0; 1857a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.receiving = 0; 1858a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1859a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1860a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbAbortFileTransfer: 1861a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (DB) rfbLog("rfbProcessFileTransfer() rfbAbortFileTransfer\n"); 1862a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1863a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1864a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->fileTransfer.fd!=-1) 1865a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1866a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(cl->fileTransfer.fd); 1867a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.fd=-1; 1868a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.sending = 0; 1869a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->fileTransfer.receiving = 0; 1870a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1871a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 1872a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1873a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* We use this message for FileTransfer rights (<=RC18 versions) 1874a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * The client asks for FileTransfer permission 1875a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1876a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (contentParam == 0) 1877a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1878a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() File Transfer Permission DENIED! (Client Version <=RC18)\n"); 1879a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Old method for FileTransfer handshake perimssion (<=RC18) (Deny it)*/ 1880a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return rfbSendFileTransferMessage(cl, rfbAbortFileTransfer, 0, -1, 0, ""); 1881a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1882a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* New method is allowed */ 1883a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->screen->getFileTransferPermission!=NULL) 1884a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1885a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->screen->getFileTransferPermission(cl)==TRUE) 1886a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1887a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() File Transfer Permission Granted!\n"); 1888a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return rfbSendFileTransferMessage(cl, rfbFileTransferAccess, 0, 1 , 0, ""); /* Permit */ 1889a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1890a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 1891a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1892a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() File Transfer Permission DENIED!\n"); 1893a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return rfbSendFileTransferMessage(cl, rfbFileTransferAccess, 0, -1 , 0, ""); /* Deny */ 1894a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1895a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1896a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 1897a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1898a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->screen->permitFileTransfer) 1899a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1900a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() File Transfer Permission Granted!\n"); 1901a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return rfbSendFileTransferMessage(cl, rfbFileTransferAccess, 0, 1 , 0, ""); /* Permit */ 1902a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1903a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 1904a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1905a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() File Transfer Permission DENIED by default!\n"); 1906a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return rfbSendFileTransferMessage(cl, rfbFileTransferAccess, 0, -1 , 0, ""); /* DEFAULT: DENY (for security) */ 1907a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1908a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1909a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1910a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1911a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1912a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1913a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1914a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbCommand: 1915a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1916a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessFileTransfer() rfbCommand:\n"); 1917a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1918a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((buffer = rfbProcessFileTransferReadBuffer(cl, length))==NULL) return FALSE; 1919a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat switch (contentParam) { 1920a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbCDirCreate: /* Client requests the creation of a directory */ 19211d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman if (!rfbFilenameTranslate2UNIX(cl, buffer, filename1, sizeof(filename1))) 19221d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman goto fail; 1923a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat retval = mkdir(filename1, 0755); 1924a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (DB) rfbLog("rfbProcessFileTransfer() rfbCommand: rfbCDirCreate(\"%s\"->\"%s\") %s\n", buffer, filename1, (retval==-1?"Failed":"Success")); 1925a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1926a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1927a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat retval = rfbSendFileTransferMessage(cl, rfbCommandReturn, rfbADirCreate, retval, length, buffer); 1928a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (buffer!=NULL) free(buffer); 1929a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return retval; 1930a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbCFileDelete: /* Client requests the deletion of a file */ 19311d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman if (!rfbFilenameTranslate2UNIX(cl, buffer, filename1, sizeof(filename1))) 19321d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman goto fail; 1933a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (stat(filename1,&statbuf)==0) 1934a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1935a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (S_ISDIR(statbuf.st_mode)) 1936a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat retval = rmdir(filename1); 1937a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 1938a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat retval = unlink(filename1); 1939a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1940a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else retval=-1; 1941a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat retval = rfbSendFileTransferMessage(cl, rfbCommandReturn, rfbAFileDelete, retval, length, buffer); 1942a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (buffer!=NULL) free(buffer); 1943a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return retval; 1944a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbCFileRename: /* Client requests the Renaming of a file/directory */ 1945a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat p = strrchr(buffer, '*'); 1946a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (p != NULL) 1947a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 1948a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Split into 2 filenames ('*' is a seperator) */ 1949a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *p = '\0'; 19501d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman if (!rfbFilenameTranslate2UNIX(cl, buffer, filename1, sizeof(filename1))) 19511d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman goto fail; 19521d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman if (!rfbFilenameTranslate2UNIX(cl, p+1, filename2, sizeof(filename2))) 19531d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman goto fail; 1954a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat retval = rename(filename1,filename2); 1955a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (DB) rfbLog("rfbProcessFileTransfer() rfbCommand: rfbCFileRename(\"%s\"->\"%s\" -->> \"%s\"->\"%s\") %s\n", buffer, filename1, p+1, filename2, (retval==-1?"Failed":"Success")); 1956a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 1957a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1958a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Restore the buffer so the reply is good */ 1959a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat *p = '*'; 1960a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat retval = rfbSendFileTransferMessage(cl, rfbCommandReturn, rfbAFileRename, retval, length, buffer); 1961a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (buffer!=NULL) free(buffer); 1962a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return retval; 1963a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1964a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1965a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1966a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1967a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 1968a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 1969a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1970a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* NOTE: don't forget to free(buffer) if you return early! */ 1971a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (buffer!=NULL) free(buffer); 1972a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 19731d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman 19741d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartmanfail: 19751d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman if (buffer!=NULL) free(buffer); 19761d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman return FALSE; 1977a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 1978a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1979a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 1980a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbProcessClientNormalMessage is called when the client has sent a normal 1981a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * protocol message. 1982a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 1983a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1984a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void 1985a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbProcessClientNormalMessage(rfbClientPtr cl) 1986a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 1987a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int n=0; 1988a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientToServerMsg msg; 1989a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *str; 1990a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i; 1991a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint32_t enc=0; 1992a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint32_t lastPreferredEncoding = -1; 1993a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char encBuf[64]; 1994a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char encBuf2[64]; 1995a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 1996a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_WITH_WEBSOCKETS 1997a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->wsctx && webSocketCheckDisconnect(cl)) 1998a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 1999a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 2000a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2001a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, (char *)&msg, 1)) <= 0) { 2002a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 2003a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientNormalMessage: read"); 2004a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2005a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2006a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2007a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2008a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat switch (msg.type) { 2009a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2010a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbSetPixelFormat: 2011a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2012a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, ((char *)&msg) + 1, 2013a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbSetPixelFormatMsg - 1)) <= 0) { 2014a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 2015a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientNormalMessage: read"); 2016a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2017a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2018a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2019a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2020a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->format.bitsPerPixel = msg.spf.format.bitsPerPixel; 2021a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->format.depth = msg.spf.format.depth; 2022a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->format.bigEndian = (msg.spf.format.bigEndian ? TRUE : FALSE); 2023a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->format.trueColour = (msg.spf.format.trueColour ? TRUE : FALSE); 2024a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->format.redMax = Swap16IfLE(msg.spf.format.redMax); 2025a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->format.greenMax = Swap16IfLE(msg.spf.format.greenMax); 2026a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->format.blueMax = Swap16IfLE(msg.spf.format.blueMax); 2027a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->format.redShift = msg.spf.format.redShift; 2028a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->format.greenShift = msg.spf.format.greenShift; 2029a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->format.blueShift = msg.spf.format.blueShift; 2030a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2031a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->readyForSetColourMapEntries = TRUE; 2032a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->setTranslateFunction(cl); 2033a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2034a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbSetPixelFormatMsg, sz_rfbSetPixelFormatMsg); 2035a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2036a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2037a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2038a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2039a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbFixColourMapEntries: 2040a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, ((char *)&msg) + 1, 2041a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbFixColourMapEntriesMsg - 1)) <= 0) { 2042a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 2043a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientNormalMessage: read"); 2044a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2045a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2046a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2047a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbSetPixelFormatMsg, sz_rfbSetPixelFormatMsg); 2048a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessClientNormalMessage: %s", 2049a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "FixColourMapEntries unsupported\n"); 2050a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2051a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2052a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2053a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2054a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* NOTE: Some clients send us a set of encodings (ie: PointerPos) designed to enable/disable features... 2055a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * We may want to look into this... 2056a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Example: 2057a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * case rfbEncodingXCursor: 2058a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * cl->enableCursorShapeUpdates = TRUE; 2059a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 2060a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Currently: cl->enableCursorShapeUpdates can *never* be turned off... 2061a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2062a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbSetEncodings: 2063a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 2064a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2065a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, ((char *)&msg) + 1, 2066a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbSetEncodingsMsg - 1)) <= 0) { 2067a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 2068a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientNormalMessage: read"); 2069a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2070a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2071a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2072a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2073a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat msg.se.nEncodings = Swap16IfLE(msg.se.nEncodings); 2074a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2075a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbSetEncodingsMsg+(msg.se.nEncodings*4),sz_rfbSetEncodingsMsg+(msg.se.nEncodings*4)); 2076a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2077a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2078a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * UltraVNC Client has the ability to adapt to changing network environments 2079a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * So, let's give it a change to tell us what it wants now! 2080a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2081a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->preferredEncoding!=-1) 2082a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lastPreferredEncoding = cl->preferredEncoding; 2083a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2084a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Reset all flags to defaults (allows us to switch between PointerPos and Server Drawn Cursors) */ 2085a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->preferredEncoding=-1; 2086a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->useCopyRect = FALSE; 2087a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->useNewFBSize = FALSE; 2088a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->cursorWasChanged = FALSE; 2089a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->useRichCursorEncoding = FALSE; 2090a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableCursorPosUpdates = FALSE; 2091a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableCursorShapeUpdates = FALSE; 2092a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableCursorShapeUpdates = FALSE; 2093a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableLastRectEncoding = FALSE; 2094a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableKeyboardLedState = FALSE; 2095a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableSupportedMessages = FALSE; 2096a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableSupportedEncodings = FALSE; 2097a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableServerIdentity = FALSE; 2098a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if defined(LIBVNCSERVER_HAVE_LIBZ) || defined(LIBVNCSERVER_HAVE_LIBPNG) 2099a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->tightQualityLevel = -1; 2100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG 2101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->tightCompressLevel = TIGHT_DEFAULT_COMPRESSION; 2102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->turboSubsampLevel = TURBO_DEFAULT_SUBSAMP; 2103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->turboQualityLevel = -1; 2104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 2105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 2106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < msg.se.nEncodings; i++) { 2109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, (char *)&enc, 4)) <= 0) { 2110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 2111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientNormalMessage: read"); 2112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat enc = Swap32IfLE(enc); 2116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat switch (enc) { 2118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingCopyRect: 2120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->useCopyRect = TRUE; 2121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingRaw: 2123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingRRE: 2124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingCoRRE: 2125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingHextile: 2126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingUltra: 2127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ 2128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingZlib: 2129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingZRLE: 2130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingZYWRLE: 2131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG 2132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingTight: 2133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 2134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 2135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBPNG 2136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingTightPng: 2137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 2138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* The first supported encoding is the 'preferred' encoding */ 2139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->preferredEncoding == -1) 2140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->preferredEncoding = enc; 2141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingXCursor: 2145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(!cl->screen->dontConvertRichCursorToXCursor) { 2146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Enabling X-style cursor updates for client %s\n", 2147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->host); 2148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* if cursor was drawn, hide the cursor */ 2149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(!cl->enableCursorShapeUpdates) 2150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbRedrawAfterHideCursor(cl,NULL); 2151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableCursorShapeUpdates = TRUE; 2153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->cursorWasChanged = TRUE; 2154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingRichCursor: 2157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Enabling full-color cursor updates for client %s\n", 2158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->host); 2159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* if cursor was drawn, hide the cursor */ 2160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(!cl->enableCursorShapeUpdates) 2161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbRedrawAfterHideCursor(cl,NULL); 2162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableCursorShapeUpdates = TRUE; 2164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->useRichCursorEncoding = TRUE; 2165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->cursorWasChanged = TRUE; 2166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingPointerPos: 2168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!cl->enableCursorPosUpdates) { 2169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Enabling cursor position updates for client %s\n", 2170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->host); 2171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableCursorPosUpdates = TRUE; 2172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->cursorWasMoved = TRUE; 2173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingLastRect: 2176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!cl->enableLastRectEncoding) { 2177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Enabling LastRect protocol extension for client " 2178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "%s\n", cl->host); 2179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableLastRectEncoding = TRUE; 2180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingNewFBSize: 2183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!cl->useNewFBSize) { 2184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Enabling NewFBSize protocol extension for client " 2185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "%s\n", cl->host); 2186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->useNewFBSize = TRUE; 2187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingKeyboardLedState: 2190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!cl->enableKeyboardLedState) { 2191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Enabling KeyboardLedState protocol extension for client " 2192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "%s\n", cl->host); 2193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableKeyboardLedState = TRUE; 2194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingSupportedMessages: 2197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!cl->enableSupportedMessages) { 2198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Enabling SupportedMessages protocol extension for client " 2199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "%s\n", cl->host); 2200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableSupportedMessages = TRUE; 2201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingSupportedEncodings: 2204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!cl->enableSupportedEncodings) { 2205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Enabling SupportedEncodings protocol extension for client " 2206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "%s\n", cl->host); 2207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableSupportedEncodings = TRUE; 2208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingServerIdentity: 2211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!cl->enableServerIdentity) { 2212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Enabling ServerIdentity protocol extension for client " 2213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "%s\n", cl->host); 2214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableServerIdentity = TRUE; 2215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingXvp: 2218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Enabling Xvp protocol extension for client " 2219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "%s\n", cl->host); 2220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendXvp(cl, 1, rfbXvp_Init)) { 2221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat default: 2226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if defined(LIBVNCSERVER_HAVE_LIBZ) || defined(LIBVNCSERVER_HAVE_LIBPNG) 2227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( enc >= (uint32_t)rfbEncodingCompressLevel0 && 2228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat enc <= (uint32_t)rfbEncodingCompressLevel9 ) { 2229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->zlibCompressLevel = enc & 0x0F; 2230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG 2231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->tightCompressLevel = enc & 0x0F; 2232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Using compression level %d for client %s\n", 2233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->tightCompressLevel, cl->host); 2234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 2235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if ( enc >= (uint32_t)rfbEncodingQualityLevel0 && 2236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat enc <= (uint32_t)rfbEncodingQualityLevel9 ) { 2237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->tightQualityLevel = enc & 0x0F; 2238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Using image quality level %d for client %s\n", 2239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->tightQualityLevel, cl->host); 2240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG 2241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->turboQualityLevel = tight2turbo_qual[enc & 0x0F]; 2242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->turboSubsampLevel = tight2turbo_subsamp[enc & 0x0F]; 2243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Using JPEG subsampling %d, Q%d for client %s\n", 2244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->turboSubsampLevel, cl->turboQualityLevel, cl->host); 2245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if ( enc >= (uint32_t)rfbEncodingFineQualityLevel0 + 1 && 2246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat enc <= (uint32_t)rfbEncodingFineQualityLevel100 ) { 2247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->turboQualityLevel = enc & 0xFF; 2248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Using fine quality level %d for client %s\n", 2249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->turboQualityLevel, cl->host); 2250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if ( enc >= (uint32_t)rfbEncodingSubsamp1X && 2251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat enc <= (uint32_t)rfbEncodingSubsampGray ) { 2252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->turboSubsampLevel = enc & 0xFF; 2253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Using subsampling level %d for client %s\n", 2254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->turboSubsampLevel, cl->host); 2255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 2256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else 2257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 2258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 2259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbExtensionData* e; 2260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(e = cl->extensions; e;) { 2261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbExtensionData* next = e->next; 2262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(e->extension->enablePseudoEncoding && 2263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat e->extension->enablePseudoEncoding(cl, 2264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat &e->data, (int)enc)) 2265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* ext handles this encoding */ 2266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat e = next; 2268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(e == NULL) { 2270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbBool handled = FALSE; 2271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* if the pseudo encoding is not handled by the 2272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat enabled extensions, search through all 2273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat extensions. */ 2274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbProtocolExtension* e; 2275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(e = rfbGetExtensionIterator(); e;) { 2277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int* encs = e->pseudoEncodings; 2278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while(encs && *encs!=0) { 2279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(*encs==(int)enc) { 2280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat void* data = NULL; 2281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(!e->enablePseudoEncoding(cl, &data, (int)enc)) { 2282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Installed extension pretends to handle pseudo encoding 0x%x, but does not!\n",(int)enc); 2283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 2284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbEnableExtension(cl, e, data); 2285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat handled = TRUE; 2286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat e = NULL; 2287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat encs++; 2291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(e) 2294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat e = e->next; 2295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbReleaseExtensionIterator(); 2297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(!handled) 2299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessClientNormalMessage: " 2300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "ignoring unsupported encoding type %s\n", 2301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat encodingName(enc,encBuf,sizeof(encBuf))); 2302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->preferredEncoding == -1) { 2310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (lastPreferredEncoding==-1) { 2311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->preferredEncoding = rfbEncodingRaw; 2312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Defaulting to %s encoding for client %s\n", encodingName(cl->preferredEncoding,encBuf,sizeof(encBuf)),cl->host); 2313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else { 2315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->preferredEncoding = lastPreferredEncoding; 2316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Sticking with %s encoding for client %s\n", encodingName(cl->preferredEncoding,encBuf,sizeof(encBuf)),cl->host); 2317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 2320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 2321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (lastPreferredEncoding==-1) { 2322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Using %s encoding for client %s\n", encodingName(cl->preferredEncoding,encBuf,sizeof(encBuf)),cl->host); 2323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 2324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Switching from %s to %s Encoding for client %s\n", 2325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat encodingName(lastPreferredEncoding,encBuf2,sizeof(encBuf2)), 2326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat encodingName(cl->preferredEncoding,encBuf,sizeof(encBuf)), cl->host); 2327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->enableCursorPosUpdates && !cl->enableCursorShapeUpdates) { 2331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Disabling cursor position updates for client %s\n", 2332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->host); 2333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableCursorPosUpdates = FALSE; 2334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbFramebufferUpdateRequest: 2341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 2342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRegionPtr tmpRegion; 2343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, ((char *)&msg) + 1, 2345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbFramebufferUpdateRequestMsg-1)) <= 0) { 2346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 2347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientNormalMessage: read"); 2348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbFramebufferUpdateRequestMsg,sz_rfbFramebufferUpdateRequestMsg); 2353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* The values come in based on the scaled screen, we need to convert them to 2355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * values based on the main screen's coordinate system 2356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(!rectSwapIfLEAndClip(&msg.fur.x,&msg.fur.y,&msg.fur.w,&msg.fur.h,cl)) 2358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 2359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Warning, ignoring rfbFramebufferUpdateRequest: %dXx%dY-%dWx%dH\n",msg.fur.x, msg.fur.y, msg.fur.w, msg.fur.h); 2360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tmpRegion = 2365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnCreateRect(msg.fur.x, 2366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat msg.fur.y, 2367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat msg.fur.x+msg.fur.w, 2368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat msg.fur.y+msg.fur.h); 2369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(cl->updateMutex); 2371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnOr(cl->requestedRegion,tmpRegion); 2372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!cl->readyForSetColourMapEntries) { 2374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* client hasn't sent a SetPixelFormat so is using server's */ 2375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->readyForSetColourMapEntries = TRUE; 2376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!cl->format.trueColour) { 2377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSetClientColourMap(cl, 0, 0)) { 2378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnDestroy(tmpRegion); 2379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat TSIGNAL(cl->updateCond); 2380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->updateMutex); 2381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!msg.fur.incremental) { 2387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnOr(cl->modifiedRegion,tmpRegion); 2388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnSubtract(cl->copyRegion,tmpRegion); 2389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat TSIGNAL(cl->updateCond); 2391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->updateMutex); 2392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnDestroy(tmpRegion); 2394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbKeyEvent: 2399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, ((char *)&msg) + 1, 2401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbKeyEventMsg - 1)) <= 0) { 2402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 2403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientNormalMessage: read"); 2404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbKeyEventMsg, sz_rfbKeyEventMsg); 2409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(!cl->viewOnly) { 2411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->kbdAddEvent(msg.ke.down, (rfbKeySym)Swap32IfLE(msg.ke.key), cl); 2412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbPointerEvent: 2418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, ((char *)&msg) + 1, 2420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbPointerEventMsg - 1)) <= 0) { 2421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 2422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientNormalMessage: read"); 2423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbPointerEventMsg, sz_rfbPointerEventMsg); 2428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->screen->pointerClient && cl->screen->pointerClient != cl) 2430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2432a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (msg.pe.buttonMask == 0) 2433a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->pointerClient = NULL; 2434a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 2435a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->pointerClient = cl; 2436a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2437a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(!cl->viewOnly) { 2438a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (msg.pe.buttonMask != cl->lastPtrButtons || 2439a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->deferPtrUpdateTime == 0) { 2440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->ptrAddEvent(msg.pe.buttonMask, 2441a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ScaleX(cl->scaledScreen, cl->screen, Swap16IfLE(msg.pe.x)), 2442a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ScaleY(cl->scaledScreen, cl->screen, Swap16IfLE(msg.pe.y)), 2443a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl); 2444a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->lastPtrButtons = msg.pe.buttonMask; 2445a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 2446a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->lastPtrX = ScaleX(cl->scaledScreen, cl->screen, Swap16IfLE(msg.pe.x)); 2447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->lastPtrY = ScaleY(cl->scaledScreen, cl->screen, Swap16IfLE(msg.pe.y)); 2448a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->lastPtrButtons = msg.pe.buttonMask; 2449a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2450a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2451a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2452a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2453a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2454a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbFileTransfer: 2455a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, ((char *)&msg) + 1, 2456a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbFileTransferMsg - 1)) <= 0) { 2457a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 2458a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientNormalMessage: read"); 2459a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2460a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2461a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2462a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat msg.ft.size = Swap32IfLE(msg.ft.size); 2463a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat msg.ft.length = Swap32IfLE(msg.ft.length); 2464a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* record statistics in rfbProcessFileTransfer as length is filled with garbage when it is not valid */ 2465a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbProcessFileTransfer(cl, msg.ft.contentType, msg.ft.contentParam, msg.ft.size, msg.ft.length); 2466a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2467a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2468a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbSetSW: 2469a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, ((char *)&msg) + 1, 2470a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbSetSWMsg - 1)) <= 0) { 2471a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 2472a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientNormalMessage: read"); 2473a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2474a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2475a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2476a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat msg.sw.x = Swap16IfLE(msg.sw.x); 2477a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat msg.sw.y = Swap16IfLE(msg.sw.y); 2478a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbSetSWMsg, sz_rfbSetSWMsg); 2479a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* msg.sw.status is not initialized in the ultraVNC viewer and contains random numbers (why???) */ 2480a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2481a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Received a rfbSetSingleWindow(%d x, %d y)\n", msg.sw.x, msg.sw.y); 2482a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->screen->setSingleWindow!=NULL) 2483a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->setSingleWindow(cl, msg.sw.x, msg.sw.y); 2484a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2485a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2486a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbSetServerInput: 2487a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, ((char *)&msg) + 1, 2488a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbSetServerInputMsg - 1)) <= 0) { 2489a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 2490a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientNormalMessage: read"); 2491a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2492a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2493a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2494a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbSetServerInputMsg, sz_rfbSetServerInputMsg); 2495a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2496a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* msg.sim.pad is not initialized in the ultraVNC viewer and contains random numbers (why???) */ 2497a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* msg.sim.pad = Swap16IfLE(msg.sim.pad); */ 2498a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2499a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Received a rfbSetServerInput(%d status)\n", msg.sim.status); 2500a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->screen->setServerInput!=NULL) 2501a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->setServerInput(cl, msg.sim.status); 2502a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2503a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2504a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbTextChat: 2505a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, ((char *)&msg) + 1, 2506a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbTextChatMsg - 1)) <= 0) { 2507a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 2508a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientNormalMessage: read"); 2509a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2510a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2511a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2512a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2513a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat msg.tc.pad2 = Swap16IfLE(msg.tc.pad2); 2514a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat msg.tc.length = Swap32IfLE(msg.tc.length); 2515a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2516a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat switch (msg.tc.length) { 2517a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbTextChatOpen: 2518a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbTextChatClose: 2519a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbTextChatFinished: 2520a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* commands do not have text following */ 2521a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Why couldn't they have used the pad byte??? */ 2522a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str=NULL; 2523a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbTextChatMsg, sz_rfbTextChatMsg); 2524a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2525a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat default: 2526a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((msg.tc.length>0) && (msg.tc.length<rfbTextMaxSize)) 2527a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 2528a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = (char *)malloc(msg.tc.length); 2529a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (str==NULL) 2530a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 2531a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Unable to malloc %d bytes for a TextChat Message\n", msg.tc.length); 2532a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2533a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2534a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2535a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, str, msg.tc.length)) <= 0) { 2536a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 2537a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientNormalMessage: read"); 2538a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(str); 2539a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2540a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2541a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2542a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbTextChatMsg+msg.tc.length, sz_rfbTextChatMsg+msg.tc.length); 2543a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2544a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 2545a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 2546a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* This should never happen */ 2547a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("client sent us a Text Message that is too big %d>%d\n", msg.tc.length, rfbTextMaxSize); 2548a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2549a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2550a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2551a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2552a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2553a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Note: length can be commands: rfbTextChatOpen, rfbTextChatClose, and rfbTextChatFinished 2554a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * at which point, the str is NULL (as it is not sent) 2555a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2556a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->screen->setTextChat!=NULL) 2557a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->setTextChat(cl, msg.tc.length, str); 2558a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2559a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(str); 2560a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2561a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2562a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2563a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbClientCutText: 2564a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2565a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, ((char *)&msg) + 1, 2566a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbClientCutTextMsg - 1)) <= 0) { 2567a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 2568a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientNormalMessage: read"); 2569a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2570a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2571a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2572a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2573a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat msg.cct.length = Swap32IfLE(msg.cct.length); 2574a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2575a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat str = (char *)malloc(msg.cct.length); 25761d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman if (str == NULL) { 25771d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman rfbLogPerror("rfbProcessClientNormalMessage: not enough memory"); 25781d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman rfbCloseClient(cl); 25791d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman return; 25801d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman } 2581a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2582a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, str, msg.cct.length)) <= 0) { 2583a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 2584a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientNormalMessage: read"); 2585a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(str); 2586a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2587a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2588a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2589a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbClientCutTextMsg+msg.cct.length, sz_rfbClientCutTextMsg+msg.cct.length); 2590a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(!cl->viewOnly) { 2591a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->setXCutText(str, msg.cct.length, cl); 2592a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2593a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(str); 2594a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2595a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2596a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2597a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbPalmVNCSetScaleFactor: 2598a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->PalmVNC = TRUE; 2599a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, ((char *)&msg) + 1, 2600a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbSetScaleMsg - 1)) <= 0) { 2601a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 2602a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientNormalMessage: read"); 2603a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2604a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2605a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 26061d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman 26071d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman if (msg.ssc.scale == 0) { 26081d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman rfbLogPerror("rfbProcessClientNormalMessage: will not accept a scale factor of zero"); 26091d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman rfbCloseClient(cl); 26101d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman return; 26111d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman } 26121d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman 2613a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbSetScaleMsg, sz_rfbSetScaleMsg); 2614a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbSetScale(%d)\n", msg.ssc.scale); 2615a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScalingSetup(cl,cl->screen->width/msg.ssc.scale, cl->screen->height/msg.ssc.scale); 2616a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2617a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSendNewScaleSize(cl); 2618a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2619a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2620a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbSetScale: 2621a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2622a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, ((char *)&msg) + 1, 2623a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbSetScaleMsg - 1)) <= 0) { 2624a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 2625a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientNormalMessage: read"); 2626a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2627a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2628a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 26291d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman 26301d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman if (msg.ssc.scale == 0) { 26311d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman rfbLogPerror("rfbProcessClientNormalMessage: will not accept a scale factor of zero"); 26321d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman rfbCloseClient(cl); 26331d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman return; 26341d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman } 26351d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman 2636a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbSetScaleMsg, sz_rfbSetScaleMsg); 2637a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbSetScale(%d)\n", msg.ssc.scale); 2638a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScalingSetup(cl,cl->screen->width/msg.ssc.scale, cl->screen->height/msg.ssc.scale); 2639a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2640a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSendNewScaleSize(cl); 2641a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2642a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2643a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbXvp: 2644a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2645a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = rfbReadExact(cl, ((char *)&msg) + 1, 2646a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbXvpMsg - 1)) <= 0) { 2647a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != 0) 2648a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessClientNormalMessage: read"); 2649a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2650a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2651a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2652a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbXvpMsg, sz_rfbXvpMsg); 2653a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2654a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* only version when is defined, so echo back a fail */ 2655a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(msg.xvp.version != 1) { 2656a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSendXvp(cl, msg.xvp.version, rfbXvp_Fail); 2657a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2658a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else { 2659a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* if the hook exists and fails, send a fail msg */ 2660a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(cl->screen->xvpHook && !cl->screen->xvpHook(cl, msg.xvp.version, msg.xvp.code)) 2661a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSendXvp(cl, 1, rfbXvp_Fail); 2662a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2663a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2664a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2665a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat default: 2666a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 2667a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbExtensionData *e,*next; 2668a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2669a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(e=cl->extensions; e;) { 2670a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat next = e->next; 2671a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(e->extension->handleMessage && 2672a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat e->extension->handleMessage(cl, e->data, &msg)) 2673a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 2674a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageRcvd(cl, msg.type, 0, 0); /* Extension should handle this */ 2675a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2676a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2677a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat e = next; 2678a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2679a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2680a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("rfbProcessClientNormalMessage: unknown message type %d\n", 2681a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat msg.type); 2682a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog(" ... closing connection\n"); 2683a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 2684a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 2685a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2686a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2687a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 2688a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2689a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2690a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2691a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 2692a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbSendFramebufferUpdate - send the currently pending framebuffer update to 2693a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the RFB client. 2694a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * givenUpdateRegion is not changed. 2695a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2696a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2697a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool 2698a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbSendFramebufferUpdate(rfbClientPtr cl, 2699a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRegionPtr givenUpdateRegion) 2700a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 2701a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRectangleIterator* i=NULL; 2702a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRect rect; 2703a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int nUpdateRegionRects; 2704a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbFramebufferUpdateMsg *fu = (rfbFramebufferUpdateMsg *)cl->updateBuf; 2705a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRegionPtr updateRegion,updateCopyRegion,tmpRegion; 2706a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int dx, dy; 2707a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbBool sendCursorShape = FALSE; 2708a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbBool sendCursorPos = FALSE; 2709a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbBool sendKeyboardLedState = FALSE; 2710a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbBool sendSupportedMessages = FALSE; 2711a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbBool sendSupportedEncodings = FALSE; 2712a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbBool sendServerIdentity = FALSE; 2713a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbBool result = TRUE; 2714a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2715a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2716a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(cl->screen->displayHook) 2717a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->displayHook(cl); 2718a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2719a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2720a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * If framebuffer size was changed and the client supports NewFBSize 2721a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * encoding, just send NewFBSize marker and return. 2722a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2723a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2724a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->useNewFBSize && cl->newFBSizePending) { 2725a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(cl->updateMutex); 2726a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->newFBSizePending = FALSE; 2727a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->updateMutex); 2728a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fu->type = rfbFramebufferUpdate; 2729a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fu->nRects = Swap16IfLE(1); 2730a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->ublen = sz_rfbFramebufferUpdateMsg; 2731a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendNewFBSize(cl, cl->scaledScreen->width, cl->scaledScreen->height)) { 2732a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(cl->screen->displayFinishedHook) 2733a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->displayFinishedHook(cl, FALSE); 2734a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 2735a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2736a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat result = rfbSendUpdateBuf(cl); 2737a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(cl->screen->displayFinishedHook) 2738a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->displayFinishedHook(cl, result); 2739a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return result; 2740a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2741a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2742a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2743a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * If this client understands cursor shape updates, cursor should be 2744a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * removed from the framebuffer. Otherwise, make sure it's put up. 2745a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2746a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2747a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->enableCursorShapeUpdates) { 2748a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->cursorWasChanged && cl->readyForSetColourMapEntries) 2749a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sendCursorShape = TRUE; 2750a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2751a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2752a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2753a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Do we plan to send cursor position update? 2754a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2755a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2756a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->enableCursorPosUpdates && cl->cursorWasMoved) 2757a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sendCursorPos = TRUE; 2758a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2759a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2760a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Do we plan to send a keyboard state update? 2761a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2762a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((cl->enableKeyboardLedState) && 2763a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (cl->screen->getKeyboardLedStateHook!=NULL)) 2764a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 2765a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int x; 2766a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat x=cl->screen->getKeyboardLedStateHook(cl->screen); 2767a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (x!=cl->lastKeyboardLedState) 2768a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 2769a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sendKeyboardLedState = TRUE; 2770a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->lastKeyboardLedState=x; 2771a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2772a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2773a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2774a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2775a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Do we plan to send a rfbEncodingSupportedMessages? 2776a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2777a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->enableSupportedMessages) 2778a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 2779a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sendSupportedMessages = TRUE; 2780a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* We only send this message ONCE <per setEncodings message received> 2781a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * (We disable it here) 2782a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2783a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableSupportedMessages = FALSE; 2784a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2785a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2786a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Do we plan to send a rfbEncodingSupportedEncodings? 2787a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2788a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->enableSupportedEncodings) 2789a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 2790a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sendSupportedEncodings = TRUE; 2791a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* We only send this message ONCE <per setEncodings message received> 2792a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * (We disable it here) 2793a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2794a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableSupportedEncodings = FALSE; 2795a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2796a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2797a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Do we plan to send a rfbEncodingServerIdentity? 2798a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2799a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->enableServerIdentity) 2800a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 2801a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sendServerIdentity = TRUE; 2802a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* We only send this message ONCE <per setEncodings message received> 2803a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * (We disable it here) 2804a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2805a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->enableServerIdentity = FALSE; 2806a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2807a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2808a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(cl->updateMutex); 2809a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2810a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2811a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * The modifiedRegion may overlap the destination copyRegion. We remove 2812a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * any overlapping bits from the copyRegion (since they'd only be 2813a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * overwritten anyway). 2814a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2815a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2816a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnSubtract(cl->copyRegion,cl->modifiedRegion); 2817a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2818a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2819a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * The client is interested in the region requestedRegion. The region 2820a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * which should be updated now is the intersection of requestedRegion 2821a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * and the union of modifiedRegion and copyRegion. If it's empty then 2822a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * no update is needed. 2823a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2824a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2825a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat updateRegion = sraRgnCreateRgn(givenUpdateRegion); 2826a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(cl->screen->progressiveSliceHeight>0) { 2827a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int height=cl->screen->progressiveSliceHeight, 2828a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat y=cl->progressiveSliceY; 2829a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRegionPtr bbox=sraRgnBBox(updateRegion); 2830a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRect rect; 2831a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(sraRgnPopRect(bbox,&rect,0)) { 2832a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRegionPtr slice; 2833a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(y<rect.y1 || y>=rect.y2) 2834a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat y=rect.y1; 2835a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat slice=sraRgnCreateRect(0,y,cl->screen->width,y+height); 2836a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnAnd(updateRegion,slice); 2837a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnDestroy(slice); 2838a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2839a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnDestroy(bbox); 2840a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat y+=height; 2841a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(y>=cl->screen->height) 2842a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat y=0; 2843a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->progressiveSliceY=y; 2844a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2845a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2846a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnOr(updateRegion,cl->copyRegion); 2847a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(!sraRgnAnd(updateRegion,cl->requestedRegion) && 2848a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnEmpty(updateRegion) && 2849a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (cl->enableCursorShapeUpdates || 2850a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (cl->cursorX == cl->screen->cursorX && cl->cursorY == cl->screen->cursorY)) && 2851a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat !sendCursorShape && !sendCursorPos && !sendKeyboardLedState && 2852a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat !sendSupportedMessages && !sendSupportedEncodings && !sendServerIdentity) { 2853a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnDestroy(updateRegion); 2854a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->updateMutex); 2855a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(cl->screen->displayFinishedHook) 2856a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->displayFinishedHook(cl, TRUE); 2857a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 2858a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2859a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2860a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2861a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * We assume that the client doesn't have any pixel data outside the 2862a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * requestedRegion. In other words, both the source and destination of a 2863a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * copy must lie within requestedRegion. So the region we can send as a 2864a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * copy is the intersection of the copyRegion with both the requestedRegion 2865a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * and the requestedRegion translated by the amount of the copy. We set 2866a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * updateCopyRegion to this. 2867a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2868a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2869a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat updateCopyRegion = sraRgnCreateRgn(cl->copyRegion); 2870a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnAnd(updateCopyRegion,cl->requestedRegion); 2871a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tmpRegion = sraRgnCreateRgn(cl->requestedRegion); 2872a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnOffset(tmpRegion,cl->copyDX,cl->copyDY); 2873a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnAnd(updateCopyRegion,tmpRegion); 2874a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnDestroy(tmpRegion); 2875a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dx = cl->copyDX; 2876a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dy = cl->copyDY; 2877a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2878a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2879a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Next we remove updateCopyRegion from updateRegion so that updateRegion 2880a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * is the part of this update which is sent as ordinary pixel data (i.e not 2881a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * a copy). 2882a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2883a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2884a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnSubtract(updateRegion,updateCopyRegion); 2885a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2886a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2887a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Finally we leave modifiedRegion to be the remainder (if any) of parts of 2888a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the screen which are modified but outside the requestedRegion. We also 2889a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * empty both the requestedRegion and the copyRegion - note that we never 2890a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * carry over a copyRegion for a future update. 2891a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2892a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2893a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnOr(cl->modifiedRegion,cl->copyRegion); 2894a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnSubtract(cl->modifiedRegion,updateRegion); 2895a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnSubtract(cl->modifiedRegion,updateCopyRegion); 2896a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2897a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnMakeEmpty(cl->requestedRegion); 2898a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnMakeEmpty(cl->copyRegion); 2899a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->copyDX = 0; 2900a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->copyDY = 0; 2901a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2902a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->updateMutex); 2903a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2904a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!cl->enableCursorShapeUpdates) { 2905a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(cl->cursorX != cl->screen->cursorX || cl->cursorY != cl->screen->cursorY) { 2906a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbRedrawAfterHideCursor(cl,updateRegion); 2907a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(cl->screen->cursorMutex); 2908a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->cursorX = cl->screen->cursorX; 2909a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->cursorY = cl->screen->cursorY; 2910a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->screen->cursorMutex); 2911a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbRedrawAfterHideCursor(cl,updateRegion); 2912a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2913a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbShowCursor(cl); 2914a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2915a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2916a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* 2917a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Now send the update. 2918a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 2919a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2920a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageSent(cl, rfbFramebufferUpdate, 0, 0); 2921a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->preferredEncoding == rfbEncodingCoRRE) { 2922a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nUpdateRegionRects = 0; 2923a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2924a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(i = sraRgnGetIterator(updateRegion); sraRgnIteratorNext(i,&rect);){ 2925a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int x = rect.x1; 2926a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int y = rect.y1; 2927a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int w = rect.x2 - x; 2928a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int h = rect.y2 - y; 2929a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int rectsPerRow, rows; 2930a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* We need to count the number of rects in the scaled screen */ 2931a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->screen!=cl->scaledScreen) 2932a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScaledCorrection(cl->screen, cl->scaledScreen, &x, &y, &w, &h, "rfbSendFramebufferUpdate"); 2933a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rectsPerRow = (w-1)/cl->correMaxWidth+1; 2934a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rows = (h-1)/cl->correMaxHeight+1; 2935a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nUpdateRegionRects += rectsPerRow*rows; 2936a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2937a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnReleaseIterator(i); i=NULL; 2938a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (cl->preferredEncoding == rfbEncodingUltra) { 2939a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nUpdateRegionRects = 0; 2940a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2941a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(i = sraRgnGetIterator(updateRegion); sraRgnIteratorNext(i,&rect);){ 2942a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int x = rect.x1; 2943a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int y = rect.y1; 2944a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int w = rect.x2 - x; 2945a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int h = rect.y2 - y; 2946a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* We need to count the number of rects in the scaled screen */ 2947a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->screen!=cl->scaledScreen) 2948a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScaledCorrection(cl->screen, cl->scaledScreen, &x, &y, &w, &h, "rfbSendFramebufferUpdate"); 2949a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nUpdateRegionRects += (((h-1) / (ULTRA_MAX_SIZE( w ) / w)) + 1); 2950a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2951a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnReleaseIterator(i); i=NULL; 2952a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ 2953a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (cl->preferredEncoding == rfbEncodingZlib) { 2954a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nUpdateRegionRects = 0; 2955a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2956a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(i = sraRgnGetIterator(updateRegion); sraRgnIteratorNext(i,&rect);){ 2957a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int x = rect.x1; 2958a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int y = rect.y1; 2959a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int w = rect.x2 - x; 2960a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int h = rect.y2 - y; 2961a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* We need to count the number of rects in the scaled screen */ 2962a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->screen!=cl->scaledScreen) 2963a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScaledCorrection(cl->screen, cl->scaledScreen, &x, &y, &w, &h, "rfbSendFramebufferUpdate"); 2964a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nUpdateRegionRects += (((h-1) / (ZLIB_MAX_SIZE( w ) / w)) + 1); 2965a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2966a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnReleaseIterator(i); i=NULL; 2967a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG 2968a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (cl->preferredEncoding == rfbEncodingTight) { 2969a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nUpdateRegionRects = 0; 2970a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2971a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(i = sraRgnGetIterator(updateRegion); sraRgnIteratorNext(i,&rect);){ 2972a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int x = rect.x1; 2973a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int y = rect.y1; 2974a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int w = rect.x2 - x; 2975a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int h = rect.y2 - y; 2976a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int n; 2977a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* We need to count the number of rects in the scaled screen */ 2978a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->screen!=cl->scaledScreen) 2979a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScaledCorrection(cl->screen, cl->scaledScreen, &x, &y, &w, &h, "rfbSendFramebufferUpdate"); 2980a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat n = rfbNumCodedRectsTight(cl, x, y, w, h); 2981a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n == 0) { 2982a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nUpdateRegionRects = 0xFFFF; 2983a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 2984a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2985a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nUpdateRegionRects += n; 2986a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 2987a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnReleaseIterator(i); i=NULL; 2988a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 2989a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 2990a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if defined(LIBVNCSERVER_HAVE_LIBJPEG) && defined(LIBVNCSERVER_HAVE_LIBPNG) 2991a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if (cl->preferredEncoding == rfbEncodingTightPng) { 2992a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nUpdateRegionRects = 0; 2993a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 2994a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(i = sraRgnGetIterator(updateRegion); sraRgnIteratorNext(i,&rect);){ 2995a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int x = rect.x1; 2996a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int y = rect.y1; 2997a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int w = rect.x2 - x; 2998a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int h = rect.y2 - y; 2999a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int n; 3000a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* We need to count the number of rects in the scaled screen */ 3001a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->screen!=cl->scaledScreen) 3002a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScaledCorrection(cl->screen, cl->scaledScreen, &x, &y, &w, &h, "rfbSendFramebufferUpdate"); 3003a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat n = rfbNumCodedRectsTight(cl, x, y, w, h); 3004a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n == 0) { 3005a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nUpdateRegionRects = 0xFFFF; 3006a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 3007a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3008a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nUpdateRegionRects += n; 3009a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3010a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnReleaseIterator(i); i=NULL; 3011a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 3012a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 3013a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nUpdateRegionRects = sraRgnCountRects(updateRegion); 3014a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3015a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3016a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fu->type = rfbFramebufferUpdate; 3017a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (nUpdateRegionRects != 0xFFFF) { 3018a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(cl->screen->maxRectsPerUpdate>0 3019a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* CoRRE splits the screen into smaller squares */ 3020a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat && cl->preferredEncoding != rfbEncodingCoRRE 3021a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Ultra encoding splits rectangles up into smaller chunks */ 3022a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat && cl->preferredEncoding != rfbEncodingUltra 3023a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ 3024a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Zlib encoding splits rectangles up into smaller chunks */ 3025a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat && cl->preferredEncoding != rfbEncodingZlib 3026a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBJPEG 3027a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Tight encoding counts the rectangles differently */ 3028a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat && cl->preferredEncoding != rfbEncodingTight 3029a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 3030a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 3031a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBPNG 3032a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Tight encoding counts the rectangles differently */ 3033a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat && cl->preferredEncoding != rfbEncodingTightPng 3034a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 3035a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat && nUpdateRegionRects>cl->screen->maxRectsPerUpdate) { 3036a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRegion* newUpdateRegion = sraRgnBBox(updateRegion); 3037a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnDestroy(updateRegion); 3038a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat updateRegion = newUpdateRegion; 3039a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nUpdateRegionRects = sraRgnCountRects(updateRegion); 3040a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3041a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fu->nRects = Swap16IfLE((uint16_t)(sraRgnCountRects(updateCopyRegion) + 3042a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nUpdateRegionRects + 3043a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat !!sendCursorShape + !!sendCursorPos + !!sendKeyboardLedState + 3044a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat !!sendSupportedMessages + !!sendSupportedEncodings + !!sendServerIdentity)); 3045a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 3046a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fu->nRects = 0xFFFF; 3047a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3048a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->ublen = sz_rfbFramebufferUpdateMsg; 3049a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3050a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sendCursorShape) { 3051a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->cursorWasChanged = FALSE; 3052a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendCursorShape(cl)) 3053a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto updateFailed; 3054a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3055a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3056a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sendCursorPos) { 3057a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->cursorWasMoved = FALSE; 3058a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendCursorPos(cl)) 3059a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto updateFailed; 3060a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3061a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3062a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sendKeyboardLedState) { 3063a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendKeyboardLedState(cl)) 3064a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto updateFailed; 3065a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3066a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3067a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sendSupportedMessages) { 3068a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendSupportedMessages(cl)) 3069a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto updateFailed; 3070a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3071a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sendSupportedEncodings) { 3072a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendSupportedEncodings(cl)) 3073a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto updateFailed; 3074a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3075a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sendServerIdentity) { 3076a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendServerIdentity(cl)) 3077a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto updateFailed; 3078a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3079a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3080a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!sraRgnEmpty(updateCopyRegion)) { 3081a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendCopyRegion(cl,updateCopyRegion,dx,dy)) 3082a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto updateFailed; 3083a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3084a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3085a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(i = sraRgnGetIterator(updateRegion); sraRgnIteratorNext(i,&rect);){ 3086a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int x = rect.x1; 3087a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int y = rect.y1; 3088a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int w = rect.x2 - x; 3089a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int h = rect.y2 - y; 3090a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3091a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* We need to count the number of rects in the scaled screen */ 3092a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->screen!=cl->scaledScreen) 3093a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScaledCorrection(cl->screen, cl->scaledScreen, &x, &y, &w, &h, "rfbSendFramebufferUpdate"); 3094a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3095a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat switch (cl->preferredEncoding) { 3096a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case -1: 3097a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingRaw: 3098a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendRectEncodingRaw(cl, x, y, w, h)) 3099a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto updateFailed; 3100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 3101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingRRE: 3102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendRectEncodingRRE(cl, x, y, w, h)) 3103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto updateFailed; 3104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 3105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingCoRRE: 3106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendRectEncodingCoRRE(cl, x, y, w, h)) 3107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto updateFailed; 3108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 3109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingHextile: 3110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendRectEncodingHextile(cl, x, y, w, h)) 3111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto updateFailed; 3112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 3113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingUltra: 3114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendRectEncodingUltra(cl, x, y, w, h)) 3115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto updateFailed; 3116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 3117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ 3118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingZlib: 3119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendRectEncodingZlib(cl, x, y, w, h)) 3120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto updateFailed; 3121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 3122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingZRLE: 3123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingZYWRLE: 3124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendRectEncodingZRLE(cl, x, y, w, h)) 3125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto updateFailed; 3126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 3127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 3128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if defined(LIBVNCSERVER_HAVE_LIBJPEG) && (defined(LIBVNCSERVER_HAVE_LIBZ) || defined(LIBVNCSERVER_HAVE_LIBPNG)) 3129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingTight: 3130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendRectEncodingTight(cl, x, y, w, h)) 3131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto updateFailed; 3132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 3133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBPNG 3134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbEncodingTightPng: 3135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendRectEncodingTightPng(cl, x, y, w, h)) 3136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto updateFailed; 3137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 3138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 3139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 3140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (i) { 3143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnReleaseIterator(i); 3144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i = NULL; 3145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( nUpdateRegionRects == 0xFFFF && 3148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat !rfbSendLastRectMarker(cl) ) 3149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat goto updateFailed; 3150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendUpdateBuf(cl)) { 3152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatupdateFailed: 3153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat result = FALSE; 3154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!cl->enableCursorShapeUpdates) { 3157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbHideCursor(cl); 3158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(i) 3161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnReleaseIterator(i); 3162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnDestroy(updateRegion); 3163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnDestroy(updateCopyRegion); 3164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(cl->screen->displayFinishedHook) 3166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->displayFinishedHook(cl, result); 3167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return result; 3168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 3169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 3172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Send the copy region as a string of CopyRect encoded rectangles. 3173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * The only slightly tricky thing is that we should send the messages in 3174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the correct order so that an earlier CopyRect will not corrupt the source 3175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * of a later one. 3176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 3177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool 3179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbSendCopyRegion(rfbClientPtr cl, 3180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRegionPtr reg, 3181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int dx, 3182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int dy) 3183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 3184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int x, y, w, h; 3185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbFramebufferUpdateRectHeader rect; 3186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCopyRect cr; 3187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRectangleIterator* i; 3188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRect rect1; 3189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* printf("copyrect: "); sraRgnPrint(reg); putchar('\n');fflush(stdout); */ 3191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i = sraRgnGetReverseIterator(reg,dx>0,dy>0); 3192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* correct for the scale of the screen */ 3194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dx = ScaleX(cl->screen, cl->scaledScreen, dx); 3195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dy = ScaleX(cl->screen, cl->scaledScreen, dy); 3196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while(sraRgnIteratorNext(i,&rect1)) { 3198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat x = rect1.x1; 3199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat y = rect1.y1; 3200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat w = rect1.x2 - x; 3201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat h = rect1.y2 - y; 3202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* correct for scaling (if necessary) */ 3204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScaledCorrection(cl->screen, cl->scaledScreen, &x, &y, &w, &h, "copyrect"); 3205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.x = Swap16IfLE(x); 3207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.y = Swap16IfLE(y); 3208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.w = Swap16IfLE(w); 3209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.h = Swap16IfLE(h); 3210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.encoding = Swap32IfLE(rfbEncodingCopyRect); 3211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy(&cl->updateBuf[cl->ublen], (char *)&rect, 3213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbFramebufferUpdateRectHeader); 3214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->ublen += sz_rfbFramebufferUpdateRectHeader; 3215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cr.srcX = Swap16IfLE(x - dx); 3217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cr.srcY = Swap16IfLE(y - dy); 3218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy(&cl->updateBuf[cl->ublen], (char *)&cr, sz_rfbCopyRect); 3220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->ublen += sz_rfbCopyRect; 3221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordEncodingSent(cl, rfbEncodingCopyRect, sz_rfbFramebufferUpdateRectHeader + sz_rfbCopyRect, 3223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat w * h * (cl->scaledScreen->bitsPerPixel / 8)); 3224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sraRgnReleaseIterator(i); 3226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 3228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 3229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 3231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Send a given rectangle in raw encoding (rfbEncodingRaw). 3232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 3233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool 3235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbSendRectEncodingRaw(rfbClientPtr cl, 3236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int x, 3237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int y, 3238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int w, 3239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int h) 3240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 3241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbFramebufferUpdateRectHeader rect; 3242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int nlines; 3243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int bytesPerLine = w * (cl->format.bitsPerPixel / 8); 3244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *fbptr = (cl->scaledScreen->frameBuffer + (cl->scaledScreen->paddedWidthInBytes * y) 3245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat + (x * (cl->scaledScreen->bitsPerPixel / 8))); 3246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Flush the buffer to guarantee correct alignment for translateFn(). */ 3248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->ublen > 0) { 3249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendUpdateBuf(cl)) 3250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 3251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.x = Swap16IfLE(x); 3254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.y = Swap16IfLE(y); 3255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.w = Swap16IfLE(w); 3256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.h = Swap16IfLE(h); 3257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.encoding = Swap32IfLE(rfbEncodingRaw); 3258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader); 3260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->ublen += sz_rfbFramebufferUpdateRectHeader; 3261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordEncodingSent(cl, rfbEncodingRaw, sz_rfbFramebufferUpdateRectHeader + bytesPerLine * h, 3264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbFramebufferUpdateRectHeader + bytesPerLine * h); 3265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nlines = (UPDATE_BUF_SIZE - cl->ublen) / bytesPerLine; 3267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (TRUE) { 3269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (nlines > h) 3270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nlines = h; 3271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (*cl->translateFn)(cl->translateLookupTable, 3273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat &(cl->screen->serverFormat), 3274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat &cl->format, fbptr, &cl->updateBuf[cl->ublen], 3275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->scaledScreen->paddedWidthInBytes, w, nlines); 3276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->ublen += nlines * bytesPerLine; 3278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat h -= nlines; 3279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (h == 0) /* rect fitted in buffer, do next one */ 3281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 3282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* buffer full - flush partial rect and do another nlines */ 3284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendUpdateBuf(cl)) 3286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 3287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fbptr += (cl->scaledScreen->paddedWidthInBytes * nlines); 3289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat nlines = (UPDATE_BUF_SIZE - cl->ublen) / bytesPerLine; 3291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (nlines == 0) { 3292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbErr("rfbSendRectEncodingRaw: send buffer too small for %d " 3293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "bytes per line\n", bytesPerLine); 3294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 3295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 3296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 3299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 3303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Send an empty rectangle with encoding field set to value of 3304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbEncodingLastRect to notify client that this is the last 3305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rectangle in framebuffer update ("LastRect" extension of RFB 3306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * protocol). 3307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 3308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool 3310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbSendLastRectMarker(rfbClientPtr cl) 3311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 3312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbFramebufferUpdateRectHeader rect; 3313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) { 3315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendUpdateBuf(cl)) 3316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 3317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.encoding = Swap32IfLE(rfbEncodingLastRect); 3320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.x = 0; 3321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.y = 0; 3322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.w = 0; 3323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.h = 0; 3324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader); 3326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->ublen += sz_rfbFramebufferUpdateRectHeader; 3327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordEncodingSent(cl, rfbEncodingLastRect, sz_rfbFramebufferUpdateRectHeader, sz_rfbFramebufferUpdateRectHeader); 3330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 3332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 3333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 3336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Send NewFBSize pseudo-rectangle. This tells the client to change 3337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * its framebuffer size. 3338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 3339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool 3341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbSendNewFBSize(rfbClientPtr cl, 3342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int w, 3343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int h) 3344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 3345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbFramebufferUpdateRectHeader rect; 3346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) { 3348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!rfbSendUpdateBuf(cl)) 3349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 3350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (cl->PalmVNC==TRUE) 3353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Sending rfbEncodingNewFBSize in response to a PalmVNC style framebuffer resize (%dx%d)\n", w, h); 3354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 3355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLog("Sending rfbEncodingNewFBSize for resize to (%dx%d)\n", w, h); 3356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.encoding = Swap32IfLE(rfbEncodingNewFBSize); 3358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.x = 0; 3359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.y = 0; 3360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.w = Swap16IfLE(w); 3361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rect.r.h = Swap16IfLE(h); 3362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy(&cl->updateBuf[cl->ublen], (char *)&rect, 3364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbFramebufferUpdateRectHeader); 3365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->ublen += sz_rfbFramebufferUpdateRectHeader; 3366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordEncodingSent(cl, rfbEncodingNewFBSize, sz_rfbFramebufferUpdateRectHeader, sz_rfbFramebufferUpdateRectHeader); 3368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 3370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 3371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 3374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Send the contents of cl->updateBuf. Returns 1 if successful, -1 if 3375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * not (errno should be set). 3376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 3377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool 3379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbSendUpdateBuf(rfbClientPtr cl) 3380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 3381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(cl->sock<0) 3382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 3383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, cl->updateBuf, cl->ublen) < 0) { 3385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbSendUpdateBuf: write"); 3386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 3387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 3388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->ublen = 0; 3391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 3392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 3393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 3395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbSendSetColourMapEntries sends a SetColourMapEntries message to the 3396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * client, using values from the currently installed colormap. 3397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 3398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbBool 3400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbSendSetColourMapEntries(rfbClientPtr cl, 3401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int firstColour, 3402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int nColours) 3403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 3404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char buf[sz_rfbSetColourMapEntriesMsg + 256 * 3 * 2]; 3405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char *wbuf = buf; 3406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSetColourMapEntriesMsg *scme; 3407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint16_t *rgb; 3408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbColourMap* cm = &cl->screen->colourMap; 3409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i, len; 3410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (nColours > 256) { 3412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* some rare hardware has, e.g., 4096 colors cells: PseudoColor:12 */ 3413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat wbuf = (char *) malloc(sz_rfbSetColourMapEntriesMsg + nColours * 3 * 2); 3414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat scme = (rfbSetColourMapEntriesMsg *)wbuf; 3417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rgb = (uint16_t *)(&wbuf[sz_rfbSetColourMapEntriesMsg]); 3418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat scme->type = rfbSetColourMapEntries; 3420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat scme->firstColour = Swap16IfLE(firstColour); 3422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat scme->nColours = Swap16IfLE(nColours); 3423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat len = sz_rfbSetColourMapEntriesMsg; 3425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < nColours; i++) { 3427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(i<(int)cm->count) { 3428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(cm->is16) { 3429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rgb[i*3] = Swap16IfLE(cm->data.shorts[i*3]); 3430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rgb[i*3+1] = Swap16IfLE(cm->data.shorts[i*3+1]); 3431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rgb[i*3+2] = Swap16IfLE(cm->data.shorts[i*3+2]); 3432a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 3433a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rgb[i*3] = Swap16IfLE((unsigned short)cm->data.bytes[i*3]); 3434a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rgb[i*3+1] = Swap16IfLE((unsigned short)cm->data.bytes[i*3+1]); 3435a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rgb[i*3+2] = Swap16IfLE((unsigned short)cm->data.bytes[i*3+2]); 3436a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3437a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3438a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3439a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat len += nColours * 3 * 2; 3441a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3442a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(cl->sendMutex); 3443a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, wbuf, len) < 0) { 3444a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbSendSetColourMapEntries: write"); 3445a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 3446a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (wbuf != buf) free(wbuf); 3447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->sendMutex); 3448a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 3449a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3450a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->sendMutex); 3451a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3452a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageSent(cl, rfbSetColourMapEntries, len, len); 3453a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (wbuf != buf) free(wbuf); 3454a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 3455a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 3456a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3457a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 3458a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbSendBell sends a Bell message to all the clients. 3459a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 3460a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3461a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 3462a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbSendBell(rfbScreenInfoPtr rfbScreen) 3463a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 3464a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientIteratorPtr i; 3465a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientPtr cl; 3466a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbBellMsg b; 3467a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3468a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i = rfbGetClientIterator(rfbScreen); 3469a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while((cl=rfbClientIteratorNext(i))) { 3470a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat b.type = rfbBell; 3471a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(cl->sendMutex); 3472a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, (char *)&b, sz_rfbBellMsg) < 0) { 3473a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbSendBell: write"); 3474a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 3475a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3476a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->sendMutex); 3477a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3478a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageSent(cl, rfbBell, sz_rfbBellMsg, sz_rfbBellMsg); 3479a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbReleaseClientIterator(i); 3480a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 3481a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3482a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3483a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 3484a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbSendServerCutText sends a ServerCutText message to all the clients. 3485a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 3486a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3487a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 3488a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbSendServerCutText(rfbScreenInfoPtr rfbScreen,char *str, int len) 3489a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 3490a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientPtr cl; 3491a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbServerCutTextMsg sct; 3492a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientIteratorPtr iterator; 3493a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3494a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat iterator = rfbGetClientIterator(rfbScreen); 3495a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while ((cl = rfbClientIteratorNext(iterator)) != NULL) { 3496a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sct.type = rfbServerCutText; 3497a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sct.length = Swap32IfLE(len); 3498a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat LOCK(cl->sendMutex); 3499a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, (char *)&sct, 3500a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sz_rfbServerCutTextMsg) < 0) { 3501a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbSendServerCutText: write"); 3502a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 3503a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->sendMutex); 3504a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat continue; 3505a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3506a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (rfbWriteExact(cl, str, len) < 0) { 3507a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbSendServerCutText: write"); 3508a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbCloseClient(cl); 3509a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3510a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat UNLOCK(cl->sendMutex); 3511a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbStatRecordMessageSent(cl, rfbServerCutText, sz_rfbServerCutTextMsg+len, sz_rfbServerCutTextMsg+len); 3512a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3513a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbReleaseClientIterator(iterator); 3514a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 3515a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3516a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/***************************************************************************** 3517a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 3518a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * UDP can be used for keyboard and pointer events when the underlying 3519a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * network is highly reliable. This is really here to support ORL's 3520a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * videotile, whose TCP implementation doesn't like sending lots of small 3521a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * packets (such as 100s of pen readings per second!). 3522a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 3523a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3524a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic unsigned char ptrAcceleration = 50; 3525a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3526a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 3527a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbNewUDPConnection(rfbScreenInfoPtr rfbScreen, 3528a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int sock) 3529a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 3530a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (write(sock, (char*) &ptrAcceleration, 1) < 0) { 3531a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbNewUDPConnection: write"); 3532a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3533a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 3534a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3535a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 3536a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Because UDP is a message based service, we can't read the first byte and 3537a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * then the rest of the packet separately like we do with TCP. We will always 3538a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * get a whole packet delivered in one go, so we ask read() for the maximum 3539a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * number of bytes we can possibly get. 3540a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 3541a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3542a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 3543a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatrfbProcessUDPInput(rfbScreenInfoPtr rfbScreen) 3544a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 3545a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int n; 3546a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientPtr cl=rfbScreen->udpClient; 3547a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientToServerMsg msg; 3548a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3549a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if((!cl) || cl->onHold) 3550a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 3551a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3552a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((n = read(rfbScreen->udpSock, (char *)&msg, sizeof(msg))) <= 0) { 3553a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n < 0) { 3554a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbLogPerror("rfbProcessUDPInput: read"); 3555a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3556a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbDisconnectUDPSock(rfbScreen); 3557a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 3558a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3559a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3560a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat switch (msg.type) { 3561a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3562a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbKeyEvent: 3563a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != sz_rfbKeyEventMsg) { 3564a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbErr("rfbProcessUDPInput: key event incorrect length\n"); 3565a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbDisconnectUDPSock(rfbScreen); 3566a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 3567a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3568a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->kbdAddEvent(msg.ke.down, (rfbKeySym)Swap32IfLE(msg.ke.key), cl); 3569a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 3570a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3571a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case rfbPointerEvent: 3572a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (n != sz_rfbPointerEventMsg) { 3573a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbErr("rfbProcessUDPInput: ptr event incorrect length\n"); 3574a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbDisconnectUDPSock(rfbScreen); 3575a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 3576a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3577a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cl->screen->ptrAddEvent(msg.pe.buttonMask, 3578a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat Swap16IfLE(msg.pe.x), Swap16IfLE(msg.pe.y), cl); 3579a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 3580a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3581a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat default: 3582a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbErr("rfbProcessUDPInput: unknown message type %d\n", 3583a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat msg.type); 3584a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbDisconnectUDPSock(rfbScreen); 3585a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 3586a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 3587a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3588a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3589