compiler warnings, contrib directory, new x11vnc from Karl Runge

pull/1/head
dscho 22 years ago
parent d60fda117b
commit 4d87189420

@ -1,3 +1,4 @@
Better x11vnc from Karl J. Runge!
fixed severe bug (Const Kaplinsky) fixed severe bug (Const Kaplinsky)
got patch from Const Kaplisnky with CursorPosUpdate encoding and some Docs got patch from Const Kaplisnky with CursorPosUpdate encoding and some Docs
sync'ed with newest RealVNC (ZRLE encoding) sync'ed with newest RealVNC (ZRLE encoding)

@ -3,6 +3,7 @@ VNCSERVERLIB=-L. -lvncserver -L/usr/local/lib -lz -ljpeg
CXX=g++ CXX=g++
CC=gcc CC=gcc
LINK=gcc
# for Solaris # for Solaris
#EXTRALIBS=-lsocket -lnsl -L/usr/X/lib #EXTRALIBS=-lsocket -lnsl -L/usr/X/lib
@ -36,6 +37,7 @@ ZRLE_SRCS=zrle.cc rdr/FdInStream.cxx rdr/FdOutStream.cxx rdr/InStream.cxx \
ZRLE_OBJS=zrle.o rdr/FdInStream.o rdr/FdOutStream.o rdr/InStream.o \ ZRLE_OBJS=zrle.o rdr/FdInStream.o rdr/FdOutStream.o rdr/InStream.o \
rdr/NullOutStream.o rdr/ZlibInStream.o rdr/ZlibOutStream.o rdr/NullOutStream.o rdr/ZlibInStream.o rdr/ZlibOutStream.o
ZRLE_DEF=-DHAVE_ZRLE ZRLE_DEF=-DHAVE_ZRLE
LINK=$(CXX)
%.o: %.cxx %.o: %.cxx
$(CXX) $(CXXFLAGS) -c -o $@ $< $(CXX) $(CXXFLAGS) -c -o $@ $<
@ -75,52 +77,53 @@ libvncserver.a: $(OBJS)
translate.o: translate.c tableinit24.c tableinitcmtemplate.c tableinittctemplate.c tabletrans24template.c tabletranstemplate.c translate.o: translate.c tableinit24.c tableinitcmtemplate.c tableinittctemplate.c tabletrans24template.c tabletranstemplate.c
example: example.o libvncserver.a example: example.o libvncserver.a
$(CC) -o example example.o $(LIBS) $(LINK) -o example example.o $(LIBS)
pnmshow: pnmshow.o libvncserver.a pnmshow: pnmshow.o libvncserver.a
$(CC) -o pnmshow pnmshow.o $(LIBS) $(LINK) -o pnmshow pnmshow.o $(LIBS)
mac.o: mac.c 1instance.c mac.o: mac.c 1instance.c
OSXvnc-server: mac.o libvncserver.a OSXvnc-server: mac.o libvncserver.a
$(CC) -o OSXvnc-server mac.o $(LIBS) $(OSX_LIBS) $(LINK) -o OSXvnc-server mac.o $(LIBS) $(OSX_LIBS)
x11vnc.o: x11vnc.c 1instance.c x11vnc.o: contrib/x11vnc.c rfb.h 1instance.c Makefile
$(CC) $(CFLAGS) -I. -c -o x11vnc.o contrib/x11vnc.c
x11vnc: x11vnc.o libvncserver.a x11vnc: x11vnc.o libvncserver.a
$(CC) -g -o x11vnc x11vnc.o $(LIBS) $(XLIBS) $(LINK) -g -o x11vnc x11vnc.o $(LIBS) $(XLIBS)
x11vnc_static: x11vnc.o libvncserver.a x11vnc_static: x11vnc.o libvncserver.a
$(CC) -o x11vnc_static x11vnc.o libvncserver.a /usr/lib/libz.a /usr/lib/libjpeg.a $(XLIBS) $(LINK) -o x11vnc_static x11vnc.o libvncserver.a /usr/lib/libz.a /usr/lib/libjpeg.a $(XLIBS)
#$(LIBS) $(XLIBS) #$(LIBS) $(XLIBS)
storepasswd: storepasswd.o d3des.o vncauth.o storepasswd: storepasswd.o d3des.o vncauth.o
$(CC) -o storepasswd storepasswd.o d3des.o vncauth.o $(LINK) -o storepasswd storepasswd.o d3des.o vncauth.o
sratest: sratest.o sratest: sratest.o
$(CC) -o sratest sratest.o $(LINK) -o sratest sratest.o
sratest.o: sraRegion.c sratest.o: sraRegion.c
$(CC) $(CFLAGS) -DSRA_TEST -c -o sratest.o sraRegion.c $(CC) $(CFLAGS) -DSRA_TEST -c -o sratest.o sraRegion.c
blooptest: blooptest.o libvncserver.a blooptest: blooptest.o libvncserver.a
$(CC) -o blooptest blooptest.o $(LIBS) $(LINK) -o blooptest blooptest.o $(LIBS)
blooptest.o: example.c rfb.h blooptest.o: example.c rfb.h
$(CC) $(CFLAGS) -DBACKGROUND_LOOP_TEST -c -o blooptest.o example.c $(CC) $(CFLAGS) -DBACKGROUND_LOOP_TEST -c -o blooptest.o example.c
pnmshow24: pnmshow24.o libvncserver.a pnmshow24: pnmshow24.o libvncserver.a
$(CC) -o pnmshow24 pnmshow24.o $(LIBS) $(LINK) -o pnmshow24 pnmshow24.o $(LIBS)
fontsel: fontsel.o libvncserver.a fontsel: fontsel.o libvncserver.a
$(CC) -o fontsel fontsel.o -L. -lvncserver -lz -ljpeg $(LINK) -o fontsel fontsel.o -L. -lvncserver -lz -ljpeg
vncev: vncev.o libvncserver.a vncev: vncev.o libvncserver.a
$(CC) -o vncev vncev.o -L. -lvncserver -lz -ljpeg $(LINK) -o vncev vncev.o -L. -lvncserver -lz -ljpeg
# Example from Justin # Example from Justin
zippy: zippy.o libvncserver.a zippy: contrib/zippy.o libvncserver.a
$(CC) -o zippy zippy.o -L. -lvncserver -lz -ljpeg $(LINK) -o zippy contrib/zippy.o -L. -lvncserver -lz -ljpeg
clean: clean:
rm -f $(OBJS) *~ core "#"* *.bak *.orig storepasswd.o \ rm -f $(OBJS) *~ core "#"* *.bak *.orig storepasswd.o \

