1
0
mirror of https://invent.kde.org/network/krfb synced 2024-07-05 09:28:35 +00:00

sync with libvncserver cvs: solaris fixes, sync with TightVNC 1.2.3, memory leaks fixed

svn path=/trunk/kdenetwork/krfb/; revision=153790
This commit is contained in:
Tim Jansen 2002-05-04 18:27:17 +00:00
parent 842c3a55cc
commit 8d2687fad3
14 changed files with 491 additions and 203 deletions

View File

@ -1,8 +1,13 @@
memory leaks squashed (localtime pseudo leak is still there :-)
small improvements for OSXvnc (still not working correctly)
synced with TightVNC 1.2.3
solaris compile cleanups
many x11vnc improvements
added backchannel, an encoding which needs special clients to pass
arbitrary data to the client
changes from Tim Jansen regarding multi threading and client blocking
as well as C++ compliancy
x11vnc can be controlled by restarting with special options if compiling
x11vnc can be controlled by starting again with special options if compiling
with LOCAL_CONTROL defined
0.3
added x11vnc, a x0rfbserver clone

View File

@ -14,7 +14,8 @@
#include "rfb.h"
void rfbUsage(void)
void
rfbUsage(void)
{
fprintf(stderr, "-rfbport port TCP port for RFB protocol\n");
fprintf(stderr, "-rfbwait time max time in ms to wait for RFB client\n");
@ -34,6 +35,17 @@ void rfbUsage(void)
exit(1);
}
/* purges COUNT arguments from ARGV at POSITION and decrements ARGC.
POSITION points to the first non purged argument afterwards. */
void rfbPurgeArguments(int* argc,int* position,int count,char *argv[])
{
int amount=(*argc)-(*position)-count;
if(amount)
memmove(argv+(*position),argv+(*position)+count,sizeof(char*)*amount);
(*argc)-=count;
(*position)--;
}
void
rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[])
{
@ -79,25 +91,21 @@ rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[])
rfbScreen->height = atoi(argv[++i]);
} else {
/* we just remove the processed arguments from the list */
if(i != i1) {
memmove(argv+i1,argv+i,sizeof(char*)*(*argc-i));
*argc -= i-i1;
}
if(i != i1)
rfbPurgeArguments(argc,&i,i1-i,argv);
i1++;
i = i1-1;
i++;
}
}
*argc -= i-i1;
}
/*
static void rfbSizeUsage()
void rfbSizeUsage()
{
fprintf(stderr, "-width sets the width of the framebuffer\n");
fprintf(stderr, "-height sets the height of the framebuffer\n");
exit(1);
}
*/
void
rfbProcessSizeArguments(int* width,int* height,int* bpp,int* argc, char *argv[])

View File

