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:
parent
842c3a55cc
commit
8d2687fad3
|
@ -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
|
||||
|
|
|
@ -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[])
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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; \
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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[]);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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; \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user