File diff suppressed because it is too large Load Diff

@ -266,7 +266,7 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
httpCloseSock(rfbScreen); httpCloseSock(rfbScreen);
return; return;
} }
// proxy connection /* proxy connection */
rfbLog("httpd: client asked for CONNECT\n"); rfbLog("httpd: client asked for CONNECT\n");
WriteExact(&cl,PROXY_OK_STR,strlen(PROXY_OK_STR)); WriteExact(&cl,PROXY_OK_STR,strlen(PROXY_OK_STR));
rfbNewClientConnection(rfbScreen,rfbScreen->httpSock); rfbNewClientConnection(rfbScreen,rfbScreen->httpSock);
@ -274,7 +274,7 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
return; return;
} }
if (!strncmp(buf, "GET ",4) && !strncmp(strchr(buf,'/'),"/proxied.connection HTTP/1.", 27)) { if (!strncmp(buf, "GET ",4) && !strncmp(strchr(buf,'/'),"/proxied.connection HTTP/1.", 27)) {
// proxy connection /* proxy connection */
rfbLog("httpd: client asked for /proxied.connection\n"); rfbLog("httpd: client asked for /proxied.connection\n");
WriteExact(&cl,PROXY_OK_STR,strlen(PROXY_OK_STR)); WriteExact(&cl,PROXY_OK_STR,strlen(PROXY_OK_STR));
rfbNewClientConnection(rfbScreen,rfbScreen->httpSock); rfbNewClientConnection(rfbScreen,rfbScreen->httpSock);

@ -128,7 +128,7 @@ void rfbScheduleCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,in
sraRgnDestroy(modifiedRegionBackup); sraRgnDestroy(modifiedRegionBackup);
#if 0 #if 0
//TODO: is this needed? Or does it mess up deferring? /* TODO: is this needed? Or does it mess up deferring? */
/* while(!sraRgnEmpty(cl->copyRegion)) */ { /* while(!sraRgnEmpty(cl->copyRegion)) */ {
#ifdef HAVE_PTHREADS #ifdef HAVE_PTHREADS
if(!cl->screen->backgroundLoop) if(!cl->screen->backgroundLoop)

22
rfb.h

@ -164,9 +164,17 @@ typedef int socklen_t;
the library and your application (at least the parts including rfb.h) the library and your application (at least the parts including rfb.h)
with the same support for pthreads. */ with the same support for pthreads. */
#ifdef HAVE_PTHREADS #ifdef HAVE_PTHREADS
#define rfbInitServer rfbInitServerWithPthreads #ifdef HAVE_ZRLE
#define rfbInitServer rfbInitServerWithPthreadsAndZRLE
#else
#define rfbInitServer rfbInitServerWithPthreadsButWithoutZRLE
#endif
#else
#ifdef HAVE_ZRLE
#define rfbInitServer rfbInitServerWithoutPthreadsButWithZRLE
#else #else
#define rfbInitServer rfbInitServerWithoutPthreads #define rfbInitServer rfbInitServerWithoutPthreadsAndZRLE
#endif
#endif #endif
#define MAX_ENCODINGS 10 #define MAX_ENCODINGS 10
@ -409,9 +417,6 @@ typedef struct _rfbClientRec {
Bool useCopyRect; Bool useCopyRect;
int preferredEncoding; int preferredEncoding;
int correMaxWidth, correMaxHeight; int correMaxWidth, correMaxHeight;
#ifdef HAVE_ZRLE
void* zrleData;
#endif
/* The following member is only used during VNC authentication */ /* The following member is only used during VNC authentication */
CARD8 authChallenge[CHALLENGESIZE]; CARD8 authChallenge[CHALLENGESIZE];
@ -538,6 +543,10 @@ typedef struct _rfbClientRec {
COND(updateCond); COND(updateCond);
#endif #endif
#ifdef HAVE_ZRLE
void* zrleData;
#endif
} rfbClientRec, *rfbClientPtr; } rfbClientRec, *rfbClientPtr;
/* /*
@ -725,9 +734,10 @@ extern void rfbSetCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr c,Bool freeOld)
extern void defaultPtrAddEvent(int buttonMask,int x,int y,rfbClientPtr cl); extern void defaultPtrAddEvent(int buttonMask,int x,int y,rfbClientPtr cl);
/* zrle.c */ /* zrle.c */
#ifdef HAVE_ZRLE
extern Bool rfbSendRectEncodingZRLE(rfbClientPtr cl, int x, int y, int w,int h); extern Bool rfbSendRectEncodingZRLE(rfbClientPtr cl, int x, int y, int w,int h);
extern void FreeZrleData(rfbClientPtr cl); extern void FreeZrleData(rfbClientPtr cl);
#endif
/* stats.c */ /* stats.c */

@ -1,583 +0,0 @@
/* This file (x11vnc.c) is part of LibVNCServer.
It is a small clone of x0rfbserver by HexoNet, demonstrating the
capabilities of LibVNCServer.
*/
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/extensions/XTest.h>
#ifndef NO_SHM
#include <X11/extensions/XShm.h>
#include <sys/shm.h>
#endif
#define KEYSYM_H
#undef Bool
#define KeySym RFBKeySym
#include "rfb.h"
Display *dpy = 0;
int window;
int c=0,blockLength = 32;
int tileX=0,tileY=0,tileWidth=32,tileHeight=32*2,dontTile=TRUE;
Bool gotInput = FALSE;
Bool viewOnly = FALSE;
Bool sharedMode = FALSE;
Bool disconnectAfterFirstClient = TRUE;
/* keyboard handling */
#define KBDDEBUG
char modifiers[0x100];
KeyCode keycodes[0x100],leftShiftCode,rightShiftCode,altGrCode;
void init_keycodes()
{
KeySym key,*keymap;
int i,j,minkey,maxkey,syms_per_keycode;
memset(modifiers,-1,sizeof(modifiers));
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
}
}
leftShiftCode=XKeysymToKeycode(dpy,XK_Shift_L);
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)
{
shutDownServer=-1;
}
enum rfbNewClientAction newClient(rfbClientPtr cl)
{
if(disconnectAfterFirstClient)
cl->clientGoneHook = clientGone;
if(viewOnly)
cl->clientData = (void*)-1;
else
cl->clientData = (void*)0;
return(RFB_CLIENT_ACCEPT);
}
#define LEFTSHIFT 1
#define RIGHTSHIFT 2
#define ALTGR 4
char ModifierState = 0;
/* this function adjusts the modifiers according to mod (as from modifiers) and ModifierState */
void tweakModifiers(signed 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)
XTestFakeKeyEvent(dpy,leftShiftCode,!down,CurrentTime);
if(ModifierState&RIGHTSHIFT)
XTestFakeKeyEvent(dpy,rightShiftCode,!down,CurrentTime);
}
if(!isShift && mod==1)
XTestFakeKeyEvent(dpy,leftShiftCode,down,CurrentTime);
if(ModifierState&ALTGR && mod!=2)
XTestFakeKeyEvent(dpy,altGrCode,!down,CurrentTime);
if(!(ModifierState&ALTGR) && mod==2)
XTestFakeKeyEvent(dpy,altGrCode,down,CurrentTime);
}
void keyboard(Bool down,KeySym keySym,rfbClientPtr cl)
{
if(((int)cl->clientData)==-1) return; /* viewOnly */
#define ADJUSTMOD(sym,state) \
if(keySym==sym) { if(down) ModifierState|=state; else ModifierState&=~state; }
ADJUSTMOD(XK_Shift_L,LEFTSHIFT)
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)
tweakModifiers(modifiers[keySym],True);
//tweakModifiers(modifiers[keySym],down);
//k = XKeysymToKeycode( dpy,keySym );
k = keycodes[keySym];
if(k!=NoSymbol) {
XTestFakeKeyEvent(dpy,k,down,CurrentTime);
gotInput = TRUE;
}
if(down)
tweakModifiers(modifiers[keySym],False);
gotInput = TRUE;
} else {
KeyCode k = XKeysymToKeycode( dpy,keySym );
if(k!=NoSymbol) {
XTestFakeKeyEvent(dpy,k,down,CurrentTime);
gotInput = TRUE;
}
}
}
int oldButtonMask = 0;
void mouse(int buttonMask,int x,int y,rfbClientPtr cl)
{
int i=0;
if(((int)cl->clientData)==-1) return; /* viewOnly */
XTestFakeMotionEvent(dpy,0,x,y,CurrentTime );
while(i<5) {
if ((oldButtonMask&(1<<i))!=(buttonMask&(1<<i)))
XTestFakeButtonEvent(dpy,i+1,(buttonMask&(1<<i))?True:False,CurrentTime);
i++;
}
oldButtonMask = buttonMask;
//fprintf(stderr,"-");
gotInput = TRUE;
}
/* the X11 interaction */
#ifndef NO_SHM
Bool useSHM = TRUE;
XShmSegmentInfo shminfo;
#else
Bool useSHM = FALSE;
#endif
void getImage(int bpp,Display *dpy,int xscreen,XImage **i,int x,int y,int width,int height)
{
if(width<=0) width=DisplayWidth(dpy,xscreen);
if(height<=0) height=DisplayHeight(dpy,xscreen);
if(useSHM && bpp>0) {
static Bool firstTime = TRUE;
if(firstTime) {
firstTime = FALSE;
*i = XShmCreateImage(dpy,
DefaultVisual( dpy, xscreen ),
bpp,
ZPixmap,
NULL,
&shminfo,
width,height);
if(*i == 0) {
useSHM = FALSE;
getImage(bpp,dpy,xscreen,i,x,y,width,height);
return;
}
shminfo.shmid = shmget( IPC_PRIVATE,
(*i)->bytes_per_line * (*i)->height,
IPC_CREAT | 0777 );
shminfo.shmaddr = (*i)->data = (char *) shmat( shminfo.shmid, 0, 0 );
shminfo.readOnly = False;
XShmAttach( dpy, &shminfo );
}
if(x==0 && y==0 && width==DisplayWidth(dpy,xscreen) && height==DisplayHeight(dpy,xscreen))
XShmGetImage(dpy,window,*i,0,0,AllPlanes);
else
XGetSubImage(dpy,window,x,y,width,height,AllPlanes,ZPixmap,*i,0,0);
} else {
*i = XGetImage(dpy,window,x,y,width,height,AllPlanes,ZPixmap );
}
}
void checkForImageUpdates(rfbScreenInfoPtr s,char *b,int rowstride,int x,int y,int width,int height)
{
Bool changed;
int i,j,k,l1,l2,x1,y1;
int bpp=s->bitsPerPixel/8;
for(j=0;j<height;j+=blockLength)
for(i=0;i<width;i+=blockLength) {
y1=j+blockLength; if(y1>height) y1=height;
x1=i+blockLength; if(x1>width) x1=width;
y1*=rowstride;
x1*=bpp;
changed=FALSE;
for(l1=j*rowstride,l2=(j+y)*s->paddedWidthInBytes+x*bpp;l1<y1;l1+=rowstride,l2+=s->paddedWidthInBytes)
for(k=i*bpp;k<x1;k++)
if(s->frameBuffer[l2+k]!=b[l1+k]) {
// fprintf(stderr,"changed: %d, %d\n",k,l);
changed=TRUE;
goto changed_p;
}
if(changed) {
changed_p:
for(l1+=i*bpp,l2+=i*bpp;l1<y1;l1+=rowstride,l2+=s->paddedWidthInBytes)
memcpy(/*b+l,*/s->frameBuffer+l2,b+l1,x1-i*bpp);
rfbMarkRectAsModified(s,x+i,y+j,x+i+blockLength,y+j+blockLength);
}
}
}
int probeX=0,probeY=0;
void probeScreen(rfbScreenInfoPtr s,int xscreen)
{
int i,j,/*pixel,i1,*/j1,
bpp=s->rfbServerFormat.bitsPerPixel/8,/*mask=(1<<bpp)-1,*/
rstride=s->paddedWidthInBytes;
XImage* im;
//fprintf(stderr,"/%d,%d",probeX,probeY);
#if 0
probeX++;
if(probeX>=tileWidth) {
probeX=0;
probeY++;
if(probeY>=tileHeight)
probeY=0;
}
#else
probeX=(rand()%tileWidth);
probeY=(rand()%tileHeight);
#endif
for(j=probeY;j<s->height;j+=tileHeight)
for(i=0/*probeX*/;i<s->width;i+=tileWidth) {
im=XGetImage(dpy,window,i,j,tileWidth/*1*/,1,AllPlanes,ZPixmap);
/* for(i1=0;i1<bpp && im->data[i1]==(s->frameBuffer+i*bpp+j*rstride)[i1];i1++);
if(i1<bpp) { */
if(memcmp(im->data,s->frameBuffer+i*bpp+j*rstride,tileWidth*bpp)) {
/* do update */
int x=i/*-probeX*/,w=(x+tileWidth>s->width)?s->width-x:tileWidth,
y=j-probeY,h=(y+tileHeight>s->height)?s->height-y:tileHeight;
XDestroyImage(im);
//getImage(bpp,dpy,xscreen,&im,x,y,w,h);
//fprintf(stderr,"GetImage(%d,%d,%d,%d)",x,y,w,h);
im = XGetImage(dpy,window,x,y,w,h,AllPlanes,ZPixmap );
for(j1=0;j1<h;j1++)
memcpy(s->frameBuffer+x*bpp+(y+j1)*rstride,
im->data+j1*im->bytes_per_line,bpp*w);
//checkForImageUpdates(s,im->data,rstride,x,y,w,h);
//if(0 && !useSHM)
XDestroyImage(im);
//memcpy(s->frameBuffer+i*bpp+j*rstride,&pixel,bpp);
rfbMarkRectAsModified(s,x,y,x+w,y+h);
//fprintf(stderr,"%d:%d:%x\n",i,j,pixel);
//fprintf(stderr,"*");
} else
XDestroyImage(im);
}
}
#define LOCAL_CONTROL
#ifdef LOCAL_CONTROL
#include "1instance.c"
#endif
/* the main program */
int main(int argc,char** argv)
{
//Screen *sc;
//Colormap cm;
XImage *framebufferImage;
char *backupImage;
int xscreen,i;
rfbScreenInfoPtr screen;
int maxMsecsToConnect = 5000; /* a maximum of 5 seconds to connect */
int updateCounter; /* about every 50 ms a screen update should be made. */
#ifdef LOCAL_CONTROL
char message[1024];
single_instance_struct single_instance = { "/tmp/x11vnc_control" };
open_control_file(&single_instance);
#endif
for(i=argc-1;i>0;i--)
#ifdef LOCAL_CONTROL
if(i<argc-1 && !strcmp(argv[i],"-toggleviewonly")) {
if(strlen(argv[i+1])>1022)
argv[i+1][1022]=0;
sprintf(message,"t%s",argv[i+1]);
send_message(&single_instance,message);
exit(0);
} else if(!strcmp(argv[i],"-listclients")) {
fprintf(stderr,"list clients\n");
send_message(&single_instance,"l");
exit(0);
} else
#ifdef BACKCHANNEL
if(i<argc-1 && !strcmp(argv[i],"-backchannel")) {
if(strlen(argv[i+1])>1022)
argv[i+1][1022]=0;
sprintf(message,"b%s",argv[i+1]);
send_message(&single_instance,message);
exit(0);
} else
#endif
#endif
if(i<argc-1 && strcmp(argv[i],"-display")==0) {
fprintf(stderr,"Using display %s\n",argv[i+1]);
dpy = XOpenDisplay(argv[i+1]);
if(dpy==0) {
fprintf(stderr,"Couldn't connect to display \"%s\".\n",argv[i+1]);
exit(1);
}
} else if(i<argc-1 && strcmp(argv[i],"-wait4client")==0) {
maxMsecsToConnect = atoi(argv[i+1]);
} else if(i<argc-1 && strcmp(argv[i],"-update")==0) {
updateCounter = atoi(argv[i+1]);
} else if(strcmp(argv[i],"-noshm")==0) {
useSHM = FALSE;
} else if(strcmp(argv[i],"-runforever")==0) {
disconnectAfterFirstClient = FALSE;
} else if(strcmp(argv[i],"-tile")==0) {
dontTile=FALSE;
} else if(strcmp(argv[i],"-viewonly")==0) {
viewOnly=TRUE;
} else if(strcmp(argv[i],"-shared")==0) {
sharedMode=TRUE;
}
updateCounter = dontTile?20:1;
if(dpy==0)
dpy = XOpenDisplay("");
if(dpy==0) {
fprintf(stderr,"Couldn't open display!\n");
exit(2);
}
xscreen = DefaultScreen(dpy);
window = RootWindow(dpy,xscreen);
//XTestGrabControl(dpy,True);
init_keycodes();
getImage(0,dpy,xscreen,&framebufferImage,0,0,-1,-1);
screen = rfbGetScreen(&argc,argv,framebufferImage->width,
framebufferImage->height,
framebufferImage->bits_per_pixel,
8,
framebufferImage->bits_per_pixel/8);
screen->paddedWidthInBytes = framebufferImage->bytes_per_line;
screen->rfbServerFormat.bitsPerPixel = framebufferImage->bits_per_pixel;
screen->rfbServerFormat.depth = framebufferImage->depth;
//rfbEndianTest = framebufferImage->bitmap_bit_order != MSBFirst;
screen->rfbServerFormat.trueColour = TRUE;
if ( screen->rfbServerFormat.bitsPerPixel == 8 ) {
if(CellsOfScreen(ScreenOfDisplay(dpy,xscreen))) {
XColor color[256];
int i;
screen->colourMap.count = 256;
screen->rfbServerFormat.trueColour = FALSE;
screen->colourMap.is16 = TRUE;
for(i=0;i<256;i++)
color[i].pixel=i;
XQueryColors(dpy,DefaultColormap(dpy,xscreen),color,256);
screen->colourMap.data.shorts = (unsigned short*)malloc(3*sizeof(short)*screen->colourMap.count);
for(i=0;i<screen->colourMap.count;i++) {
screen->colourMap.data.shorts[i*3+0] = color[i].red;
screen->colourMap.data.shorts[i*3+1] = color[i].green;
screen->colourMap.data.shorts[i*3+2] = color[i].blue;
}
} else {
screen->rfbServerFormat.redShift = 0;
screen->rfbServerFormat.greenShift = 2;
screen->rfbServerFormat.blueShift = 5;
screen->rfbServerFormat.redMax = 3;
screen->rfbServerFormat.greenMax = 7;
screen->rfbServerFormat.blueMax = 3;
}
} else {
screen->rfbServerFormat.redShift = 0;
if ( framebufferImage->red_mask )
while ( ! ( framebufferImage->red_mask & (1 << screen->rfbServerFormat.redShift) ) )
screen->rfbServerFormat.redShift++;
screen->rfbServerFormat.greenShift = 0;
if ( framebufferImage->green_mask )
while ( ! ( framebufferImage->green_mask & (1 << screen->rfbServerFormat.greenShift) ) )
screen->rfbServerFormat.greenShift++;
screen->rfbServerFormat.blueShift = 0;
if ( framebufferImage->blue_mask )
while ( ! ( framebufferImage->blue_mask & (1 << screen->rfbServerFormat.blueShift) ) )
screen->rfbServerFormat.blueShift++;
screen->rfbServerFormat.redMax = framebufferImage->red_mask >> screen->rfbServerFormat.redShift;
screen->rfbServerFormat.greenMax = framebufferImage->green_mask >> screen->rfbServerFormat.greenShift;
screen->rfbServerFormat.blueMax = framebufferImage->blue_mask >> screen->rfbServerFormat.blueShift;
}
backupImage = malloc(screen->height*screen->paddedWidthInBytes);
memcpy(backupImage,framebufferImage->data,screen->height*screen->paddedWidthInBytes);
screen->frameBuffer = backupImage;
screen->cursor = 0;
screen->newClientHook = newClient;
screen->kbdAddEvent = keyboard;
screen->ptrAddEvent = mouse;
if(sharedMode) {
screen->rfbAlwaysShared = TRUE;
}
screen->rfbDeferUpdateTime = 1;
updateCounter /= screen->rfbDeferUpdateTime;
rfbInitServer(screen);
c=0;
while(1) {
if(screen->rfbClientHead)
maxMsecsToConnect = 1<<16;
else {
maxMsecsToConnect -= screen->rfbDeferUpdateTime;
if(maxMsecsToConnect<0) {
fprintf(stderr,"Maximum time to connect reached. Exiting.\n");
XTestDiscard(dpy);
exit(2);
}
}
#ifdef LOCAL_CONTROL
if(get_next_message(message,1024,&single_instance,50)) {
if(message[0]=='l' && message[1]==0) {
rfbClientPtr cl;
int i;
for(i=0,cl=screen->rfbClientHead;cl;cl=cl->next,i++)
fprintf(stderr,"%02d: %s\n",i,cl->host);
} else if(message[0]=='t') {
rfbClientPtr cl;
for(cl=screen->rfbClientHead;cl;cl=cl->next)
if(!strcmp(message+1,cl->host)) {
cl->clientData=(void*)((cl->clientData==0)?-1:0);
break;
}
}
#ifdef BACKCHANNEL
else if(message[0]=='b')
rfbSendBackChannel(screen,message+1,strlen(message+1));
#endif
}
#endif
rfbProcessEvents(screen,-1);
if(shutDownServer) {
free(backupImage);
rfbScreenCleanup(screen);
XFree(dpy);
#ifndef NO_SHM
XShmDetach(dpy,&shminfo);
#endif
exit(0);
}
if(dontTile) {
if(gotInput) {
gotInput = FALSE;
c=updateCounter;
} else if(screen->rfbClientHead && c++>updateCounter) {
c=0;
//fprintf(stderr,"*");
if(!useSHM)
framebufferImage->f.destroy_image(framebufferImage);
if(dontTile) {
getImage(screen->rfbServerFormat.bitsPerPixel,dpy,xscreen,&framebufferImage,0,0,screen->width,screen->height);
checkForImageUpdates(screen,framebufferImage->data,framebufferImage->bytes_per_line,
0,0,screen->width,screen->height);
} else {
/* old tile code. Eventually to be removed (TODO) */
char isRightEdge = tileX+tileWidth>=screen->width;
char isLowerEdge = tileY+tileHeight>=screen->height;
getImage(screen->rfbServerFormat.bitsPerPixel,dpy,xscreen,&framebufferImage,tileX,tileY,
isRightEdge?screen->width-tileX:tileWidth,
isLowerEdge?screen->height-tileY:tileHeight);
checkForImageUpdates(screen,framebufferImage->data,framebufferImage->bytes_per_line,
tileX,tileY,
isRightEdge?screen->width-tileX:tileWidth,
isLowerEdge?screen->height-tileY:tileHeight);
if(isRightEdge) {
tileX=0;
if(isLowerEdge)
tileY=0;
else
tileY+=tileHeight;
} else
tileX+=tileWidth;
}
}
} else if(c++>updateCounter) {
c=0;
probeScreen(screen,xscreen);
}
#ifdef WRITE_SNAPS
{
int i,j,r,g,b;
FILE* f=fopen("test.pnm","wb");
fprintf(f,"P6\n%d %d\n255\n",screen->width,screen->height);
for(j=0;j<screen->height;j++)
for(i=0;i<screen->width;i++) {
//r=screen->frameBuffer[j*screen->paddedWidthInBytes+i*2];
r=framebufferImage->data[j*screen->paddedWidthInBytes+i*2];
fputc(((r>>screen->rfbServerFormat.redShift)&screen->rfbServerFormat.redMax)*255/screen->rfbServerFormat.redMax,f);
fputc(((r>>screen->rfbServerFormat.greenShift)&screen->rfbServerFormat.greenMax)*255/screen->rfbServerFormat.greenMax,f);
fputc(((r>>screen->rfbServerFormat.blueShift)&screen->rfbServerFormat.blueMax)*255/screen->rfbServerFormat.blueMax,f);
}
fclose(f);
}
#endif
}
#ifndef NO_SHM
//XShmDetach(dpy,framebufferImage);
#endif
return(0);
}
Loading…
Cancel
Save