@ -143,7 +143,7 @@ rfbSendCursorShape(cl)
bpp2=cl->format.bitsPerPixel/8;
(*cl->translateFn)(cl->translateLookupTable,
&(cl->screen->rfbServerFormat),
&cl->format, (char*)pCursor->richSource,
&cl->format, pCursor->richSource,
&cl->updateBuf[cl->ublen],
pCursor->width*bpp1, pCursor->width, pCursor->height);
@ -241,7 +241,7 @@ rfbCursorPtr rfbMakeXCursor(int width,int height,char* cursorString,char* maskSt
for(i=0,bit=0x80;i<width;i++,bit=(bit&1)?0x80:bit>>1,cp++)
if(*cp!=' ') cursor->mask[j*w+i/8]|=bit;
} else
cursor->mask = (unsigned char*)rfbMakeMaskForXCursor(width,height,(char*)cursor->source);
cursor->mask = (unsigned char*)rfbMakeMaskForXCursor(width,height,cursor->source);
return(cursor);
}
@ -272,6 +272,8 @@ char* rfbMakeMaskForXCursor(int width,int height,char* source)
void rfbFreeCursor(rfbCursorPtr cursor)
{
if(cursor) {
if(cursor->richSource)
free(cursor->richSource);
free(cursor->source);
free(cursor->mask);
free(cursor);
@ -308,12 +310,12 @@ void MakeRichCursorFromXCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor)
rfbPixelFormat* format=&rfbScreen->rfbServerFormat;
int i,j,w=(cursor->width+7)/8,bpp=format->bitsPerPixel/8;
CARD32 background,foreground;
char *cp,*back=(char*)&background,*fore=(char*)&foreground;
char *back=(char*)&background,*fore=(char*)&foreground;
unsigned char *cp;
unsigned char bit;
cp=(char*)calloc(cursor->width*bpp,cursor->height);
cursor->richSource = (unsigned char*) cp;
cp=cursor->richSource=(unsigned char*)calloc(cursor->width*bpp,cursor->height);
if(format->bigEndian) {
back+=4-bpp;
fore+=4-bpp;
@ -435,8 +437,8 @@ void rfbDrawCursor(rfbScreenInfoPtr s)
}
/* for debugging */
/*
static void rfbPrintXCursor(rfbCursorPtr cursor)
void rfbPrintXCursor(rfbCursorPtr cursor)
{
int i,i1,j,w=(cursor->width+7)/8;
unsigned char bit;
@ -449,7 +451,6 @@ static void rfbPrintXCursor(rfbCursorPtr cursor)
putchar('\n');
}
}
*/
extern void rfbSetCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr c,Bool freeOld)
{

View File

@ -296,8 +296,13 @@ subrectEncode##bpp(rfbClientPtr cl, CARD##bpp *data, int w, int h,
*/ \
\
static void \
testColours##bpp(CARD##bpp *data, int size, Bool *mono, Bool *solid, \
CARD##bpp *bg, CARD##bpp* fg) \
testColours##bpp(data,size,mono,solid,bg,fg) \
CARD##bpp *data; \
int size; \
Bool *mono; \
Bool *solid; \
CARD##bpp *bg; \
CARD##bpp *fg; \
{ \
CARD##bpp colour1 = 0, colour2 = 0; \
int n1 = 0, n2 = 0; \

View File

@ -39,6 +39,10 @@
#include <fcntl.h>
#include <errno.h>
#ifdef USE_LIBWRAP
#include <tcpd.h>
#endif
#include "rfb.h"
#define NOT_FOUND_STR "HTTP/1.0 404 Not found\n\n" \
@ -47,7 +51,7 @@
#define OK_STR "HTTP/1.0 200 OK\nContent-Type: text/html\n\n"
static void httpProcessInput(rfbScreenInfoPtr rfbScreen);
static void httpProcessInput();
static Bool compareAndSkip(char **ptr, const char *str);
/*
@ -62,6 +66,7 @@ FILE* httpFP = NULL;
#define BUF_SIZE 32768
static char buf[BUF_SIZE];
static size_t buf_filled=0;
/*
@ -137,6 +142,7 @@ httpCheckFds(rfbScreenInfoPtr rfbScreen)
}
if (FD_ISSET(rfbScreen->httpListenSock, &fds)) {
int flags;
if (rfbScreen->httpSock >= 0) close(rfbScreen->httpSock);
if ((rfbScreen->httpSock = accept(rfbScreen->httpListenSock,
@ -144,12 +150,27 @@ httpCheckFds(rfbScreenInfoPtr rfbScreen)
rfbLogPerror("httpCheckFds: accept");
return;
}
#ifdef USE_LIBWRAP
if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
STRING_UNKNOWN)) {
rfbLog("Rejected connection from client %s\n",
inet_ntoa(addr.sin_addr));
#else
if ((rfbScreen->httpFP = fdopen(rfbScreen->httpSock, "r+")) == NULL) {
rfbLogPerror("httpCheckFds: fdopen");
#endif
close(rfbScreen->httpSock);
rfbScreen->httpSock = -1;
return;
}
flags=fcntl(rfbScreen->httpSock,F_GETFL);
if(flags==-1 ||
fcntl(rfbScreen->httpSock,F_SETFL,flags|O_NONBLOCK)==-1) {
rfbLogPerror("httpCheckFds: fcntl");
close(rfbScreen->httpSock);
rfbScreen->httpSock=-1;
return;
}
/*AddEnabledDevice(httpSock);*/
}
@ -180,11 +201,10 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
char *fname;
unsigned int maxFnameLen;
FILE* fd;
Bool gotGet = FALSE;
Bool performSubstitutions = FALSE;
char str[256];
#ifndef WIN32
struct passwd *user = getpwuid(getuid());;
struct passwd *user = getpwuid(getuid());
#endif
cl.sock=rfbScreen->httpSock;
@ -198,66 +218,74 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
fname = &fullFname[strlen(fullFname)];
maxFnameLen = 255 - strlen(fullFname);
buf[0] = '\0';
/* Read data from the HTTP client until we get a complete request. */
while (1) {
ssize_t got = read (rfbScreen->httpSock, buf + buf_filled,
sizeof (buf) - buf_filled - 1);
/* Read lines from the HTTP client until a blank line. The only
line we need to parse is the line "GET <filename> ..." */
if (!fgets(buf, BUF_SIZE, rfbScreen->httpFP)) {
rfbLogPerror("httpProcessInput: fgets");
if (got <= 0) {
if (got == 0) {
rfbLog("httpd: premature connection close\n");
} else {
if (errno == EAGAIN) {
return;
}
rfbLogPerror("httpProcessInput: read");
}
httpCloseSock(rfbScreen);
return;
}
if ((strcmp(buf,"\n") == 0) || (strcmp(buf,"\r\n") == 0)
|| (strcmp(buf,"\r") == 0) || (strcmp(buf,"\n\r") == 0))
/* end of client request */
buf_filled += got;
buf[buf_filled] = '\0';
/* Is it complete yet (is there a blank line)? */
if (strstr (buf, "\r\r") || strstr (buf, "\n\n") ||
strstr (buf, "\r\n\r\n") || strstr (buf, "\n\r\n\r"))
break;
if (strncmp(buf, "GET ", 4) == 0) {
gotGet = TRUE;
if (strlen(buf) > maxFnameLen) {
rfbLog("GET line too long\n");
httpCloseSock(rfbScreen);
return;
}
if (sscanf(buf, "GET %s HTTP/1.0", fname) != 1) {
rfbLog("couldn't parse GET line\n");
httpCloseSock(rfbScreen);
return;
}
if (fname[0] != '/') {
rfbLog("filename didn't begin with '/'\n");
WriteExact(&cl, NOT_FOUND_STR, strlen(NOT_FOUND_STR));
httpCloseSock(rfbScreen);
return;
}
if (strchr(fname+1, '/') != NULL) {
rfbLog("asking for file in other directory\n");
WriteExact(&cl, NOT_FOUND_STR, strlen(NOT_FOUND_STR));
httpCloseSock(rfbScreen);
return;
}
getpeername(rfbScreen->httpSock, (struct sockaddr *)&addr, &addrlen);
rfbLog("httpd: get '%s' for %s\n", fname+1,
inet_ntoa(addr.sin_addr));
continue;
}
}
if (!gotGet) {
/* Process the request. */
if (strncmp(buf, "GET ", 4)) {
rfbLog("no GET line\n");
httpCloseSock(rfbScreen);
return;
} else {
/* Only use the first line. */
buf[strcspn(buf, "\n\r")] = '\0';
}
if (strlen(buf) > maxFnameLen) {
rfbLog("GET line too long\n");
httpCloseSock(rfbScreen);
return;
}
if (sscanf(buf, "GET %s HTTP/1.0", fname) != 1) {
rfbLog("couldn't parse GET line\n");
httpCloseSock(rfbScreen);
return;
}
if (fname[0] != '/') {
rfbLog("filename didn't begin with '/'\n");
WriteExact(&cl, NOT_FOUND_STR, strlen(NOT_FOUND_STR));
httpCloseSock(rfbScreen);
return;
}
if (strchr(fname+1, '/') != NULL) {
rfbLog("asking for file in other directory\n");
WriteExact(&cl, NOT_FOUND_STR, strlen(NOT_FOUND_STR));
httpCloseSock(rfbScreen);
return;
}
getpeername(rfbScreen->httpSock, (struct sockaddr *)&addr, &addrlen);
rfbLog("httpd: get '%s' for %s\n", fname+1,
inet_ntoa(addr.sin_addr));
/* If we were asked for '/', actually read the file index.vnc */
if (strcmp(fname, "/") == 0) {
@ -273,11 +301,11 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
/* Open the file */
if (!(fd = fopen(fullFname, "r"))) {
rfbLogPerror("httpProcessInput: open");
WriteExact(&cl, NOT_FOUND_STR, strlen(NOT_FOUND_STR));
httpCloseSock(rfbScreen);
return;
if ((fd = fopen(fullFname, "r")) <= 0) {
rfbLogPerror("httpProcessInput: open");
WriteExact(&cl, NOT_FOUND_STR, strlen(NOT_FOUND_STR));
httpCloseSock(rfbScreen);
return;
}
WriteExact(&cl, OK_STR, strlen(OK_STR));

View File

@ -43,8 +43,176 @@
#include "rfb.h"
#include "keysym.h"
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <IOKit/pwr_mgt/IOPM.h>
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
Bool rfbNoDimming = FALSE;
Bool rfbNoSleep = TRUE;
static pthread_mutex_t dimming_mutex;
static unsigned long dim_time;
static unsigned long sleep_time;
static mach_port_t master_dev_port;
static io_connect_t power_mgt;
static Bool initialized = FALSE;
static Bool dim_time_saved = FALSE;
static Bool sleep_time_saved = FALSE;
static int
saveDimSettings(void)
{
if (IOPMGetAggressiveness(power_mgt,
kPMMinutesToDim,
&dim_time) != kIOReturnSuccess)
return -1;
dim_time_saved = TRUE;
return 0;
}
static int
restoreDimSettings(void)
{
if (!dim_time_saved)
return -1;
if (IOPMSetAggressiveness(power_mgt,
kPMMinutesToDim,
dim_time) != kIOReturnSuccess)
return -1;
dim_time_saved = FALSE;
dim_time = 0;
return 0;
}
static int
saveSleepSettings(void)
{
if (IOPMGetAggressiveness(power_mgt,
kPMMinutesToSleep,
&sleep_time) != kIOReturnSuccess)
return -1;
sleep_time_saved = TRUE;
return 0;
}
static int
restoreSleepSettings(void)
{
if (!sleep_time_saved)
return -1;
if (IOPMSetAggressiveness(power_mgt,
kPMMinutesToSleep,
sleep_time) != kIOReturnSuccess)
return -1;
sleep_time_saved = FALSE;
sleep_time = 0;
return 0;
}
int
rfbDimmingInit(void)
{
pthread_mutex_init(&dimming_mutex, NULL);
if (IOMasterPort(bootstrap_port, &master_dev_port) != kIOReturnSuccess)
return -1;
if (!(power_mgt = IOPMFindPowerManagement(master_dev_port)))
return -1;
if (rfbNoDimming) {
if (saveDimSettings() < 0)
return -1;
if (IOPMSetAggressiveness(power_mgt,
kPMMinutesToDim, 0) != kIOReturnSuccess)
return -1;
}
if (rfbNoSleep) {
if (saveSleepSettings() < 0)
return -1;
if (IOPMSetAggressiveness(power_mgt,
kPMMinutesToSleep, 0) != kIOReturnSuccess)
return -1;
}
initialized = TRUE;
return 0;
}
int
rfbUndim(void)
{
int result = -1;
pthread_mutex_lock(&dimming_mutex);
if (!initialized)
goto DONE;
if (!rfbNoDimming) {
if (saveDimSettings() < 0)
goto DONE;
if (IOPMSetAggressiveness(power_mgt, kPMMinutesToDim, 0) != kIOReturnSuccess)
goto DONE;
if (restoreDimSettings() < 0)
goto DONE;
}
if (!rfbNoSleep) {
if (saveSleepSettings() < 0)
goto DONE;
if (IOPMSetAggressiveness(power_mgt, kPMMinutesToSleep, 0) != kIOReturnSuccess)
goto DONE;
if (restoreSleepSettings() < 0)
goto DONE;
}
result = 0;
DONE:
pthread_mutex_unlock(&dimming_mutex);
return result;
}
int
rfbDimmingShutdown(void)
{
int result = -1;
if (!initialized)
goto DONE;
pthread_mutex_lock(&dimming_mutex);
if (dim_time_saved)
if (restoreDimSettings() < 0)
goto DONE;
if (sleep_time_saved)
if (restoreSleepSettings() < 0)
goto DONE;
result = 0;
DONE:
pthread_mutex_unlock(&dimming_mutex);
return result;
}
rfbScreenInfoPtr rfbScreen;
void rfbShutdown(rfbClientPtr cl);
/* some variables to enable special behaviour */
int startTime = -1, maxSecsToConnect = 0;
Bool disconnectAfterFirstClient = TRUE;
@ -225,7 +393,7 @@ static int keyTable[] = {
};
void
KbdAddEvent(Bool down, KeySym keySym, struct rfbClientRec* cl)
KbdAddEvent(Bool down, KeySym keySym, struct _rfbClientRec* cl)
{
int i;
CGKeyCode keyCode = -1;
@ -233,6 +401,8 @@ KbdAddEvent(Bool down, KeySym keySym, struct rfbClientRec* cl)
if(((int)cl->clientData)==-1) return; /* viewOnly */
rfbUndim();
for (i = 0; i < (sizeof(keyTable) / sizeof(int)); i += 2) {
if (keyTable[i] == keySym) {
keyCode = keyTable[i+1];
@ -262,6 +432,8 @@ PtrAddEvent(buttonMask, x, y, cl)
if(((int)cl->clientData)==-1) return; /* viewOnly */
rfbUndim();
position.x = x;
position.y = y;
@ -281,11 +453,16 @@ Bool viewOnly = FALSE, sharedMode = FALSE;
void
ScreenInit(int argc, char**argv)
{
int bitsPerSample=CGDisplayBitsPerSample(kCGDirectMainDisplay);
rfbScreen = rfbGetScreen(&argc,argv,
CGDisplayPixelsWide(kCGDirectMainDisplay),
CGDisplayPixelsHigh(kCGDirectMainDisplay),
CGDisplayBitsPerSample(kCGDirectMainDisplay),
bitsPerSample,
CGDisplaySamplesPerPixel(kCGDirectMainDisplay),4);
rfbScreen->rfbServerFormat.redShift = bitsPerSample*2;
rfbScreen->rfbServerFormat.greenShift = bitsPerSample*1;
rfbScreen->rfbServerFormat.blueShift = 0;
gethostname(rfbScreen->rfbThisHost, 255);
rfbScreen->paddedWidthInBytes = CGDisplayBytesPerRow(kCGDirectMainDisplay);
rfbScreen->frameBuffer =
@ -335,7 +512,7 @@ refreshCallback(CGRectCount count, const CGRect *rectArray, void *ignore)
#endif
if(startTime>0 && time(0)>startTime+maxSecsToConnect)
exit(0);
rfbShutdown(0);
for (i = 0; i < count; i++)
rfbMarkRectAsModified(rfbScreen,
@ -346,18 +523,20 @@ refreshCallback(CGRectCount count, const CGRect *rectArray, void *ignore)
void clientGone(rfbClientPtr cl)
{
exit(0);
rfbShutdown(cl);
}
void newClient(rfbClientPtr cl)
enum rfbNewClientAction newClient(rfbClientPtr cl)
{
if(startTime>0 && time(0)>startTime+maxSecsToConnect)
exit(0);
rfbShutdown(cl);
if(disconnectAfterFirstClient)
cl->clientGoneHook = clientGone;
cl->clientData=(void*)((viewOnly)?-1:0);
return(RFB_CLIENT_ACCEPT);
}
int main(int argc,char *argv[])
@ -400,6 +579,8 @@ int main(int argc,char *argv[])
sharedMode=TRUE;
}
rfbDimmingInit();
ScreenInit(argc,argv);
rfbScreen->newClientHook = newClient;
@ -410,6 +591,14 @@ int main(int argc,char *argv[])
CGRegisterScreenRefreshCallback(refreshCallback, NULL);
RunApplicationEventLoop();
rfbDimmingShutdown();
return(0); /* never ... */
}
void rfbShutdown(rfbClientPtr cl)
{
rfbScreenCleanup(rfbScreen);
rfbDimmingShutdown();
exit(0);
}

View File

@ -34,14 +34,21 @@
MUTEX(logMutex);
int rfbEnableLogging = 1;
int rfbEnableLogging=1;
char rfbEndianTest = (_BYTE_ORDER == _LITTLE_ENDIAN);
/* we cannot compare to _LITTLE_ENDIAN, because some systems
(as Solaris) assume little endian if _LITTLE_ENDIAN is
defined, even if _BYTE_ORDER is not _LITTLE_ENDIAN */
char rfbEndianTest = (_BYTE_ORDER == 1234);
/* from rfbserver.c */
void rfbIncrClientRef(rfbClientPtr cl);
void rfbDecrClientRef(rfbClientPtr cl);
void rfbLogEnable(int enabled) {
rfbEnableLogging=enabled;
}
/*
* rfbLog prints a time-stamped message to the log file (stderr).
*/
@ -53,15 +60,15 @@ rfbLog(const char *format, ...)
char buf[256];
time_t log_clock;
if (!rfbEnableLogging)
return;
if(!rfbEnableLogging)
return;
LOCK(logMutex);
va_start(args, format);
time(&log_clock);
strftime(buf, 255, "%d/%m/%Y %T ", localtime(&log_clock));
fprintf(stderr, buf);
fprintf(stderr,buf);
vfprintf(stderr, format, args);
fflush(stderr);
@ -75,17 +82,13 @@ void rfbLogPerror(const char *str)
rfbLog("%s: %s\n", str, strerror(errno));
}
void rfbLogEnable(int enabled) {
rfbEnableLogging = enabled;
}
void rfbScheduleCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy)
{
{
rfbClientIteratorPtr iterator;
rfbClientPtr cl;
rfbUndrawCursor(rfbScreen);
iterator=rfbGetClientIterator(rfbScreen);
while((cl=rfbClientIteratorNext(iterator))) {
LOCK(cl->updateMutex);
@ -255,7 +258,7 @@ clientOutput(void *data)
UNLOCK(cl->updateMutex); /* we really needn't lock now. */
}
}
/* OK, now, to save bandwidth, wait a little while for more
updates to come along. */
usleep(cl->screen->rfbDeferUpdateTime * 1000);
@ -315,15 +318,16 @@ listenerRun(void *data)
socklen_t len;
if (rfbScreen->inetdSock != -1) {
cl = rfbNewClient(rfbScreen, rfbScreen->inetdSock);
if (cl && !cl->onHold )
rfbStartOnHoldClient(cl);
return 0;
cl = rfbNewClient(rfbScreen, rfbScreen->inetdSock);
if (cl && !cl->onHold )
rfbStartOnHoldClient(cl);
return 0;
}
len = sizeof(peer);
/* TODO: this thread wont die by restarting the server */
while ((client_fd = accept(rfbScreen->rfbListenSock,
while ((client_fd = accept(rfbScreen->rfbListenSock,
(struct sockaddr*)&peer, &len)) >= 0) {
cl = rfbNewClient(rfbScreen,client_fd);
len = sizeof(peer);
@ -331,7 +335,6 @@ listenerRun(void *data)
if (cl && !cl->onHold )
rfbStartOnHoldClient(cl);
}
return 0;
}
void
@ -377,7 +380,7 @@ defaultPtrAddEvent(int buttonMask, int x, int y, rfbClientPtr cl)
}
}
static void defaultSetXCutText(char *text, int len, rfbClientPtr cl)
void defaultSetXCutText(char* text, int len, rfbClientPtr cl)
{
}
@ -410,13 +413,13 @@ static rfbCursor myCursor =
};
#endif
static rfbCursorPtr defaultGetCursorPtr(rfbClientPtr cl)
rfbCursorPtr defaultGetCursorPtr(rfbClientPtr cl)
{
return(cl->screen->cursor);
}
/* response is cl->authChallenge vncEncrypted with passwd */
static Bool defaultPasswordCheck(rfbClientPtr cl,char* response,int len)
Bool defaultPasswordCheck(rfbClientPtr cl,const char* response,int len)
{
int i;
char *passwd=vncDecryptPasswdFromFile(cl->screen->rfbAuthPasswdData);
@ -511,7 +514,7 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
rfbScreen->rfbNeverShared = FALSE;
rfbScreen->rfbDontDisconnect = FALSE;
rfbScreen->rfbAuthPasswdData = 0;
rfbScreen->width = width;
rfbScreen->height = height;
rfbScreen->bitsPerPixel = rfbScreen->depth = 8*bytesPerPixel;
@ -557,9 +560,15 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
format->greenShift = bitsPerSample;
format->blueShift = bitsPerSample * 2;
} else {
format->redShift = bitsPerSample*3;
format->greenShift = bitsPerSample*2;
format->blueShift = bitsPerSample;
if(bytesPerPixel==3) {
format->redShift = bitsPerSample*2;
format->greenShift = bitsPerSample*1;
format->blueShift = 0;
} else {
format->redShift = bitsPerSample*3;
format->greenShift = bitsPerSample*2;
format->blueShift = bitsPerSample;
}
}
}
@ -596,9 +605,19 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
void rfbScreenCleanup(rfbScreenInfoPtr rfbScreen)
{
rfbClientIteratorPtr i=rfbGetClientIterator(rfbScreen);
rfbClientPtr cl,cl1=rfbClientIteratorNext(i);
while(cl1) {
cl=rfbClientIteratorNext(i);
rfbClientConnectionGone(cl1);
cl1=cl;
}
rfbReleaseClientIterator(i);
/* TODO: hang up on all clients and free all reserved memory */
if(rfbScreen->colourMap.data.bytes)
free(rfbScreen->colourMap.data.bytes);
#define FREE_IF(x) if(rfbScreen->x) free(rfbScreen->x)
FREE_IF(colourMap.data.bytes);
FREE_IF(underCursorBuffer);
TINI_MUTEX(rfbScreen->cursorMutex);
free(rfbScreen);
}

View File

@ -65,16 +65,22 @@ typedef unsigned long KeySym;
#include <machine/endian.h>
#define _BYTE_ORDER BYTE_ORDER
#define _LITTLE_ENDIAN LITTLE_ENDIAN
#elif sparc
#define _LITTLE_ENDIAN 1234
#define _BYTE_ORDER _LITTLE_ENDIAN
#elif defined (__SVR4) && defined (__sun) /* Solaris */
#include <sys/types.h>
#if defined(__sparc)
/* SPARC here (big endian) */
#define _BYTE_ORDER 4321
#elif defined(__i386)
#define _BYTE_ORDER 1234
#else
#error Solaris 2.5.1 had ppc support did it not? :-)
#endif
#undef Bool
#define Bool char
#undef SIGNED
#define SIGNED
#include <sys/types.h>
/* typedef unsigned int pthread_t; */
/* SUN cc seems to have problems with inclusion of sys/types! */
#elif defined(WIN32)
#define _LITTLE_ENDIAN 1234
#define _BYTE_ORDER _LITTLE_ENDIAN
@ -88,7 +94,7 @@ typedef unsigned long KeySym;
#define _BYTE_ORDER __BYTE_ORDER
#endif
#ifndef _LITTLE_ENDIAN
#if !defined(_LITTLE_ENDIAN) && defined(__LITTLE_ENDIAN)
#define _LITTLE_ENDIAN __LITTLE_ENDIAN
#endif
@ -104,6 +110,10 @@ typedef unsigned long KeySym;
#define SOCKET int
#endif
#ifndef INADDR_NONE
#define INADDR_NONE ((in_addr_t) 0xffffffff)
#endif
#ifdef HAVE_PTHREADS
#include <pthread.h>
#if 0 /* debugging */
@ -556,7 +566,7 @@ extern void rfbInitSockets(rfbScreenInfoPtr rfbScreen);
extern void rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen);
extern void rfbCloseClient(rfbClientPtr cl);
extern int ReadExact(rfbClientPtr cl, char *buf, int len);
extern int ReadExactTimeout(rfbClientPtr cl, char *buf, int len, int timeout);
extern int ReadExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout);
extern int WriteExact(rfbClientPtr cl, const char *buf, int len);
extern void rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec);
extern int rfbConnect(rfbScreenInfoPtr rfbScreen, char* host, int port);
@ -747,7 +757,7 @@ void rfbDrawLine(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,Pixel col);
with a NULL.
It returns the index in the list or -1 if cancelled or something else
wasn't kosher. */
typedef void (*SelectionChangedHookPtr)(int);
typedef void (*SelectionChangedHookPtr)(int _index);
extern int rfbSelectBox(rfbScreenInfoPtr rfbScreen,
rfbFontDataPtr font, char** list,
int x1, int y1, int x2, int y2,
@ -757,6 +767,7 @@ extern int rfbSelectBox(rfbScreenInfoPtr rfbScreen,
/* cargs.c */
extern void rfbUsage(void);
extern void rfbPurgeArguments(int* argc,int* position,int count,char *argv[]);
extern void rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[]);
extern void rfbProcessSizeArguments(int* width,int* height,int* bpp,int* argc, char *argv[]);

View File

@ -66,17 +66,17 @@ static void selPaintLine(rfbSelectData* m,int line,Bool invert)
invert?m->backColour:m->colour);
}
static void selSelect(rfbSelectData* m,int indexs)
static void selSelect(rfbSelectData* m,int _index)
{
int delta;
if(indexs==m->selected || indexs<0 || indexs>=m->listSize)
if(_index==m->selected || _index<0 || _index>=m->listSize)
return;
if(m->selected>=0)
selPaintLine(m,m->selected-m->displayStart,FALSE);
if(indexs<m->displayStart || indexs>=m->displayStart+m->pageH) {
if(_index<m->displayStart || _index>=m->displayStart+m->pageH) {
/* targetLine is the screen line in which the selected line will
be displayed.
targetLine = m->pageH/2 doesn't look so nice */
@ -84,11 +84,11 @@ static void selSelect(rfbSelectData* m,int indexs)
int lineStart,lineEnd;
/* scroll */
if(indexs<targetLine)
targetLine = indexs;
else if(indexs+m->pageH-targetLine>=m->listSize)
targetLine = indexs+m->pageH-m->listSize;
delta = indexs-(m->displayStart+targetLine);
if(_index<targetLine)
targetLine = _index;
else if(_index+m->pageH-targetLine>=m->listSize)
targetLine = _index+m->pageH-m->listSize;
delta = _index-(m->displayStart+targetLine);
if(delta>-m->pageH && delta<m->pageH) {
if(delta>0) {
@ -109,15 +109,15 @@ static void selSelect(rfbSelectData* m,int indexs)
}
m->displayStart += delta;
for(delta=lineStart;delta<lineEnd;delta++)
if(delta!=indexs)
if(delta!=_index)
selPaintLine(m,delta,FALSE);
}
m->selected = indexs;
m->selected = _index;
selPaintLine(m,m->selected-m->displayStart,TRUE);
if(m->selChangedHook)
m->selChangedHook(indexs);
m->selChangedHook(_index);
/* todo: scrollbars */
}

View File

@ -64,13 +64,16 @@ struct timeval
}
;
#endif
#ifndef INADDR_NONE
#define INADDR_NONE ((in_addr_t) 0xffffffff)
#endif
#include <fcntl.h>
#include <errno.h>
#ifdef USE_LIBWRAP
#include <syslog.h>
#include <tcpd.h>
int allow_severity=LOG_INFO;
int deny_severity=LOG_WARNING;
#endif
#include "rfb.h"
/*#ifndef WIN32
@ -177,7 +180,7 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
fd_set fds;
struct timeval tv;
struct sockaddr_in addr;
unsigned int addrlen = sizeof(addr);
socklen_t addrlen = sizeof(addr);
char buf[6];
const int one = 1;
int sock;
@ -227,6 +230,16 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
return;
}
#ifdef USE_LIBWRAP
if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
STRING_UNKNOWN)) {
rfbLog("Rejected connection from client %s\n",
inet_ntoa(addr.sin_addr));
close(sock);
return;
}
#endif
rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr));
rfbNewClient(rfbScreen,sock);
@ -298,7 +311,7 @@ rfbCloseClient(cl)
LOCK(cl->updateMutex);
if (cl->sock != -1) {
FD_CLR(cl->sock,&(cl->screen->allFds));
shutdown(cl->sock, SHUT_RDWR);
shutdown(cl->sock,SHUT_RDWR);
close(cl->sock);
cl->sock = -1;
}
@ -357,28 +370,12 @@ rfbConnect(rfbScreen, host, port)
*/
int
ReadExact(cl, buf, len)
rfbClientPtr cl;
char *buf;
int len;
{
return ReadExactTimeout(cl, buf, len, rfbMaxClientWait);
}
/*
* ReadExact with customizable timeout (in ms).
*/
int
ReadExactTimeout(cl, buf, len, timeout)
rfbClientPtr cl;
char *buf;
int len;
ReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
{
int sock = cl->sock;
int n;
fd_set fds;
struct timeval tv;
int totalTimeWaited = 0;
while (len > 0) {
n = read(sock, buf, len);
@ -400,36 +397,28 @@ ReadExactTimeout(cl, buf, len, timeout)
return n;
}
/* Retry every 5 seconds until we exceed the timeout. We
need to do this because select doesn't necessarily return
immediately when the other end has gone away */
FD_ZERO(&fds);
FD_SET(sock, &fds);
tv.tv_sec = 5;
tv.tv_usec = 0;
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000;
n = select(sock+1, &fds, NULL, &fds, &tv);
if (n < 0) {
rfbLogPerror("ReadExact: select");
return n;
}
if (n == 0) {
totalTimeWaited += 5000;
if (totalTimeWaited >= timeout) {
errno = ETIMEDOUT;
return -1;
}
} else {
totalTimeWaited = 0;
errno = ETIMEDOUT;
return -1;
}
}
}
return 1;
}
int ReadExact(rfbClientPtr cl,char* buf,int len)
{
return(ReadExactTimeout(cl,buf,len,rfbMaxClientWait));
}
/*
* WriteExact writes an exact number of bytes to a client. Returns 1 if

View File

@ -33,7 +33,7 @@ typedef struct sraRegion {
sraSpanList *sraSpanListDup(const sraSpanList *src);
void sraSpanListDestroy(sraSpanList *list);
static sraSpan *
sraSpan *
sraSpanCreate(int start, int end, const sraSpanList *subspan) {
sraSpan *item = (sraSpan*)malloc(sizeof(sraSpan));
item->_next = item->_prev = NULL;
@ -43,7 +43,7 @@ sraSpanCreate(int start, int end, const sraSpanList *subspan) {
return item;
}
static sraSpan *
sraSpan *
sraSpanDup(const sraSpan *src) {
sraSpan *span;
if (!src) return NULL;
@ -51,7 +51,7 @@ sraSpanDup(const sraSpan *src) {
return span;
}
static void
void
sraSpanInsertAfter(sraSpan *newspan, sraSpan *after) {
newspan->_next = after->_next;
newspan->_prev = after;
@ -59,7 +59,7 @@ sraSpanInsertAfter(sraSpan *newspan, sraSpan *after) {
after->_next = newspan;
}
static void
void
sraSpanInsertBefore(sraSpan *newspan, sraSpan *before) {
newspan->_next = before;
newspan->_prev = before->_prev;
@ -67,35 +67,33 @@ sraSpanInsertBefore(sraSpan *newspan, sraSpan *before) {
before->_prev = newspan;
}
static void
void
sraSpanRemove(sraSpan *span) {
span->_prev->_next = span->_next;
span->_next->_prev = span->_prev;
}
static void
void
sraSpanDestroy(sraSpan *span) {
if (span->subspan) sraSpanListDestroy(span->subspan);
free(span);
}
/*
static void
void
sraSpanCheck(const sraSpan *span, const char *text) {
// Check the span is valid!
/* Check the span is valid! */
if (span->start == span->end) {
printf(text);
printf(":%d-%d\n", span->start, span->end);
exit(0);
}
}
*/
/* -=- SpanList routines */
void sraSpanPrint(const sraSpan *s);
static void
void
sraSpanListPrint(const sraSpanList *l) {
sraSpan *curr;
if (!l) {
@ -118,7 +116,7 @@ sraSpanPrint(const sraSpan *s) {
sraSpanListPrint(s->subspan);
}
static sraSpanList *
sraSpanList *
sraSpanListCreate() {
sraSpanList *item = (sraSpanList*)malloc(sizeof(sraSpanList));
item->front._next = &(item->back);
@ -158,7 +156,7 @@ sraSpanListDestroy(sraSpanList *list) {
free(list);
}
static void
void
sraSpanListMakeEmpty(sraSpanList *list) {
sraSpan *curr, *next;
while (list->front._next != &(list->back)) {
@ -174,12 +172,7 @@ sraSpanListMakeEmpty(sraSpanList *list) {
list->back._next = NULL;
}
/*
static int sraMax(int a, int b) {return (a>b)?a:b;}
static int sraMin(int a, int b) {return (a<b)?a:b;}
*/
static Bool
Bool
sraSpanListEqual(const sraSpanList *s1, const sraSpanList *s2) {
sraSpan *sp1, *sp2;
@ -212,12 +205,12 @@ sraSpanListEqual(const sraSpanList *s1, const sraSpanList *s2) {
}
}
static Bool
Bool
sraSpanListEmpty(const sraSpanList *list) {
return (list->front._next == &(list->back));
}
static unsigned long
unsigned long
sraSpanListCount(const sraSpanList *list) {
sraSpan *curr = list->front._next;
unsigned long count = 0;
@ -232,7 +225,7 @@ sraSpanListCount(const sraSpanList *list) {
return count;
}
static void
void
sraSpanMergePrevious(sraSpan *dest) {
sraSpan *prev = dest->_prev;
while ((prev->end == dest->start) &&
@ -252,7 +245,7 @@ sraSpanMergePrevious(sraSpan *dest) {
}
}
static void
void
sraSpanMergeNext(sraSpan *dest) {
sraSpan *next = dest->_next;
while ((next->start == dest->end) &&
@ -272,7 +265,7 @@ sraSpanMergeNext(sraSpan *dest) {
}
}
static void
void
sraSpanListOr(sraSpanList *dest, const sraSpanList *src) {
sraSpan *d_curr, *s_curr;
int s_start, s_end;
@ -362,7 +355,7 @@ sraSpanListOr(sraSpanList *dest, const sraSpanList *src) {
}
}
static Bool
Bool
sraSpanListAnd(sraSpanList *dest, const sraSpanList *src) {
sraSpan *d_curr, *s_curr, *d_next;
@ -442,7 +435,7 @@ sraSpanListAnd(sraSpanList *dest, const sraSpanList *src) {
return !sraSpanListEmpty(dest);
}
static Bool
Bool
sraSpanListSubtract(sraSpanList *dest, const sraSpanList *src) {
sraSpan *d_curr, *s_curr;
@ -515,7 +508,7 @@ sraSpanListSubtract(sraSpanList *dest, const sraSpanList *src) {
/* -=- Region routines */
sraRegion*
sraRegion *
sraRgnCreate() {
return (sraRegion*)sraSpanListCreate();
}
@ -696,13 +689,13 @@ sraRectangleIterator *sraRgnGetReverseIterator(sraRegion *s,Bool reverseX,Bool r
return(i);
}
static Bool sraReverse(sraRectangleIterator *i)
Bool sraReverse(sraRectangleIterator *i)
{
return( ((i->ptrPos&2) && i->reverseX) ||
(!(i->ptrPos&2) && i->reverseY));
}
static sraSpan* sraNextSpan(sraRectangleIterator *i)
sraSpan* sraNextSpan(sraRectangleIterator *i)
{
if(sraReverse(i))
return(i->sPtrs[i->ptrPos]->_prev);

View File

@ -449,7 +449,7 @@ CheckSolidTile(cl, x, y, w, h, colorPtr, needSameColor)
#define DEFINE_CHECK_SOLID_FUNCTION(bpp) \
\
static Bool \
CheckSolidTile##bpp(cl, x, y, w, h, colorPtr, needSameColor) \
CheckSolidTile##bpp(cl, x, y, w, h, colorPtr, needSameColor) \
rfbClientPtr cl; \
int x, y, w, h; \
CARD32 *colorPtr; \

View File

@ -38,7 +38,7 @@ Bool rfbEconomicTranslate = FALSE;
*/
static const rfbPixelFormat BGR233Format = {
8, 8, 0, 1, 7, 7, 3, 0, 3, 6, 0, 0
8, 8, 0, 1, 7, 7, 3, 0, 3, 6, 0, 0
};
@ -359,7 +359,8 @@ rfbSetTranslateFunction(cl)
*/
static Bool
rfbSetClientColourMapBGR233(rfbClientPtr cl)
rfbSetClientColourMapBGR233(cl)
rfbClientPtr cl;
{
char buf[sz_rfbSetColourMapEntriesMsg + 256 * 3 * 2];
rfbSetColourMapEntriesMsg *scme = (rfbSetColourMapEntriesMsg *)buf;

View File

@ -11,6 +11,8 @@
#include <sys/shm.h>
#endif
#define KEYSYM_H
#undef Bool
#define KeySym RFBKeySym
#include "rfb.h"
Display *dpy = 0;
@ -24,6 +26,7 @@ Bool sharedMode = FALSE;
Bool disconnectAfterFirstClient = TRUE;
/* keyboard handling */
#define KBDDEBUG
char modifiers[0x100];
KeyCode keycodes[0x100],leftShiftCode,rightShiftCode,altGrCode;
@ -38,12 +41,23 @@ void init_keycodes()
XDisplayKeycodes(dpy,&minkey,&maxkey);
keymap=XGetKeyboardMapping(dpy,minkey,(maxkey - minkey + 1),&syms_per_keycode);
#ifdef KBDDEBUG
fprintf(stderr,"minkey=%d, maxkey=%d, syms_per_keycode=%d\n",
minkey,maxkey,syms_per_keycode);
#endif
for (i = minkey; i <= maxkey; i++)
for(j=0;j<syms_per_keycode;j++) {
key=keymap[(i-minkey)*syms_per_keycode+j];
#ifdef KBDDEBUG
fprintf(stderr,"keymap(i=0x%x,j=%d)==0x%lx\n",i,j,key);
#endif
if(key>=' ' && key<0x100 && i==XKeysymToKeycode(dpy,key)) {
keycodes[key]=i;
modifiers[key]=j;
#ifdef KBDDEBUG
fprintf(stderr,"key 0x%lx (%c): keycode=0x%x, modifier=%d\n",
key,(char)key,i,j);
#endif
}
}
@ -51,17 +65,24 @@ void init_keycodes()
rightShiftCode=XKeysymToKeycode(dpy,XK_Shift_R);
altGrCode=XKeysymToKeycode(dpy,XK_Mode_switch);
#ifdef KBDDEBUG
fprintf(stderr,"leftShift=0x%x, rightShift=0x%x, altGr=0x%x\n",
leftShiftCode,rightShiftCode,altGrCode);
#endif
XFree ((char *) keymap);
}
static Bool shutDownServer=0;
/* the hooks */
void clientGone(rfbClientPtr cl)
{
exit(0);
shutDownServer=-1;
}
void newClient(rfbClientPtr cl)
enum rfbNewClientAction newClient(rfbClientPtr cl)
{
if(disconnectAfterFirstClient)
cl->clientGoneHook = clientGone;
@ -69,6 +90,7 @@ void newClient(rfbClientPtr cl)
cl->clientData = (void*)-1;
else
cl->clientData = (void*)0;
return(RFB_CLIENT_ACCEPT);
}
#define LEFTSHIFT 1
@ -81,6 +103,10 @@ char ModifierState = 0;
void tweakModifiers(char mod,Bool down)
{
Bool isShift=ModifierState&(LEFTSHIFT|RIGHTSHIFT);
#ifdef KBDDEBUG
fprintf(stderr,"tweakModifiers: 0x%x %s\n",
mod,down?"down":"up");
#endif
if(mod<0) return;
if(isShift && mod!=1) {
if(ModifierState&LEFTSHIFT)
@ -108,6 +134,11 @@ void keyboard(Bool down,KeySym keySym,rfbClientPtr cl)
ADJUSTMOD(XK_Shift_R,RIGHTSHIFT)
ADJUSTMOD(XK_Mode_switch,ALTGR)
#ifdef KBDDEBUG
fprintf(stderr,"keyboard: down=%s, keySym=0x%lx (%s), ModState=0x%x\n",
down?"down":"up",keySym,XKeysymToString(keySym),ModifierState);
#endif
if(keySym>=' ' && keySym<0x100) {
KeyCode k;
if(down)
@ -119,7 +150,6 @@ void keyboard(Bool down,KeySym keySym,rfbClientPtr cl)
XTestFakeKeyEvent(dpy,k,down,CurrentTime);
gotInput = TRUE;
}
/*XTestFakeKeyEvent(dpy,keycodes[keySym],down,CurrentTime);*/
if(down)
tweakModifiers(modifiers[keySym],False);
gotInput = TRUE;
@ -462,7 +492,7 @@ int main(int argc,char** argv)
rfbClientPtr cl;
for(cl=screen->rfbClientHead;cl;cl=cl->next)
if(!strcmp(message+1,cl->host)) {
cl->clientData=(cl->clientData==0)?-1:0;
cl->clientData=(void*)((cl->clientData==0)?-1:0);
break;
}
}
@ -474,6 +504,15 @@ int main(int argc,char** argv)
#endif
rfbProcessEvents(screen,-1);
if(shutDownServer) {
free(backupImage);
rfbScreenCleanup(screen);
XFree(dpy);
#ifndef NO_SHM
XShmDetach(dpy,framebufferImage);
#endif
exit(0);
}
if(dontTile) {
if(gotInput) {