New droidvncgrab lib

This library allows one to compile droidVNCserver without having AOSP.
Screen grabbing is performed by this library, which is compiled against
AOSP.
This commit is contained in:
JosePereira 2012-05-06 20:08:57 +01:00
parent 9ee1545d6d
commit 190a5509f4
392 changed files with 285403 additions and 0 deletions

24
droidvncgrab/Android.mk Executable file
View File

@ -0,0 +1,24 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES = \
droidVncGrab.cpp
#LOCAL_CFLAGS += -DPLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION)
LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_PRELINK_MODULE:=false #override prelink map
LOCAL_MODULE:= droidvncgrab_sdk$(PLATFORM_SDK_VERSION)
LOCAL_MODULE_TAGS:= optional
ifeq ($(PLATFORM_SDK_VERSION),9)
LOCAL_SHARED_LIBRARIES := libsurfaceflinger_client libui libbinder libutils libcutils #libcrypto libssl libhardware
else ifeq ($(PLATFORM_SDK_VERSION),15)
LOCAL_SHARED_LIBRARIES := libgui libui libbinder libcutils
else
#add here more sdk versions
LOCAL_SHARED_LIBRARIES := libsurfaceflinger_client libui libbinder libutils libcutils #libcrypto libssl libhardware
endif
include $(BUILD_SHARED_LIBRARY)

1
droidvncgrab/README Normal file
View File

@ -0,0 +1 @@
This

83
droidvncgrab/droidVncGrab.cpp Executable file
View File

@ -0,0 +1,83 @@
/*
droid vnc server - Android VNC server
Copyright (C) 2009 Jose Pereira <onaips@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "droidVncGrab.h"
#include "screenFormat.h"
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <binder/IMemory.h>
#include <surfaceflinger/ISurfaceComposer.h>
#include <surfaceflinger/SurfaceComposerClient.h>
using namespace android;
ScreenshotClient *screenshotClient=NULL;
extern "C" screenFormat getScreenFormat()
{
//get format on PixelFormat struct
PixelFormat f=screenshotClient->getFormat();
PixelFormatInfo pf;
getPixelFormatInfo(f,&pf);
screenFormat format;
format.bitsPerPixel = pf.bitsPerPixel;
format.width = screenshotClient->getWidth();
format.height = screenshotClient->getHeight();
format.size = pf.bitsPerPixel*format.width*format.height/CHAR_BIT;
format.redShift = pf.l_red;
format.redMax = pf.h_red;
format.greenShift = pf.l_green;
format.greenMax = pf.h_green-pf.h_red;
format.blueShift = pf.l_blue;
format.blueMax = pf.h_blue-pf.h_green;
format.alphaShift = pf.l_alpha;
format.alphaMax = pf.h_alpha-pf.h_blue;
return format;
}
extern "C" int initScreenGrab()
{
int errno;
L("--Initializing gingerbread access method--\n");
screenshotClient=new ScreenshotClient();
errno=screenshotClient->update();
if (errno != NO_ERROR) {
L("screen capture failed: %s\n", strerror(-errno));
return -1;
}
return 0;
}
extern "C" unsigned int * getScreenBuffer()
{
screenshotClient->update();
return (unsigned int*)screenshotClient->getPixels();
}

36
droidvncgrab/droidVncGrab.h Executable file
View File

@ -0,0 +1,36 @@
/*
droid vnc server - Android VNC server
Copyright (C) 2009 Jose Pereira <onaips@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef DISPLAY_BINDER
#define DISPLAY_BINDER
#ifdef __cplusplus
#define L(...) __android_log_print(ANDROID_LOG_INFO,"VNCserver",__VA_ARGS__);printf(__VA_ARGS__);
extern "C" {
#endif
unsigned int * updateScreen();
int initScreenGrab();
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,26 @@
#include <stdint.h>
typedef struct _screenFormat
{
uint16_t width;
uint16_t height;
uint8_t bitsPerPixel;
uint16_t redMax;
uint16_t greenMax;
uint16_t blueMax;
uint16_t alphaMax;
uint8_t redShift;
uint8_t greenShift;
uint8_t blueShift;
uint8_t alphaShift;
uint32_t size;
uint32_t pad;
} screenFormat;

Binary file not shown.

94
droidvncgrab/vnc/Android.mk Executable file
View File

@ -0,0 +1,94 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm
local_c_flags += -Wall -O3 -DLIBVNCSERVER_WITH_WEBSOCKETS -DLIBVNCSERVER_HAVE_LIBPNG
local_src_files:= \
input.c \
gui.c \
adb_method.c \
framebuffer_method.c \
suinput.c \
droidvncserver.c \
gralloc_method.c \
libvncserver-kanaka/libvncserver/scale.c \
libvncserver-kanaka/libvncserver/main.c \
libvncserver-kanaka/libvncserver/rfbserver.c \
libvncserver-kanaka/libvncserver/rfbregion.c \
libvncserver-kanaka/libvncserver/auth.c \
libvncserver-kanaka/libvncserver/sockets.c \
libvncserver-kanaka/libvncserver/stats.c \
libvncserver-kanaka/libvncserver/corre.c \
libvncserver-kanaka/libvncserver/hextile.c \
libvncserver-kanaka/libvncserver/rre.c \
libvncserver-kanaka/libvncserver/translate.c \
libvncserver-kanaka/libvncserver/cutpaste.c \
libvncserver-kanaka/libvncserver/httpd.c \
libvncserver-kanaka/libvncserver/cursor.c \
libvncserver-kanaka/libvncserver/font.c \
libvncserver-kanaka/libvncserver/draw.c \
libvncserver-kanaka/libvncserver/selbox.c \
libvncserver-kanaka/libvncserver/minilzo.c \
libvncserver-kanaka/libvncserver/vncauth.c \
libvncserver-kanaka/libvncserver/d3des.c \
libvncserver-kanaka/libvncserver/md5.c \
libvncserver-kanaka/libvncserver/cargs.c \
libvncserver-kanaka/libvncserver/ultra.c \
libvncserver-kanaka/libvncserver/zlib.c \
libvncserver-kanaka/libvncserver/zrle.c \
libvncserver-kanaka/libvncserver/zrleoutstream.c \
libvncserver-kanaka/libvncserver/zrlepalettehelper.c \
libvncserver-kanaka/libvncserver/tight.c \
libvncserver-kanaka/libvncserver/zywrletemplate.c \
libvncserver-kanaka/libvncserver/websockets.c
ginger_up := displaybinder.cpp
local_c_includes := \
$(LOCAL_PATH) \
$(LOCAL_PATH)/libvncserver-kanaka/libvncserver \
$(LOCAL_PATH)/libvncserver-kanaka \
$(LOCAL_PATH)/libvncserver-kanaka/common \
$(LOCAL_PATH)/../../zlib \
$(LOCAL_PATH)/../../jpeg \
$(LOCAL_PATH)/../../openssl/include \
$(LOCAL_PATH)/../../libpng \
#######################################
# target
include $(CLEAR_VARS)
LOCAL_SRC_FILES += $(local_src_files)
LOCAL_CFLAGS += $(local_c_flags) -DANDROID_FROYO
LOCAL_C_INCLUDES += $(local_c_includes)
LOCAL_MODULE:= androidvncserver_froyo
LOCAL_MODULE_TAGS:= optional
LOCAL_STATIC_LIBRARIES := libcutils libz libpng jpeg
LOCAL_SHARED_LIBRARIES := libcrypto libssl libhardware
include $(BUILD_EXECUTABLE)
#######################################
# target
include $(CLEAR_VARS)
LOCAL_SRC_FILES += $(local_src_files) $(ginger_up)
LOCAL_CFLAGS += $(local_c_flags)
LOCAL_C_INCLUDES += $(local_c_includes)
LOCAL_MODULE:= androidvncserver_gingerup
LOCAL_MODULE_TAGS:= optional
LOCAL_STATIC_LIBRARIES := libcutils libz libpng jpeg
LOCAL_SHARED_LIBRARIES := libcrypto libssl libhardware libsurfaceflinger_client libui
include $(BUILD_EXECUTABLE)

284
droidvncgrab/vnc/adb_method.c Executable file
View File

@ -0,0 +1,284 @@
/*
droid vnc server - Android VNC server
Copyright (C) 2009 Jose Pereira <onaips@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "adb_method.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <cutils/properties.h>
//#include "common.h"
#define A_CNXN 0x4e584e43
#define A_OKAY 0x59414b4f
#define A_CLSE 0x45534c43
#define A_WRTE 0x45545257
#define DDMS_RAWIMAGE_VERSION 1
char connect_string[] = {
0x43, 0x4e, 0x58, 0x4e, 0x00, 0x00, 0x00, 0x01,
0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x32, 0x02, 0x00, 0x00, 0xbc, 0xb1, 0xa7, 0xb1,
0x68, 0x6f, 0x73, 0x74, 0x3a, 0x3a, 0x00 };
char framebuffer_string[] = {
0x4f, 0x50, 0x45, 0x4e, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
0xbf, 0x04, 0x00, 0x00, 0xb0, 0xaf, 0xba, 0xb1,
0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, 0x66,
0x66, 0x65, 0x72, 0x3a, 0x00 };
char okay_string[24];
struct fbinfo *fb_info;
struct _message *message,*okay_message;
int sockfd;
ssize_t write_socket(int fd, const void *buf, size_t count)
{
// L("--Writing %d \n",count);
int n = write(fd,buf,count);
if (n < 0)
perror("ERROR writing to socket");
return n;
}
void read_socket(int fd, void *buf, size_t count)
{
int n=0;
while (count>0)
{
n=read(fd,buf,count);
if (n < 0)
L("ERROR reading from socket\n");
count-=n;
}
return;
}
void send_connect_string()
{
write_socket(sockfd,connect_string,sizeof(connect_string));
read_socket(sockfd,message,sizeof(struct _message));
if (message->command!=A_CNXN)
L("bad A_CNXN response\n");
//lets read, i don't want this
read_socket(sockfd,message,message->data_length);
}
void send_framebuffer_string();
int initADB()
{
L("--Initializing adb access method--\n");
int portno;
struct sockaddr_in serv_addr;
struct hostent *server;
adbbuf=NULL;
property_set("service.adb.tcp.port", "5555");
system("setprop service.adb.tcp.port 5555");
system("adbd");
message=malloc(sizeof(struct _message));
okay_message=malloc(sizeof(struct _message));
// L("1\n");
portno = 5555;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
L("adb ERROR opening socket\n");
return -1;
}
#ifdef ANDROID
server = gethostbyname("127.0.0.1");
#else
server = gethostbyname("192.168.10.6");
#endif
if (server == NULL) {
L("adb ERROR, no such host\n");
return -1;
}
// L("2\n");
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
{
L("adb ERROR connecting\n");
return -1;
}
// L("3\n");
send_connect_string();
// L("4\n");
return 0;
}
void send_framebuffer_string()//returns the fb struct size from adb
{
int n;
char *buffer=NULL;
write_socket(sockfd,framebuffer_string,sizeof(framebuffer_string));
read_socket(sockfd,okay_message,sizeof(struct _message));
if (okay_message->command!=A_OKAY)
{
L("---\ncommand=%32X\narg0=%32X\narg1=%32X\ndata_len=%d\n---\n",message->command,message->arg0,message->arg1,message->data_length);
L("bad OKAY response on send_framebuffer_string\n");
}
n=okay_message->arg0;
okay_message->arg0=okay_message->arg1;
okay_message->arg1=n;
// L("arg0=%08X\narg1=%08X\n",okay_message->arg0,okay_message->arg1);
//we now have our okay message
//lets receive fb info...
read_socket(sockfd,message,sizeof(struct _message));
if (message->command!=A_WRTE)
L("bad WRTE response\n");
// L("---\ncommand=%32X\narg0=%32X\narg1=%32X\ndata_len=%d\n---\n",message->command,message->arg0,message->arg1,message->data_length);
// if (message->data_length!=sizeof(struct _message))
// error("Size should match...");
buffer=(char*)malloc(sizeof(char)*message->data_length);
read_socket(sockfd,&displayInfo,sizeof(struct fbinfo));
// L("sizeof(struct fbinfo)=%d\n",sizeof(struct fbinfo));
// L("ADB framebuffer method:\nversion=%d\nbpp=%d\nsize=%d bytes\nwidth=%dpx\nheight=%dpx\nsize=%d\n",
// displayInfo.version,displayInfo.bpp,displayInfo.size,displayInfo.width,displayInfo.height,displayInfo.size);
// L("sizeof(struct _message)=%d\n",sizeof(struct _message));
write_socket(sockfd,okay_message,sizeof(struct _message));
if (adbbuf==NULL)
adbbuf=(unsigned int*)malloc(displayInfo.size);
}
void updateADBFrame()
{
int n=0;
int count=0;
send_framebuffer_string();
// L("1\n");
while (message->command!=A_CLSE)
{
read_socket(sockfd,message,sizeof(struct _message));
// L("---\ncommand=%32X\narg0=%32X\narg1=%32X\ndata_len=%d\n---\n",message->command,message->arg0,message->arg1,message->data_length);
if (message->command==A_CLSE)
break;
else if (message->command!=A_WRTE)
{
L("Weird command received... %08X\n",message->command);
L("---\ncommand=%32X\narg0=%32X\narg1=%32X\ndata_len=%d\n---\n",message->command,message->arg0,message->arg1,message->data_length);
}
char * s=(char*)adbbuf+count;
read_socket(sockfd,s,message->data_length);
count+=message->data_length;
// L("ahah %d %d\n",message->data_length,n);
n=write_socket(sockfd,okay_message,sizeof(struct _message));
if (n<0)
break;
}
// L("Exit updating...\n");
// L("Received %d bytes\n",count);
// if (resp!=A_OKAY)
// error("bad OKAY response");
}
#ifndef ANDROID
void main()
{
connect_to_adb();
L("up\n");
update_frame();
L("up\n");
update_frame();
}
#endif
// int main(int argc, char *argv[])
// {
// message=(struct _message*)malloc(sizeof(struct _message));
// okay_message=(struct _message*)malloc(sizeof(struct _message));
//
// connect_to_adb();
//
// // adbbuf=calloc(fb_info->size,1);
//
// update_frame();
//
//
// close(sockfd);
// return 0;
// }

66
droidvncgrab/vnc/adb_method.h Executable file
View File

@ -0,0 +1,66 @@
/*
droid vnc server - Android VNC server
Copyright (C) 2009 Jose Pereira <onaips@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ADB_CONNECT_METHOD
#define ADB_CONNECT_METHOD
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
// #include <cutils/properties.h>
#include "common.h"
#define A_CNXN 0x4e584e43
#define A_OKAY 0x59414b4f
#define A_CLSE 0x45534c43
#define A_WRTE 0x45545257
#define DDMS_RAWIMAGE_VERSION 1
struct _message {
unsigned int command; /* command identifier constant */
unsigned int arg0; /* first argument */
unsigned int arg1; /* second argument */
unsigned int data_length; /* length of payload (0 is allowed) */
unsigned int data_crc32; /* crc32 of data payload */
unsigned int magic; /* command ^ 0xffffffff */
} __attribute__((packed));
// void error(const char *msg);
// ssize_t write_socket(int fd, const void *buf, size_t count);
// ssize_t read_socket(int fd, void *buf, size_t count);
// void send_connect_string();
int initADB();
void updateADBFrame();
unsigned int *adbbuf;
#endif

97
droidvncgrab/vnc/common.h Executable file
View File

@ -0,0 +1,97 @@
/*
droid vnc server - Android VNC server
Copyright (C) 2009 Jose Pereira <onaips@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef COMMON_H
#define COMMON_H
//android log
#include <android/log.h>
#ifndef __cplusplus
/* libvncserver */
#include "rfb/rfb.h"
#include "libvncserver/scale.h"
#include "rfb/keysym.h"
#include "suinput.h"
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/sysmacros.h> /* For makedev() */
#include <fcntl.h>
#include <linux/fb.h>
#include <linux/input.h>
#include <assert.h>
#include <errno.h>
#define SOCK_PATH "org.onaips.vnc.gui"
#include <cutils/log.h>
// #define L(...) do { __android_log_print(ANDROID_LOG_INFO,"VNCserver",__VA_ARGS__); } while (0)
// #define L(...) __android_log_print(ANDROID_LOG_INFO,"VNCserver",__VA_ARGS__);printf(__VA_ARGS__);
#define L(...) do{ __android_log_print(ANDROID_LOG_INFO,"VNCserver",__VA_ARGS__);printf(__VA_ARGS__); } while (0);
#endif
struct fbinfo {
unsigned int version;
unsigned int bpp;
unsigned int size;
unsigned int width;
unsigned int height;
unsigned int red_offset;
unsigned int red_length;
unsigned int blue_offset;
unsigned int blue_length;
unsigned int green_offset;
unsigned int green_length;
unsigned int alpha_offset;
unsigned int alpha_length;
} __attribute__((packed));
void rotate(int);
int getCurrentRotation();
int isIdle();
void setIdle(int i);
void close_app();
struct fbinfo displayInfo;
#endif

View File

@ -0,0 +1,75 @@
/*
droid vnc server - Android VNC server
Copyright (C) 2009 Jose Pereira <onaips@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "displaybinder.h"
#include "common.h"
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <binder/IMemory.h>
#include <surfaceflinger/ISurfaceComposer.h>
#include <surfaceflinger/SurfaceComposerClient.h>
using namespace android;
ScreenshotClient *screenshotclient;
extern "C" int initGingerbreadMethod()
{
L("--Initializing gingerbread access method--\n");
screenshotclient=new ScreenshotClient();
int err=screenshotclient->update();
if (err != NO_ERROR) {
L("screen capture failed: %s\n", strerror(-err));
//mandar msg incompatible
return -1;
}
PixelFormat f=screenshotclient->getFormat();
PixelFormatInfo pf;
getPixelFormatInfo(f,&pf);
displayInfo.bpp = pf.bitsPerPixel;
displayInfo.width = screenshotclient->getWidth();
displayInfo.height = screenshotclient->getHeight();;
displayInfo.size = pf.bitsPerPixel*displayInfo.width*displayInfo.height/CHAR_BIT;
displayInfo.red_offset = pf.l_red;
displayInfo.red_length = pf.h_red;
displayInfo.green_offset = pf.l_green;
displayInfo.green_length = pf.h_green-pf.h_red;
displayInfo.blue_offset = pf.l_blue;
displayInfo.blue_length = pf.h_blue-pf.h_green;
displayInfo.alpha_offset = pf.l_alpha;
displayInfo.alpha_length = pf.h_alpha-pf.h_blue;
return 0;
}
extern "C" void updateScreen()
{
screenshotclient->update();
gingerbuf=(unsigned int*)screenshotclient->getPixels();
}

View File

@ -0,0 +1,42 @@
/*
droid vnc server - Android VNC server
Copyright (C) 2009 Jose Pereira <onaips@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef DISPLAY_BINDER
#define DISPLAY_BINDER
unsigned int *gingerbuf;
#ifdef __cplusplus
#define L(...) __android_log_print(ANDROID_LOG_INFO,"VNCserver",__VA_ARGS__);printf(__VA_ARGS__);
extern "C" {
#endif
void updateScreen();
int initGingerbreadMethod();
#ifdef __cplusplus
}
#endif
#endif

513
droidvncgrab/vnc/droidvncserver.c Executable file
View File

@ -0,0 +1,513 @@
/*
droid vnc server - Android VNC server
Copyright (C) 2009 Jose Pereira <onaips@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "common.h"
#include "framebuffer_method.h"
#include "gralloc_method.h"
#include "adb_method.h"
#include "gui.h"
#include "input.h"
#include "displaybinder.h"
#define CONCAT2(a,b) a##b
#define CONCAT2E(a,b) CONCAT2(a,b)
#define CONCAT3(a,b,c) a##b##c
#define CONCAT3E(a,b,c) CONCAT3(a,b,c)
char VNC_PASSWORD[256] = "";
int VNC_PORT=5901;
/* Android already has 5900 bound natively in some devices. */
unsigned int *cmpbuf;
unsigned int *vncbuf;
static rfbScreenInfoPtr vncscr;
int idle=0,standby=0, rotation=0,scaling=100;
char *rhost=NULL;
int rport=5500;
void (*update_screen)(void)=NULL;
enum method_type {AUTO,FRAMEBUFFER,ADB,GRALLOC
#ifndef ANDROID_FROYO
,GINGERBREAD};
#else
};
#endif
enum method_type method=AUTO;
#define PIXEL_TO_VIRTUALPIXEL_FB(i,j) ((j+scrinfo.yoffset)*scrinfo.xres_virtual+i+scrinfo.xoffset)
#define PIXEL_TO_VIRTUALPIXEL(i,j) ((j*displayInfo.width)+i)
#define OUT 8
#include "update_screen.c"
#undef OUT
#define OUT 16
#include "update_screen.c"
#undef OUT
// #define OUT 24
// #include "update_screen.c"
// #undef OUT
#define OUT 32
#include "update_screen.c"
#undef OUT
inline int getCurrentRotation()
{
return rotation;
}
inline int isIdle()
{
return idle;
}
void setIdle(int i)
{
idle=i;
}
ClientGoneHookPtr clientGone(rfbClientPtr cl)
{
sendMsgToGui("~DISCONNECTED|\n");
return 0;
}
rfbNewClientHookPtr clientHook(rfbClientPtr cl)
{
if (scaling!=100)
{
rfbScalingSetup(cl, vncscr->width*scaling/100.0, vncscr->height*scaling/100.0);
L("Scaling to w=%d h=%d\n",(int)(vncscr->width*scaling/100.0), (int)(vncscr->height*scaling/100.0));
// rfbSendNewScaleSize(cl);
}
cl->clientGoneHook=(ClientGoneHookPtr)clientGone;
char *header="~CONNECTED|";
char *msg=malloc(sizeof(char)*((strlen(cl->host)) + strlen(header)+1));
msg[0]='\0';
strcat(msg,header);
strcat(msg,cl->host);
strcat(msg,"\n");
sendMsgToGui(msg);
free (msg);
return RFB_CLIENT_ACCEPT;
}
void CutText(char* str,int len, struct _rfbClientRec* cl)
{
str[len]='\0';
char *header="~CLIP|\n";
char *msg=malloc(sizeof(char)*(strlen(str) + strlen(header)+1));
msg[0]='\0';
strcat(msg,header);
strcat(msg,str);
strcat(msg,"\n");
sendMsgToGui(msg);
free(msg);
}
void sendServerStarted(){
sendMsgToGui("~SERVERSTARTED|\n");
}
void sendServerStopped()
{
sendMsgToGui("~SERVERSTOPPED|\n");
}
void initVncServer(int argc, char **argv)
{
vncbuf = calloc(displayInfo.width * displayInfo.height, displayInfo.bpp/CHAR_BIT);
cmpbuf = calloc(displayInfo.width * displayInfo.height, displayInfo.bpp/CHAR_BIT);
assert(vncbuf != NULL);
assert(cmpbuf != NULL);
if (rotation==0 || rotation==180)
vncscr = rfbGetScreen(&argc, argv, displayInfo.width , displayInfo.height, 0 /* not used */ , 3, displayInfo.bpp/CHAR_BIT);
else
vncscr = rfbGetScreen(&argc, argv, displayInfo.height, displayInfo.width, 0 /* not used */ , 3, displayInfo.bpp/CHAR_BIT);
assert(vncscr != NULL);
vncscr->desktopName = "Android";
vncscr->frameBuffer =(char *)vncbuf;
vncscr->port = VNC_PORT;
vncscr->kbdAddEvent = keyEvent;
vncscr->ptrAddEvent = ptrEvent;
vncscr->newClientHook = (rfbNewClientHookPtr)clientHook;
vncscr->setXCutText = CutText;
if (strcmp(VNC_PASSWORD,"")!=0)
{
char **passwords = (char **)malloc(2 * sizeof(char **));
passwords[0] = VNC_PASSWORD;
passwords[1] = NULL;
vncscr->authPasswdData = passwords;
vncscr->passwordCheck = rfbCheckPasswordByList;
}
vncscr->httpDir="/data/data/org.onaips.vnc/files/";
vncscr->sslcertfile="self.pem";
vncscr->serverFormat.redShift=displayInfo.red_offset;
vncscr->serverFormat.greenShift=displayInfo.green_offset;
vncscr->serverFormat.blueShift=displayInfo.blue_offset;
vncscr->serverFormat.redMax=((1<<displayInfo.red_length)-1);
vncscr->serverFormat.greenMax=((1<<displayInfo.green_length)-1);
vncscr->serverFormat.blueMax=((1<<displayInfo.blue_length)-1);
vncscr->serverFormat.bitsPerPixel=displayInfo.bpp;
vncscr->alwaysShared = TRUE;
vncscr->handleEventsEagerly = TRUE;
vncscr->deferUpdateTime = 5;
rfbInitServer(vncscr);
//assign update_screen depending on bpp
if (vncscr->serverFormat.bitsPerPixel == 32)
update_screen=&CONCAT2E(update_screen_,32);
// else if (vncscr->serverFormat.bitsPerPixel == 24)
// update_screen=&CONCAT2E(update_screen_,24);
else if (vncscr->serverFormat.bitsPerPixel == 16)
update_screen=&CONCAT2E(update_screen_,16);
else if (vncscr->serverFormat.bitsPerPixel == 8)
update_screen=&CONCAT2E(update_screen_,8);
else {
L("Unsupported pixel depth: %d\n",
vncscr->serverFormat.bitsPerPixel);
sendMsgToGui("~SHOW|Unsupported pixel depth, please send bug report.\n");
return;
}
/* Mark as dirty since we haven't sent any updates at all yet. */
rfbMarkRectAsModified(vncscr, 0, 0, vncscr->width, vncscr->height);
}
void rotate(int value)
{
L("rotate()");
if (value==-1 ||
((value==90 || value==270) && (rotation==0 || rotation==180)) ||
((value==0 || value==180) && (rotation==90 || rotation==270)))
{
int h=vncscr->height;
int w=vncscr->width;
vncscr->width = h;
vncscr->paddedWidthInBytes = h * displayInfo.bpp / CHAR_BIT;
vncscr->height = w;
{
rfbClientIteratorPtr iterator;
rfbClientPtr cl;
iterator = rfbGetClientIterator(vncscr);
while ((cl = rfbClientIteratorNext(iterator)) != NULL)
cl->newFBSizePending = 1;
}
}
if (value==-1)
{
rotation+=90;
rotation=rotation%360;
}
else
{
rotation=value;
}
rfbMarkRectAsModified(vncscr, 0, 0, vncscr->width, vncscr->height);
}
void close_app()
{
L("Cleaning up...\n");
cleanupFramebuffer();
cleanupInput();
sendServerStopped();
unbindIPCserver();
exit(0); /* normal exit status */
}
void extractReverseHostPort(char *str)
{
int len=strlen(str);
char *p;
/* copy in to host */
rhost = (char *) malloc(len+1);
if (! rhost) {
L("reverse_connect: could not malloc string %d\n", len);
exit(-1);
}
strncpy(rhost, str, len);
rhost[len] = '\0';
/* extract port, if any */
if ((p = strrchr(rhost, ':')) != NULL) {
rport = atoi(p+1);
if (rport < 0) {
rport = -rport;
} else if (rport < 20) {
rport = 5500 + rport;
}
*p = '\0';
}
}
void printUsage(char **argv)
{
L("\nandroidvncserver [parameters]\n"
"-f <device>\t- Framebuffer device (only with -m fb, default is /dev/graphics/fb0)\n"
"-h\t\t- Print this help\n"
"-m <method>\t- Display grabber method\n\tfb: framebuffer\n\tgb: gingerbread+ devices\n\tadb: slower, but should be compatible with all devices\n"
"-p <password>\t- Password to access server\n"
"-r <rotation>\t- Screen rotation (degrees) (0,90,180,270)\n"
"-R <host:port>\t- Host for reverse connection\n"
"-s <scale>\t- Scale percentage (20,30,50,100,150)\n\n" );
}
int main(int argc, char **argv)
{
signal(SIGINT, close_app);//pipe signals
signal(SIGKILL, close_app);
signal(SIGILL, close_app);
if(argc > 1)
{
int i=1;
int r;
while(i < argc)
{
if(*argv[i] == '-')
{
switch(*(argv[i] + 1))
{
case 'h':
printUsage(argv);
exit(0);
break;
case 'p':
i++;
strcpy(VNC_PASSWORD,argv[i]);
break;
case 'f':
i++;
setFramebufferDevice(argv[i]);
break;
case 'P':
i++;
VNC_PORT=atoi(argv[i]);
break;
case 'r':
i++;
r=atoi(argv[i]);
if (r==0 || r==90 || r==180 || r==270)
rotation=r;
L("rotating to %d degrees\n",rotation);
break;
case 's':
i++;
r=atoi(argv[i]);
if (r>=1 && r <= 150)
scaling=r;
else
scaling=100;
L("scaling to %d percent\n",scaling);
break;
case 'm':
i++;
if (strcmp(argv[i],"adb")==0)
{
method=ADB;
L("ADB display grabber selected\n");
}
else if (strcmp(argv[i],"fb")==0)
{
method=FRAMEBUFFER;
L("Framebuffer display grabber selected\n");
}
else if (strcmp(argv[i],"gralloc")==0)
{
method=GRALLOC;
L("Gralloc display grabber selected\n");
}
#ifndef ANDROID_FROYO
else if (strcmp(argv[i],"gingerbread")==0)
{
method=GINGERBREAD;
L("Gingerbread display grabber selected\n");
}
#endif
else
{
L("Grab method \"%s\" not found, reverting to default.\n",argv[i]);
}
break;
case 'R':
i++;
extractReverseHostPort(argv[i]);
break;
}
}
i++;
}
}
L("Initializing grabber method...\n");
if (method==AUTO)
{
L("No grabber method selected, auto-detecting...");
do
{
#ifndef ANDROID_FROYO
if (initGingerbreadMethod()!=-1)
method=GINGERBREAD;
else
#endif
if (init_gralloc()!=-1)
method=GRALLOC;
else if (initFramebuffer()!=-1)
method=FRAMEBUFFER;
else if (initADB()!=-1)
{
method=ADB;
updateADBFrame();
}
break;
}
while (0);
}
else if (method==FRAMEBUFFER)
initFramebuffer();
else if (method==ADB)
{
initADB();
updateADBFrame();
}
else if (method==GRALLOC)
init_gralloc();
#ifndef ANDROID_FROYO
else if (method==GINGERBREAD)
initGingerbreadMethod();
#endif
L("Initializing virtual keyboard and touch device...\n");
initInput();
L("Initializing VNC server:\n");
L(" width: %d\n", (int)displayInfo.width);
L(" height: %d\n", (int)displayInfo.height);
L(" bpp: %d\n", (int)displayInfo.bpp);
L(" port: %d\n", (int)VNC_PORT);
L("Colourmap_rgba=%d:%d:%d:%d lenght=%d:%d:%d:%d\n",displayInfo.red_offset,displayInfo.green_offset,displayInfo.blue_offset,displayInfo.alpha_offset,
displayInfo.red_length,displayInfo.green_length,displayInfo.blue_length,displayInfo.alpha_length);
initVncServer(argc, argv);
bindIPCserver();
sendServerStarted();
if (rhost)
{
rfbClientPtr cl;
cl = rfbReverseConnection(vncscr, rhost, rport);
if (cl == NULL)
{
char *str=malloc(255*sizeof(char));
sprintf(str,"~SHOW|Couldn't connect to remote host:\n%s\n",rhost);
L("Couldn't connect to remote host: %s\n",rhost);
sendMsgToGui(str);
free(str);
}
else
{
cl->onHold = FALSE;
rfbStartOnHoldClient(cl);
}
}
rfbRunEventLoop(vncscr,-1,TRUE);
while (1)
{
usleep(300000*(standby/2.0));
if (idle)
standby++;
else
standby=2;
if (vncscr->clientHead == NULL)
continue;
update_screen();
}
close_app();
}

View File

@ -0,0 +1,136 @@
/*
droid VNC server - a vnc server for android
Copyright (C) 2011 Jose Pereira <onaips@gmail.com>
Other contributors:
Oleksandr Andrushchenko <andr2000@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "framebuffer_method.h"
#include "common.h"
#include "gui.h"
int fbfd = -1;
char framebuffer_device[256] = "/dev/graphics/fb0";
void setFramebufferDevice(char *s)
{
strcpy(framebuffer_device,s);
}
int initFramebuffer(void)
{
L("--Initializing framebuffer access method--\n");
fbmmap = MAP_FAILED;
if ((fbfd = open(framebuffer_device, O_RDWR)) == -1)
{
L("Cannot open fb device %s\n", framebuffer_device);
sendMsgToGui("~SHOW|Cannot open fb device, please try out other display grab method\n");
return -1;
}
update_fb_info();
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &fscrinfo) != 0)
{
L("ioctl error\n");
return -1;
}
L("line_lenght=%d xres=%d, yres=%d, xresv=%d, yresv=%d, xoffs=%d, yoffs=%d, bpp=%d\n",
(int)fscrinfo.line_length,(int)scrinfo.xres, (int)scrinfo.yres,
(int)scrinfo.xres_virtual, (int)scrinfo.yres_virtual,
(int)scrinfo.xoffset, (int)scrinfo.yoffset,
(int)scrinfo.bits_per_pixel);
size_t size=scrinfo.yres_virtual;
if (size<scrinfo.yres*2)
{
L("Using Droid workaround\n");
size=scrinfo.yres*2;
}
if ((scrinfo.bits_per_pixel==24))// && (fscrinfo.line_length/scrinfo.xres_virtual==CHAR_BIT*4))
{
scrinfo.bits_per_pixel=32;
L("24-bit XRGB display detected\n");
}
size_t fbSize = roundUpToPageSize(fscrinfo.line_length * size);
fbmmap = mmap(NULL, fbSize , PROT_READ|PROT_WRITE , MAP_SHARED , fbfd, 0);
if (fbmmap == MAP_FAILED)
{
L("mmap failed\n");
sendMsgToGui("~SHOW|Framebuffer mmap failed, please try out other display grab method\n");
return -1;
}
displayInfo.bpp = scrinfo.bits_per_pixel;
displayInfo.size = scrinfo.xres * scrinfo.yres * scrinfo.bits_per_pixel / CHAR_BIT;
displayInfo.width = scrinfo.xres;
displayInfo.height = scrinfo.yres;
displayInfo.red_offset = scrinfo.red.offset;
displayInfo.red_length = scrinfo.red.length;
displayInfo.green_offset = scrinfo.green.offset;
displayInfo.green_length = scrinfo.green.length;
displayInfo.blue_offset = scrinfo.blue.offset;
displayInfo.blue_length = scrinfo.blue.length;
displayInfo.alpha_offset = scrinfo.transp.offset;
displayInfo.alpha_length = scrinfo.transp.length;
return 1;
}
void cleanupFramebuffer(void)
{
if(fbfd != -1)
{
close(fbfd);
}
}
void update_fb_info()
{
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &scrinfo) != 0)
{
L("ioctl error\n");
sendMsgToGui("~SHOW|Framebuffer ioctl error, please try out other display grab method\n");
exit(EXIT_FAILURE);
}
}
inline int roundUpToPageSize(int x) {
return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
}

View File

@ -0,0 +1,36 @@
/*
droid VNC server - a vnc server for android
Copyright (C) 2011 Jose Pereira <onaips@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ADB_FRAMEBUFFER_METHOD
#define ADB_FRAMEBUFFER_METHOD
#include "common.h"
unsigned int *fbmmap;
struct fb_var_screeninfo scrinfo;
struct fb_fix_screeninfo fscrinfo;
int initFramebuffer(void);
void cleanupFramebuffer(void);
void update_fb_info();
int roundUpToPageSize(int x);
void setFramebufferDevice(char *);
#endif

View File

@ -0,0 +1,245 @@
/*
droid vnc server - Android VNC server
Copyright (C) 2011 Jose Pereira <onaips@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "gralloc_method.h"
#include "common.h"
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/fb.h>
#include <hardware/hardware.h>
#include <hardware/gralloc.h>
#include <cutils/log.h>
#define r(fd, ptr, size) (read((fd), (ptr), (size)) != (int)(size))
#define w(fd, ptr, size) (write((fd), (ptr), (size)) != (int)(size))
static int fill_format(struct fbinfo* info, int format)
{
// bpp, red, green, blue, alpha
static const int format_map[][9] = {
{0, 0, 0, 0, 0, 0, 0, 0, 0}, // INVALID
{32, 0, 8, 8, 8, 16, 8, 24, 8}, // HAL_PIXEL_FORMAT_RGBA_8888
{32, 0, 8, 8, 8, 16, 8, 0, 0}, // HAL_PIXEL_FORMAT_RGBX_8888
{24, 16, 8, 8, 8, 0, 8, 0, 0}, // HAL_PIXEL_FORMAT_RGB_888
{16, 11, 5, 5, 6, 0, 5, 0, 0}, // HAL_PIXEL_FORMAT_RGB_565
{32, 16, 8, 8, 8, 0, 8, 24, 8}, // HAL_PIXEL_FORMAT_BGRA_8888
{16, 11, 5, 6, 5, 1, 5, 0, 1}, // HAL_PIXEL_FORMAT_RGBA_5551
{16, 12, 4, 8, 4, 4, 4, 0, 4} // HAL_PIXEL_FORMAT_RGBA_4444
};
const int *p;
if (format == 0 || format > HAL_PIXEL_FORMAT_RGBA_4444)
return -ENOTSUP;
p = format_map[format];
info->bpp = *(p++);
info->red_offset = *(p++);
info->red_length = *(p++);
info->green_offset = *(p++);
info->green_length = *(p++);
info->blue_offset = *(p++);
info->blue_length = *(p++);
info->alpha_offset = *(p++);
info->alpha_length = *(p++);
return 0;
}
#if 0
static int readfb_devfb (int fd)
{
struct fb_var_screeninfo vinfo;
int fb, offset;
char x[256];
int rv = -ENOTSUP;
struct fbinfo fbinfo;
unsigned i, bytespp;
fb = open("/dev/graphics/fb0", O_RDONLY);
if (fb < 0) goto done;
if (ioctl(fb, FBIOGET_VSCREENINFO, &vinfo) < 0) goto done;
fcntl(fb, F_SETFD, FD_CLOEXEC);
bytespp = vinfo.bits_per_pixel / 8;
fbinfo.bpp = vinfo.bits_per_pixel;
fbinfo.size = vinfo.xres * vinfo.yres * bytespp;
fbinfo.width = vinfo.xres;
fbinfo.height = vinfo.yres;
fbinfo.red_offset = vinfo.red.offset;
fbinfo.red_length = vinfo.red.length;
fbinfo.green_offset = vinfo.green.offset;
fbinfo.green_length = vinfo.green.length;
fbinfo.blue_offset = vinfo.blue.offset;
fbinfo.blue_length = vinfo.blue.length;
fbinfo.alpha_offset = vinfo.transp.offset;
fbinfo.alpha_length = vinfo.transp.length;
/* HACK: for several of our 3d cores a specific alignment
* is required so the start of the fb may not be an integer number of lines
* from the base. As a result we are storing the additional offset in
* xoffset. This is not the correct usage for xoffset, it should be added
* to each line, not just once at the beginning */
offset = vinfo.xoffset * bytespp;
offset += vinfo.xres * vinfo.yoffset * bytespp;
rv = 0;
if (w(fd, &fbinfo, sizeof(fbinfo))) goto done;
lseek(fb, offset, SEEK_SET);
for (i = 0; i < fbinfo.size; i += 256) {
if (r(fb, &x, 256)) goto done;
if (w(fd, &x, 256)) goto done;
}
if (r(fb, &x, fbinfo.size % 256)) goto done;
if (w(fd, &x, fbinfo.size % 256)) goto done;
done:
if (fb >= 0) close(fb);
return rv;
}
#endif
struct gralloc_module_t *gralloc;
struct framebuffer_device_t *fbdev = 0;
struct alloc_device_t *allocdev = 0;
buffer_handle_t buf = 0;
unsigned char* data = 0;
int stride;
#define CHECK_RV if (rv != 0){close_gralloc();return -1;}
int init_gralloc()
{
L("--Initializing gralloc access method--\n");
grallocfb=0;
int linebytes;
int rv;
rv = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t**)&gralloc);
CHECK_RV;
rv = framebuffer_open(&gralloc->common, &fbdev);
CHECK_RV;
if (!fbdev->read) {
rv = -ENOTSUP;
close_gralloc();
return rv;
}
rv = gralloc_open(&gralloc->common, &allocdev);
CHECK_RV;
rv = allocdev->alloc(allocdev, fbdev->width, fbdev->height,
fbdev->format, GRALLOC_USAGE_SW_READ_OFTEN,
&buf, &stride);
rv = fbdev->read(fbdev, buf);
CHECK_RV;
rv = gralloc->lock(gralloc, buf, GRALLOC_USAGE_SW_READ_OFTEN, 0, 0,
fbdev->width, fbdev->height, (void**)&data);
CHECK_RV;
rv = fill_format(&displayInfo, fbdev->format);
CHECK_RV;
stride *= (displayInfo.bpp >> 3);
linebytes = fbdev->width * (displayInfo.bpp >> 3);
displayInfo.size = linebytes * fbdev->height;
displayInfo.width = fbdev->width;
displayInfo.height = fbdev->height;
// point of no return: don't attempt alternative means of reading
// after this
rv = 0;
grallocfb=malloc(displayInfo.size);
L("Stride=%d Linebytes=%d %p\n",stride,linebytes,fbdev->setUpdateRect);
memcpy(grallocfb,data,displayInfo.size);
if (data)
gralloc->unlock(gralloc, buf);
L("Copy %d bytes\n",displayInfo.size);
L("Returning rv=%d\n",rv);
return rv;
}
void close_gralloc()
{
if (buf)
allocdev->free(allocdev, buf);
if (allocdev)
gralloc_close(allocdev);
if (fbdev)
framebuffer_close(fbdev);
}
int readfb_gralloc ()
{
int rv;
rv = fbdev->read(fbdev, buf);
CHECK_RV;
rv = gralloc->lock(gralloc, buf, GRALLOC_USAGE_SW_READ_OFTEN, 0, 0,
fbdev->width, fbdev->height, (void**)&data);
CHECK_RV;
memcpy(grallocfb,data,displayInfo.size);
if (data)
gralloc->unlock(gralloc, buf);
return rv;
}

View File

@ -0,0 +1,31 @@
/*
droid vnc server - Android VNC server
Copyright (C) 2009 Jose Pereira <onaips@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef GRALLOC_H
#define GRALLOC_H
unsigned int *grallocfb;
int init_gralloc();
int readfb_gralloc();
void close_gralloc();
#endif

131
droidvncgrab/vnc/gui.c Executable file
View File

@ -0,0 +1,131 @@
/*
droid VNC server - a vnc server for android
Copyright (C) 2011 Jose Pereira <onaips@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "gui.h"
#define SOCKET_ERROR -1
#define BUFFER_SIZE 1024
#define QUEUE_SIZE 1
int hServerSocket; /* handle to socket */
struct sockaddr_in Address; /* Internet socket address stuct */
int nAddressSize=sizeof(struct sockaddr_in);
char pBuffer[BUFFER_SIZE];
static int nHostPort;
int sendMsgToGui(char *buffer)
{
int sock, n;
unsigned int length;
struct sockaddr_in server;
sock= socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) perror("socket");
bzero(&server,sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr=inet_addr("127.0.0.1");
server.sin_port = htons(13131);
length=sizeof(struct sockaddr_in);
n=sendto(sock,buffer,
strlen(buffer),0,(struct sockaddr *)&server,length);
if (n < 0) perror("Sendto");
// L("Sent %s\n",buffer);
// n = recvfrom(sock,buffer,256,0,(struct sockaddr *)&from, &length);
// if (n < 0) error("recvfrom");
// write(1,"Got an ack: ",12);
// write(1,buffer,n);
close(sock);
return 0;
}
int bindIPCserver()
{
nHostPort=13132;
L("Starting IPC connection...");
/* make a socket */
hServerSocket=socket(AF_INET,SOCK_DGRAM,0);
if(hServerSocket == SOCKET_ERROR)
{
L("\nCould not make a socket\n");
return 0;
}
/* fill address struct */
Address.sin_addr.s_addr=INADDR_ANY;
Address.sin_port=htons(nHostPort);
Address.sin_family=AF_INET;
/* bind to a port */
if(bind(hServerSocket,(struct sockaddr*)&Address,sizeof(Address)) == SOCKET_ERROR)
{
L("\nCould not connect to IPC gui, another daemon already running?\n");
sendMsgToGui("~SHOW|Could not connect to IPC gui, another daemon already running?\n");
exit(-1);
}
L("binded to port %d\n",nHostPort);
pthread_t thread;
pthread_create( &thread,NULL,handle_connections,NULL);
return 1;
}
void *handle_connections()
{
L("\nWaiting for a connection\n");
struct sockaddr_in from;
int fromlen = sizeof(struct sockaddr_in);
int n;
while (1) {
n = recvfrom(hServerSocket,pBuffer,BUFFER_SIZE,0,(struct sockaddr *)&from,&fromlen);
if (n < 0) perror("recvfrom");
L("Recebido: %s\n",pBuffer);
if (strstr(pBuffer,"~PING|")!=NULL)
{
char *resp="~PONG|";
n = sendto(hServerSocket,resp,strlen(resp),
0,(struct sockaddr *)&from,fromlen);
if (n < 0) perror("sendto");
}
else if (strstr(pBuffer,"~KILL|")!=NULL)
close_app();
}
}
void unbindIPCserver()
{
close(hServerSocket);
}

33
droidvncgrab/vnc/gui.h Executable file
View File

@ -0,0 +1,33 @@
/*
droid VNC server - a vnc server for android
Copyright (C) 2011 Jose Pereira <onaips@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef GUI_COMM_H
#define GUI_COMM_H
#include "common.h"
int sendMsgToGui(char *msg);
int bindIPCserver();
void unbindIPCserver();
void *handle_connections();
#endif

325
droidvncgrab/vnc/input.c Executable file
View File

@ -0,0 +1,325 @@
/*
droid VNC server - a vnc server for android
Copyright (C) 2011 Jose Pereira <onaips@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "input.h"
int inputfd = -1;
// keyboard code modified from remote input by http://www.math.bme.hu/~morap/RemoteInput/
// q,w,e,r,t,y,u,i,o,p,a,s,d,f,g,h,j,k,l,z,x,c,v,b,n,m
int qwerty[] = {30,48,46,32,18,33,34,35,23,36,37,38,50,49,24,25,16,19,31,20,22,47,17,45,21,44};
// ,!,",#,$,%,&,',(,),*,+,,,-,.,/
int spec1[] = {57,2,40,4,5,6,8,40,10,11,9,13,51,12,52,52};
int spec1sh[] = {0,1,1,1,1,1,1,0,1,1,1,1,0,0,0,1};
// :,;,<,=,>,?,@
int spec2[] = {39,39,227,13,228,53,215};
int spec2sh[] = {1,0,1,1,1,1,0};
// [,\,],^,_,`
int spec3[] = {26,43,27,7,12,399};
int spec3sh[] = {0,0,0,1,1,0};
// {,|,},~
int spec4[] = {26,43,27,215,14};
int spec4sh[] = {1,1,1,1,0};
void initInput()
{
L("---Initializing uinput...---\n");
struct input_id id = {
BUS_VIRTUAL, /* Bus type. */
1, /* Vendor id. */
1, /* Product id. */
1 /* Version id. */
};
if((inputfd = suinput_open("qwerty", &id)) == -1)
{
L("cannot create virtual kbd device.\n");
sendMsgToGui("~SHOW|Cannot create virtual input device!\n");
// exit(EXIT_FAILURE); do not exit, so we still can see the framebuffer
}
}
int keysym2scancode(rfbBool down, rfbKeySym c, rfbClientPtr cl, int *sh, int *alt)
{
int real=1;
if ('a' <= c && c <= 'z')
return qwerty[c-'a'];
if ('A' <= c && c <= 'Z')
{
(*sh)=1;
return qwerty[c-'A'];
}
if ('1' <= c && c <= '9')
return c-'1'+2;
if (c == '0')
return 11;
if (32 <= c && c <= 47)
{
(*sh) = spec1sh[c-32];
return spec1[c-32];
}
if (58 <= c && c <= 64)
{
(*sh) = spec2sh[c-58];
return spec2[c-58];
}
if (91 <= c && c <= 96)
{
(*sh) = spec3sh[c-91];
return spec3[c-91];
}
if (123 <= c && c <= 127)
{
(*sh) = spec4sh[c-123];
return spec4[c-123];
}
switch(c)
{
case 0xff08: return 14;// backspace
case 0xff09: return 15;// tab
case 1: (*alt)=1; return 34;// ctrl+a
case 3: (*alt)=1; return 46;// ctrl+c
case 4: (*alt)=1; return 32;// ctrl+d
case 18: (*alt)=1; return 31;// ctrl+r
case 0xff0D: return 28;// enter
case 0xff1B: return 158;// esc -> back
case 0xFF51: return 105;// left -> DPAD_LEFT
case 0xFF53: return 106;// right -> DPAD_RIGHT
case 0xFF54: return 108;// down -> DPAD_DOWN
case 0xFF52: return 103;// up -> DPAD_UP
// case 360: return 232;// end -> DPAD_CENTER (ball click)
case 0xff50: return KEY_HOME;// home
case 0xFFC8: rfbShutdownServer(cl->screen,TRUE); return 0; //F11 disconnect
case 0xFFC9:
L("F12 closing...");
exit(0); //F10 closes daemon
break;
case 0xffc1: down?rotate(-1):0; return 0; // F4 rotate
case 0xffff: return 158;// del -> back
case 0xff55: return 229;// PgUp -> menu
case 0xffcf: return 127;// F2 -> search
case 0xffe3: return 127;// left ctrl -> search
case 0xff56: return 61;// PgUp -> call
case 0xff57: return 107;// End -> endcall
case 0xffc2: return 211;// F5 -> focus
case 0xffc3: return 212;// F6 -> camera
case 0xffc4: return 150;// F7 -> explorer
case 0xffc5: return 155;// F8 -> envelope
case 50081:
case 225: (*alt)=1;
if (real) return 48; //a with acute
return 30; //a with acute -> a with ring above
case 50049:
case 193:(*sh)=1; (*alt)=1;
if (real) return 48; //A with acute
return 30; //A with acute -> a with ring above
case 50089:
case 233: (*alt)=1; return 18; //e with acute
case 50057:
case 201:(*sh)=1; (*alt)=1; return 18; //E with acute
case 50093:
case 0xffbf: (*alt)=1;
if (real) return 36; //i with acute
return 23; //i with acute -> i with grave
case 50061:
case 205: (*sh)=1; (*alt)=1;
if (real) return 36; //I with acute
return 23; //I with acute -> i with grave
case 50099:
case 243:(*alt)=1;
if (real) return 16; //o with acute
return 24; //o with acute -> o with grave
case 50067:
case 211:(*sh)=1; (*alt)=1;
if (real) return 16; //O with acute
return 24; //O with acute -> o with grave
case 50102:
case 246: (*alt)=1; return 25; //o with diaeresis
case 50070:
case 214: (*sh)=1; (*alt)=1; return 25; //O with diaeresis
case 50577:
case 245:(*alt)=1;
if (real) return 19; //Hungarian o
return 25; //Hungarian o -> o with diaeresis
case 50576:
case 213: (*sh)=1; (*alt)=1;
if (real) return 19; //Hungarian O
return 25; //Hungarian O -> O with diaeresis
case 50106:
// case 0xffbe: (*alt)=1;
// if (real) return 17; //u with acute
// return 22; //u with acute -> u with grave
case 50074:
case 218: (*sh)=1; (*alt)=1;
if (real) return 17; //U with acute
return 22; //U with acute -> u with grave
case 50108:
case 252: (*alt)=1; return 47; //u with diaeresis
case 50076:
case 220:(*sh)=1; (*alt)=1; return 47; //U with diaeresis
case 50609:
case 251: (*alt)=1;
if (real) return 45; //Hungarian u
return 47; //Hungarian u -> u with diaeresis
case 50608:
case 219: (*sh)=1; (*alt)=1;
if (real) return 45; //Hungarian U
return 47; //Hungarian U -> U with diaeresis
}
return 0;
}
void keyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl)
{
int code;
// L("Got keysym: %04x (down=%d)\n", (unsigned int)key, (int)down);
setIdle(0);
int sh = 0;
int alt = 0;
if ((code = keysym2scancode(down, key, cl,&sh,&alt)))
{
int ret=0;
if (key && down)
{
if (sh) suinput_press(inputfd, 42); //left shift
if (alt) suinput_press(inputfd, 56); //left alt
ret=suinput_press(inputfd,code);
ret=suinput_release(inputfd,code);
if (alt) suinput_release(inputfd, 56); //left alt
if (sh) suinput_release(inputfd, 42); //left shift
}
else
;//ret=suinput_release(inputfd,code);
// L("injectKey (%d, %d) ret=%d\n", code , down,ret);
}
}
void ptrEvent(int buttonMask, int x, int y, rfbClientPtr cl)
{
static int leftClicked=0,rightClicked=0,middleClicked=0;
setIdle(0);
transformTouchCoordinates(&x,&y,cl->screen->width,cl->screen->height);
if((buttonMask & 1)&& leftClicked) {//left btn clicked and moving
static int i=0;
i=i+1;
if (i%10==1)//some tweak to not report every move event
{
suinput_write(inputfd, EV_ABS, ABS_X, x);
suinput_write(inputfd, EV_ABS, ABS_Y, y);
suinput_write(inputfd, EV_SYN, SYN_REPORT, 0);
}
}
else if (buttonMask & 1)//left btn clicked
{
leftClicked=1;
suinput_write(inputfd, EV_ABS, ABS_X, x);
suinput_write(inputfd, EV_ABS, ABS_Y, y);
suinput_write(inputfd,EV_KEY,BTN_TOUCH,1);
suinput_write(inputfd, EV_SYN, SYN_REPORT, 0);
}
else if (leftClicked)//left btn released
{
leftClicked=0;
suinput_write(inputfd, EV_ABS, ABS_X, x);
suinput_write(inputfd, EV_ABS, ABS_Y, y);
suinput_write(inputfd,EV_KEY,BTN_TOUCH,0);
suinput_write(inputfd, EV_SYN, SYN_REPORT, 0);
}
if (buttonMask & 4)//right btn clicked
{
rightClicked=1;
suinput_press(inputfd,158); //back key
}
else if (rightClicked)//right button released
{
rightClicked=0;
suinput_release(inputfd,158);
}
if (buttonMask & 2)//mid btn clicked
{
middleClicked=1;
suinput_press( inputfd,KEY_END);
}
else if (middleClicked)// mid btn released
{
middleClicked=0;
suinput_release( inputfd,KEY_END);
}
}
inline void transformTouchCoordinates(int *x, int *y,int width,int height)
{
int scale=4096.0;
int old_x=*x,old_y=*y;
int rotation=getCurrentRotation();
if (rotation==0)
{
*x = old_x*scale/width-scale/2.0;
*y = old_y*scale/height-scale/2.0;
}
else if (rotation==90)
{
*x =old_y*scale/height-scale/2.0;
*y = (width - old_x)*scale/width-scale/2.0;
}
else if (rotation==180)
{
*x =(width - old_x)*scale/width-scale/2.0;
*y =(height - old_y)*scale/height-scale/2.0;
}
else if (rotation==270)
{
*y =old_x*scale/width-scale/2.0;
*x =(height - old_y)*scale/height-scale/2.0;
}
}
void cleanupInput()
{
if(inputfd != -1)
{
suinput_close(inputfd);
}
}

36
droidvncgrab/vnc/input.h Executable file
View File

@ -0,0 +1,36 @@
/*
droid VNC server - a vnc server for android
Copyright (C) 2011 Jose Pereira <onaips@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef KEYMANIP_H
#define KEYMANIP_H
#include "common.h"
#include "gui.h"
#define BUS_VIRTUAL 0x06
void initInput();
int keysym2scancode(rfbBool down, rfbKeySym c, rfbClientPtr cl, int *sh, int *alt);
void transformTouchCoordinates(int *x, int *y,int,int);
void ptrEvent(int buttonMask, int x, int y, rfbClientPtr cl);
void keyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl);
void cleanupInput();
#endif

View File

@ -0,0 +1,30 @@
Makefile
Makefile.in
compile
configure
configure.lineno
config.status
config.log
LibVNCServer.spec.in
LibVNCServer.spec
x11vnc.spec.in
.deps
aclocal.m4
autom4te.cache
libvncserver-config
_configs.sed
config.h
LibVNCServer*.tar.gz
upload_beta.sh
stamp-*
x11vnc*.tar.gz
config.h.in
rfbconfig.h
rfbconfig.h.in
install-sh
missing
mkinstalldirs
depcomp
description-pak
libvncserver*.deb

View File

@ -0,0 +1,73 @@
*.swp
*~
Makefile
Makefile.in
compile
configure
configure.lineno
config.status
config.log
LibVNCServer.spec.in
LibVNCServer.spec
x11vnc.spec.in
.deps
.libs
aclocal.m4
autom4te.cache
libvncserver-config
_configs.sed
config.h
LibVNCServer*.tar.gz
upload_beta.sh
stamp-*
x11vnc*.tar.gz
config.h.in
rfbconfig.h
rfbconfig.h.in
install-sh
missing
mkinstalldirs
depcomp
description-pak
libvncserver*.deb
*.o
*.lo
CVS
client_examples/SDLvncviewer
client_examples/backchannel
client_examples/ppmtest
config.guess
config.sub
contrib/zippy
examples/backchannel
examples/blooptest
examples/camera
examples/colourmaptest
examples/example
examples/filetransfer
examples/fontsel
examples/pnmshow
examples/pnmshow24
examples/regiontest
examples/rotate
examples/simple
examples/simple15
examples/storepasswd
examples/vncev
libtool
libvncclient/libvncclient.la
libvncserver/libvncserver.la
rfb/rfbint.h
test/blooptest
test/cargstest
test/copyrecttest
test/cursortest
test/encodingstest
vncterm/LinuxVNC
vncterm/VNCommand
vncterm/example
x11vnc.spec
x11vnc/x11vnc
CMakeCache.txt
cmake_install.cmake
/CMakeFiles

View File

@ -0,0 +1,50 @@
* LibVNCServer (C) 2001 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
is based on
* Original OSXvnc (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>,
which in turn is based on
* Original Xvnc (C) 1999 AT&T Laboratories Cambridge.
Lots of improvements of this library are thanks to
* TightVNC (C) 2000-2003 Const Kaplinsky
The ZRLE compression scheme is from
* RealVNC (James "Wez" Weatherall, who helped also with regions)
The good folks from
* KRFB (I think it was Tim Jansen)
helped also a lot (some *big* bugs!).
Karl Runge provides an x11vnc, which is a much, much improved version of my
original proof-of-concept. It really deserves to replace the old version,
as it is a state-of-the-art, fast and usable program by now! However, he
maintains it and improves it still in amazing ways!
The file transfer protocol from TightVNC was implemented by Rohit Kumar.
This includes an implementation of RFB protocol version 3.7t.
Occasional important patches were sent by (in order I found the names in my
archives and please don't beat me, if I forgot you, but just send me an
email!): Akira Hatakeyama, Karl J. Runge, Justin "Zippy" Dearing,
Oliver Mihatsch, Greg Sternberg, Werner Hofer, Giampiero Giancipoli,
Glenn Mabutt, Paul Kreiner, Erik Kunze, Mike Frysinger, Martin Waitz,
Mark McLoughlin, Paul Fox, Juan Jose Costello, Andre Leiadella,
Alberto Lusiani, Malvina Mazin, Dave Stuart, Rohit Kumar, Donald Dugger,
Steven Carr, Uwe Völker, Charles Coffing, Guillaume Rousse,
Alessandro Praduroux, Brad Hards, Timo Ketola, Christian Ehrlicher,
Noriaki Yamazaki, Ben Klopfenstein, Vic Lee, Christian Beier,
Alexander Dorokhine, Corentin Chary and Wouter Van Meir.
Probably I forgot quite a few people sending a patch here and there, which
really made a difference. Without those, some obscure bugs still would
be unfound.
A hearty unthanks goes to Michael and Erick, who provided me with nothing
but hollow words. Finally I got that configure and install working, but
it would have been so much better for them not just to complain, but also
help. As you showed me real egoism, you are the main reasons I am not
working one dot to make this library less than GPL, so that nobody ever
can make profit of my and others work without giving something back to me
and others.
Speaking of hollow words, another hearty unthanks goes to Sam, who thought
he could let me work for him, not paying me in any way.

View File

@ -0,0 +1,253 @@
cmake_minimum_required(VERSION 2.6)
project(LibVNCServer)
include(CheckFunctionExists)
include(CheckIncludeFile)
include(CheckTypeSize)
include(TestBigEndian)
set(PACKAGE_NAME "LibVNCServer")
set(FULL_PACKAGE_NAME "LibVNCServer")
set(PACKAGE_VERSION "0.9.7")
set(PROJECT_BUGREPORT_PATH "http://sourceforge.net/projects/libvncserver")
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/libvncserver)
find_package(ZLIB)
find_package(JPEG)
find_package(SDL)
find_package(GnuTLS)
find_package(Threads)
if(SDL_FOUND) # == pthread.h available
option(TIGHTVNC_FILETRANSFER "Enable filetransfer" ON)
endif(SDL_FOUND)
if(ZLIB_FOUND)
set(LIBVNCSERVER_HAVE_LIBZ 1)
endif(ZLIB_FOUND)
if(JPEG_FOUND)
set(LIBVNCSERVER_HAVE_LIBJPEG 1)
endif(JPEG_FOUND)
option(LIBVNCSERVER_ALLOW24BPP "Allow 24 bpp" ON)
if(GNUTLS_FOUND)
set(LIBVNCSERVER_WITH_CLIENT_TLS 1)
endif(GNUTLS_FOUND)
check_include_file("fcntl.h" LIBVNCSERVER_HAVE_FCNTL_H)
check_include_file("netinet/in.h" LIBVNCSERVER_HAVE_NETINET_IN_H)
check_include_file("sys/socket.h" LIBVNCSERVER_HAVE_SYS_SOCKET_H)
check_include_file("sys/stat.h" LIBVNCSERVER_HAVE_SYS_STAT_H)
check_include_file("sys/time.h" LIBVNCSERVER_HAVE_SYS_TIME_H)
check_include_file("sys/types.h" LIBVNCSERVER_HAVE_SYS_TYPES_H)
check_include_file("sys/wait.h" LIBVNCSERVER_HAVE_SYS_WAIT_H)
check_include_file("unistd.h" LIBVNCSERVER_HAVE_UNISTD_H)
# headers needed for check_type_size()
check_include_file("arpa/inet.h" HAVE_ARPA_INET_H)
check_include_file("stdint.h" HAVE_STDINT_H)
check_include_file("stddef.h" HAVE_STDDEF_H)
check_include_file("sys/types.h" HAVE_SYS_TYPES_H)
check_function_exists(gettimeofday LIBVNCSERVER_HAVE_GETTIMEOFDAY)
if(CMAKE_USE_PTHREADS_INIT)
set(LIBVNCSERVER_HAVE_LIBPTHREAD 1)
endif(CMAKE_USE_PTHREADS_INIT)
if(LIBVNCSERVER_HAVE_SYS_SOCKET_H)
# socklen_t
list(APPEND CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h")
endif(LIBVNCSERVER_HAVE_SYS_SOCKET_H)
if(HAVE_ARPA_INET_H)
# in_addr_t
list(APPEND CMAKE_EXTRA_INCLUDE_FILES "arpa/inet.h")
endif(HAVE_ARPA_INET_H)
check_type_size(pid_t LIBVNCSERVER_PID_T)
check_type_size(size_t LIBVNCSERVER_SIZE_T)
check_type_size(socklen_t LIBVNCSERVER_SOCKLEN_T)
check_type_size(in_addr_t LIBVNCSERVER_IN_ADDR_T)
if(NOT HAVE_LIBVNCSERVER_IN_ADDR_T)
set(LIBVNCSERVER_NEED_INADDR_T 1)
endif(NOT HAVE_LIBVNCSERVER_IN_ADDR_T)
TEST_BIG_ENDIAN(LIBVNCSERVER_WORDS_BIGENDIAN)
# TODO:
# LIBVNCSERVER_ENOENT_WORKAROUND
# inline
configure_file(${CMAKE_SOURCE_DIR}/rfb/rfbconfig.h.cmake ${CMAKE_BINARY_DIR}/rfb/rfbconfig.h)
configure_file(${CMAKE_SOURCE_DIR}/rfb/rfbint.h.cmake ${CMAKE_BINARY_DIR}/rfb/rfbint.h)
set(LIBVNCSERVER_DIR ${CMAKE_SOURCE_DIR}/libvncserver)
set(LIBVNCCLIENT_DIR ${CMAKE_SOURCE_DIR}/libvncclient)
set(LIBVNCSRVTEST_DIR ${CMAKE_SOURCE_DIR}/examples)
set(LIBVNCCLITEST_DIR ${CMAKE_SOURCE_DIR}/client_examples)
set(LIBVNCSERVER_SOURCES
${LIBVNCSERVER_DIR}/main.c
${LIBVNCSERVER_DIR}/rfbserver.c
${LIBVNCSERVER_DIR}/rfbregion.c
${LIBVNCSERVER_DIR}/auth.c
${LIBVNCSERVER_DIR}/sockets.c
${LIBVNCSERVER_DIR}/stats.c
${LIBVNCSERVER_DIR}/corre.c
${LIBVNCSERVER_DIR}/hextile.c
${LIBVNCSERVER_DIR}/rre.c
${LIBVNCSERVER_DIR}/translate.c
${LIBVNCSERVER_DIR}/cutpaste.c
${LIBVNCSERVER_DIR}/httpd.c
${LIBVNCSERVER_DIR}/cursor.c
${LIBVNCSERVER_DIR}/font.c
${LIBVNCSERVER_DIR}/draw.c
${LIBVNCSERVER_DIR}/selbox.c
${LIBVNCSERVER_DIR}/d3des.c
${LIBVNCSERVER_DIR}/vncauth.c
${LIBVNCSERVER_DIR}/cargs.c
${LIBVNCSERVER_DIR}/minilzo.c
${LIBVNCSERVER_DIR}/ultra.c
${LIBVNCSERVER_DIR}/scale.c
)
set(LIBVNCCLIENT_SOURCES
${LIBVNCCLIENT_DIR}/cursor.c
${LIBVNCCLIENT_DIR}/listen.c
${LIBVNCCLIENT_DIR}/rfbproto.c
${LIBVNCCLIENT_DIR}/sockets.c
${LIBVNCCLIENT_DIR}/vncviewer.c
${LIBVNCCLIENT_DIR}/minilzo.c
${LIBVNCCLIENT_DIR}/tls.c
)
if(ZLIB_FOUND)
add_definitions(-DLIBVNCSERVER_HAVE_LIBZ)
include_directories(${ZLIB_INCLUDE_DIR})
set(LIBVNCSERVER_SOURCES
${LIBVNCSERVER_SOURCES}
${LIBVNCSERVER_DIR}/zlib.c
${LIBVNCSERVER_DIR}/zrle.c
${LIBVNCSERVER_DIR}/zrleoutstream.c
${LIBVNCSERVER_DIR}/zrlepalettehelper.c
)
endif(ZLIB_FOUND)
if(JPEG_FOUND)
add_definitions(-DLIBVNCSERVER_HAVE_LIBJPEG)
include_directories(${JPEG_INCLUDE_DIR})
set(LIBVNCSERVER_SOURCES
${LIBVNCSERVER_SOURCES}
${LIBVNCSERVER_DIR}/tight.c
)
endif(JPEG_FOUND)
if(TIGHTVNC_FILETRANSFER)
set(LIBVNCSERVER_SOURCES
${LIBVNCSERVER_SOURCES}
${LIBVNCSERVER_DIR}/tightvnc-filetransfer/rfbtightserver.c
${LIBVNCSERVER_DIR}/tightvnc-filetransfer/handlefiletransferrequest.c
${LIBVNCSERVER_DIR}/tightvnc-filetransfer/filetransfermsg.c
${LIBVNCSERVER_DIR}/tightvnc-filetransfer/filelistinfo.c
)
endif(TIGHTVNC_FILETRANSFER)
add_library(vncclient SHARED ${LIBVNCCLIENT_SOURCES})
add_library(vncserver SHARED ${LIBVNCSERVER_SOURCES})
if(WIN32)
set(ADDITIONAL_LIBS ws2_32)
endif(WIN32)
target_link_libraries(vncclient
${ADDITIONAL_LIBS}
${ZLIB_LIBRARIES}
${JPEG_LIBRARIES}
${SDL_LIBRARY}
)
target_link_libraries(vncserver
${ADDITIONAL_LIBS}
${ZLIB_LIBRARIES}
${JPEG_LIBRARIES}
${SDL_LIBRARY}
)
# tests
set(LIBVNCSERVER_TESTS
backchannel
camera
colourmaptest
example
fontsel
pnmshow
pnmshow24
regiontest
rotate
simple
simple15
storepasswd
vncev
)
if(SDL_FOUND)
set(LIBVNCSERVER_TESTS
${LIBVNCSERVER_TESTS}
blooptest
)
endif(SDL_FOUND)
if(TIGHTVNC_FILETRANSFER)
set(LIBVNCSERVER_TESTS
${LIBVNCSERVER_TESTS}
filetransfer
)
endif(TIGHTVNC_FILETRANSFER)
if(MACOS)
set(LIBVNCSERVER_TESTS
${LIBVNCSERVER_TESTS}
mac
)
endif(MACOS)
set(LIBVNCCLIENT_TESTS
backchannel
ppmtest
)
if(SDL_FOUND)
include_directories(${SDL_INCLUDE_DIR})
set(LIBVNCCLIENT_TESTS
${LIBVNCCLIENT_TESTS}
SDLvncviewer
)
endif(SDL_FOUND)
if(HAVE_FFMPEG)
set(LIBVNCCLIENT_TESTS
${LIBVNCCLIENT_TESTS}
vnc2mpg
)
endif(HAVE_FFMPEG)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/examples)
foreach(test ${LIBVNCSERVER_TESTS})
add_executable(examples/${test} ${LIBVNCSRVTEST_DIR}/${test}.c)
target_link_libraries(examples/${test} vncserver ${CMAKE_THREAD_LIBS_INIT})
endforeach(test ${LIBVNCSERVER_TESTS})
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/client_examples)
foreach(test ${LIBVNCCLIENT_TESTS})
add_executable(client_examples/${test} ${LIBVNCCLITEST_DIR}/${test}.c)
target_link_libraries(client_examples/${test} vncclient ${CMAKE_THREAD_LIBS_INIT} ${GNUTLS_LIBRARIES} ${SDL_LIBRARY} ${FFMPEG_LIBRARIES})
endforeach(test ${LIBVNCCLIENT_TESTS})
install_targets(/lib vncserver)
install_targets(/lib vncclient)
install_files(/include/rfb FILES
rfb/keysym.h
rfb/rfb.h
rfb/rfbclient.h
rfb/rfbconfig.h
rfb/rfbint.h
rfb/rfbproto.h
rfb/rfbregion.h
)

View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@ -0,0 +1,767 @@
2010-05-08 Karl Runge <runge@karlrunge.com>
* libvncclient/rfbproto.c: rfbResizeFrameBuffer should also set
updateRect.
2010-01-02 Karl Runge <runge@karlrunge.com>
* tightvnc-filetransfer/rfbtightserver.c: enabled fix
for tight security type for RFB 3.8 (debian bug 517422.)
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=517422
http://sourceforge.net/tracker/?func=detail&aid=2647349&group_id=32584&atid=405858
2009-05-21 Karl Runge <runge@karlrunge.com>
* configure.ac: check for __thread.
* libvncserver/main.c, libvncserver/rfbserver.c: various
thread safe corrections including sendMutex guard.
* libvncserver/zrle.c, libvncserver/zrleencodetemplate.c:
thread safety via per-client buffers.
* libvncserver/tight.c, libvncserver/zlib.c: thread safety
corrections via thread local storage using __thread.
* rfb/rfb.h: new members for threaded usage.
* tightvnc-filetransfer/rfbtightserver.c: fix (currently disabled)
for tight security type for RFB 3.8 (debian bug 517422.)
NEEDS AUDIT.
2009-03-12 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* client_examples/SDLvncviewer.c: support mouse wheel operations
2009-03-08 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* client_examples/SDLvncviewer.c: support clipboard operations
2009-03-07 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* client_examples/SDLvncviewer.c: force releasing Alt keys whenr
losing focus. This helps when you switch windows by pressing
Alt+Tab (SDLvncviewer would get the "Alt down" event, but not
the "Alt up" one).
2009-03-07 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* client_examples/SDLvncviewer.c: make the viewer resizable
2009-03-06 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* client_examples/SDLvncviewer.c: enable key repeat
2009-02-03 Mike Frysinger <vapier@gentoo.org>
* autogen.sh, configure.ac, **/Makefile.am: major automake cleanups
2009-01-04 Karl Runge <runge@karlrunge.com>
* configure.ac, CMakeLists.txt: set LibVNCServer version to 0.9.7
2009-01-04 Karl Runge <runge@karlrunge.com>
* prepare_x11vnc_dist.sh: fix SUBDIRS and DIST_SUBDIRS when using
--with-system-libvncserver
2008-06-03 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* client_examples/SDLvncviewer.c: fix update after resize
2008-02-18 Christian Ehrlicher <Ch.Ehrlicher@gmx.de>
* libvncserver/rfbregion.c: please MS Visual C++
2008-02-04 Noriaki Yamazaki <micro-vnc@ias.hitachi-system.co.jp>
* libvncclient/rfbproto.c, libvncclient/zrle.c: Add ZYWRLE
support to LibVNCClient
2008-02-04 Noriaki Yamazaki <micro-vnc@ias.hitachi-system.co.jp>
* libvncserver/zywrletemplate.c: Fix mis encode/decode when
width != scanline
2008-02-02 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* client_examples/SDLvncviewer.c: fix buttons (2 & 3 were switched),
fix Tab key, and fix Ctrl+<letter>
2008-01-29 Christian Ehrlicher <Ch.Ehrlicher@gmx.de>
* libvncserver/rfbserver.c: add missing #include <time.h>
2008-01-28 Noriaki Yamazaki <micro-vnc@ias.hitachi-system.co.jp>
* rfb/rfbproto.h, libvncserver/rfbserver.c, libvncserver/scale.c,
libvncserver/zrle.c, libvncserver/zrleencodetemplate.c,
libvncserver/zywrletemplate.c: add (server-side) ZYWRLE support,
and fix a few endian/scale errors
2008-01-27 Christian Ehrlicher <Ch.Ehrlicher@gmx.de>
* CMakeLists, rfb/rfbconfig.h.cmake, rfb/rfbint.h.cmake:
support CMake
2007-09-04 Karl Runge <runge@karlrunge.com>
* classes/ssl: improve timeouts, port fallback, and connection
time of the SSL Java viewers.
2007-08-10 Timo Ketola <timo@riihineva.no-ip.org>
* libvncclient/rfbproto.c: add missing else (so that GotRect
handling overrides the default operation).
2007-06-14 Karl Runge <runge@karlrunge.com>
* configure.ac: add a note on what you must do if you want to
re-run autoconf from the LibVNCServer-X.Y.Z.tar.gz tarball.
2007-05-26 Karl Runge <runge@karlrunge.com>
* configure.ac, Makefile.am, x11vnc/Makefile.am: change
configure to make more of a split between libvncserver and
x11vnc packages. LibVNCServer pkg does not include x11vnc.
2007-04-06 Brad Hards <bradh@users.sourceforge.net>
* rfb/rfbclient.h: use 'extern "C"' to make it convenient to
include from C++.
2007-04-05 Alessandro Praduroux <pradu@pradu.it>
* rfb/rfb.h: do not misplace guards, which makes it possible to
double include rfb.h from C++.
2007-03-31 Guillaume Rousse <Guillaume.Rousse@inria.fr>
* configure.ac, **/Makefile.am: build shared libraries
2007-03-20 Karl Runge <runge@karlrunge.com>
* libvncserver/httpd.c: Add "Connection: close" to HTTP replies.
2007-03-17 Charles Coffing <cconffing@novell.com>
* libvncserver: fix a locking issue
2007-02-01 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* libvncclient: add updateRect member to rfbClient, to allow
requesting smaller updates than whole-screen.
2007-01-31 Karl Runge <runge@karlrunge.com>
* libvncclient: add GotCursorShape() and GotCopyRect() hooks.
fix copyrect code in rfbproto.c, add copyrect to default list.
* Makefile.am and prepare_x11vnc_dist.sh: add x11vnc dependence
on libvncclient.
2006-12-13 Karl Runge <runge@karlrunge.com>
* remove stray "-permitfiletransfer permit file transfer support"
print out.
2006-11-21 Karl Runge <runge@karlrunge.com>
* configure.ac: add DPMS detection.
2006-11-13 Karl Runge <runge@karlrunge.com>
* configure.ac: x11vnc warnings for no XTEST or SSL.
* prepare_x11vnc_dist.sh: to 0.8.4
2006-11-07 Karl Runge <runge@karlrunge.com>
* configure.ac: clean up -R linker case, add --without-macosx-native
* prepare_x11vnc_dist.sh: have "make rpm" work properly for
x11vnc package.
2006-07-17 Karl Runge <runge@karlrunge.com>
* configure.ac: move non-X11 tests out of HAVE_X: set
SSL_LIBS and CRYPT_LIBS and some header checks.
2006-07-12 Karl Runge <runge@karlrunge.com>
* libvncserver: release for CVE-2006-2450 fix.
2006-07-08 Karl Runge <runge@karlrunge.com>
* configure.ac: add <linux/uinput.h> for linux console.
2006-07-04 Karl Runge <runge@karlrunge.com>
* configure.ac: add getspnam.
2006-06-08 Karl Runge <runge@karlrunge.com>
* prepare_x11vnc_dist.sh: to 0.8.2
2006-05-29 Steven Carr <scarr@jsa-usa.com>
* Identified and removed some memory leaks associated
with the Encodings RRE, CoRRE, ZLIB, and Ultra.
* KeyboardLedState now has portable masks defined.
* rfb >= 3.7 Security Type Handler list would grow 1
entry for each new client connection.
2006-05-16 Steven Carr <scarr@jsa-usa.com>
* Statistics output now fits in 80-column output
* Corrected Cursor Statistics reporting as messages
2006-05-15 Steven Carr <scarr@jsa-usa.com>
* Default to RFB 3.8
* Add command line options:
-rfbversion X.Y Sets the version thatthe server reports
-permitfiletransfer Permits File Transfer (Default is Deny)
2006-05-15 Steven Carr <scarr@jsa-usa.com>
* The great UltraVNC Compatibility Commit!
libvncserver now supports the following messages:
SetSingleWindow - Select a single window to be the source of the
framebuffer.
ServerInput - Disable and blank the servers display
TextChat - TextChat between the remote/local user
(Bandwidth friendly VS the Notepad approach)
FileTransfer - Emulates a Windows Filesystem to the viewer
(Currently does not support Delta Transfers)
(Currently does not support Sending Directories)
UltraZip - Improved UltraZip support
* Improved Statistics SubSystem, now supports all encodings
* RFB 3.8 support! Error Messages are a 'Good Thing' (tm)
* Default to identify as RFB 3.6 to emulate UltraVNC server
(Server now has the ability to set the RFB version reported)
(permits the viewer to identify the server has FileTransfer ability)
* Client Encoding AutoSelection Supported (UltraViewer is speed aware)
* libvncclient has improved server detection/capabilities logic!
2006-05-13 Karl Runge <runge@karlrunge.com>
* minilzo.c,minilzo.h,lzoconf.h: switch to non-CRLF versions.
* libvncclient/Makefile.am: add minilzo.c, minilzo.h, lzoconf.h
and ultra.c to materials lists.
* libvncserver/scale.c: remove libm dependency with CEIL and
FLOOR macros.
* libvncserver/rfbserver.c: remove C99 declarations.
* vncterm/Makefile.am: fix VPATH build.
2006-05-06 Karl Runge <runge@karlrunge.com>
* configure.ac: add linux/videodev.h and linux/fb.h detection.
2006-05-04 Steven Carr <scarr@jsa-usa.com>
* rfbEncodingSupportedEncodings - What encodings are supported?
* rfbEncodingSupportedMessages - What message types are supported?
This way a client can identify if a particular server supports a
specific message types.
* rfbEncodingServerIdentity - What is the servers version string?
ie: "x11vnc: 0.8.1 lastmod: 2006-04-25 (LibVNCServer 0.9pre)"
2006-05-03 Steven Carr <scarr@jsa-usa.com>
* Server Side Scaling is now supported in libvncserver
Both PalmVNC and UltraVNC SetScale messages are supported
2006-05-02 Steven Carr <scarr@jsa-usa.com>
* Ultra Encoding added. Tested against UltraVNC V1.01
* libvncclient/rfbproto.c CopyRectangle() BPP!=8 bug fixed.
* Incompatible pointer usage warnings eliminated (gcc 4.0.1)
2006-04-27 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* examples/{rotate.c, rotatetemplate.c}: add modified pnmshow
which demonstrates fast rotating and flipping.
2006-04-26 Karl Runge <runge@karlrunge.com>
* all Makefile.am: use -I $(top_srcdir) instead of -I .. so VPATH
builds will work.
* configure.ac: create rfb subdir for rfbint.h under VPATH.
2006-04-17 Steven Carr <scarr@jsa-usa.com>
* Added an example camera application to demonstrate another
way to write a server application.
2006-04-05 Karl Runge <runge@karlrunge.com>
* classes/ssl: SSL Java viewer workarounds for firewall
proxies (signed applet as last resort, proxy.vnc).
include ssl_vncviewer stunnel wrapper script.
2006-03-28 Steven Carr <scarr@jsa-usa.com>
* SDLvncviewer.c, rfbproto.c, vncviewer.c, main.c, rfbserver.c,
rfb.h, rfbclient.h, rfbproto.h: add new encoding: KeyboardLedState
2006-03-28 Karl Runge <runge@karlrunge.com>
* classes/ssl: patch to tightvnc Java viewer for SSL support
plus other fixes (richcursor colors, Tab keysym, etc).
* libvncserver/httpd.c: add missing \r in 200 OK.
2006-03-27 Steven Carr <scarr@jsa-usa.com>
* rfbserver.c: Zlib encoding cannot have a limit via
maxRectsPerUpdate
2006-02-28 Donald Dugger <donald.d.dugger@intel.com>
* rfb.h, sockets.c, main.c: add a flag to handle all pending
input events instead of one at a time.
2006-02-24 Karl Runge <runge@karlrunge.com>
* x11vnc: -unixpw and -stunnel options. Add clipboard input
to per-client input controls.
2006-02-24 Rohit Kumar <rokumar@novell.com>
* main.c, rfbtightserver.c, rfb.h: added method to get
extension specific client data.
2006-02-22 Rohit Kumar <rokumar@novell.com>
* auth.c, main.c, rfbtightserver.c, rfb.h: add methods to
unregister extensions and security types.
2006-02-20 Karl Runge <runge@karlrunge.com>
* main.c, cursor.c, tightvnc-filetransfer: fix some non-gcc
compiler warnings.
2006-01-14 Karl Runge <runge@karlrunge.com>
* x11vnc: add -8to24 option for some multi-depth displays.
2006-01-12 Karl Runge <runge@karlrunge.com>
* configure.ac: add switches for most X extensions.
2006-01-10 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* libvncserver/{main.c,rfbserver.c}: fix timely closing of clients;
the client iterator in rfbProcessEvents() has to iterate also
over clients whose sock < 0. Noticed by Karl.
2006-01-08 Karl Runge <runge@karlrunge.com>
* x11vnc: the big split. (and -afteraccept and -passwdfile read:..)
* examples/pnmshow24.c: fix typo.
2006-01-08 Karl Runge <runge@karlrunge.com>
* libvncclient/vncviewer.c: fix non-jpeg/libz builds.
* examples/pnmshow24.c: fix non-ALLOW24BPP builds.
* libvncserver/main.c: fix 'static int' defn.
2006-01-05 Karl Runge <runge@karlrunge.com>
* libvncserver/main.c: rfbRegisterProtocolExtension extMutex was
never initialized.
2005-12-24 Karl Runge <runge@karlrunge.com>
* x11vnc: enhance -passwdfile features, filetransfer on by default.
2005-12-19 Dave Stuart <dave@justdave.us>
* libvncserver/{main.c,rfbserver.c,cargs.c}, rfb/rfb.h: introduce
deferPtrUpdateTime, which defers the handling of pointer events
for a couple of milliseconds.
2005-12-19 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* client_examples/SDLvncviewer.c, libvncclient/{sockets.c,vncviewer.c},
libvncserver/{main.c,rfbserver.c,sockets.c}: fix MinGW32 compilation
2005-12-08 "Mazin, Malvina" <Malvina.Mazin@kla-tencor.com>
* configure.ac, libvncserver/sockets.c: on Solaris 2.7, write may
return ENOENT when it really means EAGAIN.
2005-12-07 Giampiero Giancipoli <giampiero.giancipoli@fredreggiane.com>
* libvncclient/vncviewer.c: plug memory leaks
2005-12-07 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* client_examples/SDLvncviewer.c: use unicode to determine the keysym
(much more reliable than the old method)
2005-11-25 Karl Runge <runge@karlrunge.com>
* configure.ac: disable tightvnc-filetransfer if no libpthread.
add --without-pthread option.
* libvncserver/Makefile.am: enable WITH_TIGHTVNC_FILETRANSFER
conditional.
* libvncserver/rfbserver.c: fix deadlock from
rfbReleaseExtensionIterator(), fix no libz/libjpeg builds.
* libvncserver/{main.c,private.h}, rfb/rfbclient.h, libvncclient/{rfbproto.c,
tight.c,vncviewer.c}: fix no libz/libjpeg builds.
* libvncserver/tightvnc-filetransfer/rfbtightserver.c: fix no
libz/libjpeg builds. rm // comments.
* libvncserver/tightvnc-filetransfer/filetransfermsg{.c,.h},
libvncserver/auth.c: rm // comments.
* libvncserver/tightvnc-filetransfer/filelistinfo.h: set NAME_MAX if not
defined.
* x11vnc: throttle load if fb update requests not taking place.
2005-10-22 Karl Runge <runge@karlrunge.com>
* x11vnc: -filexfer file transfer, -slow_fb, -blackout noptr...
2005-10-06 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* many a files: kill BackChannel and CustomClientMessage
support. The new extension mechanism is much more versatile.
To prove this, a new example shows how to implement the back
channel as an extension. Of course, this had to be tested, so
LibVNCClient now has beginnings of an extension mechanism, too.
And an example implementing the client side of the back channel.
2005-10-03 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* libvncserver/rfbserver.c, rfb/rfb.h: add a method to the
extension struct which is called to enable pseudo encodings.
This is a versatile mechanism to enable/disable custom
extensions with custom clients and servers.
2005-09-28 Rohit Kumar <rokumar@novell.com>
* examples/filetransfer.c, rfb/rfb.h, configure.ac,
libvncserver/{auth,cargs,main,rfbserver,sockets}.c,
libvncserver/tightvnc-extension/*:
Implement TightVNC's file transfer protocol.
2005-09-27 Rohit Kumar <rokumar@novell.com>
* libvncserver/{cargs,sockets,main,rfbserver}.c,
rfb/rfb.h: Provide a generic means to extend the RFB
protocol: rfbRegisterProtocolExtension(extension). This
deprecates the current (very limited) option to override
rfbScreenInfoPtr->processCustomClientMessage(client).
2005-09-26 Rohit Kumar <rokumar@novell.com>
* libvncserver/{auth,main,rfbserver}.c, rfb/{rfb,rfbproto}.h:
support VNC protocol version 3.7. This allows to add security
types.
2005-08-21 Alberto Lusiani <alusiani@gmail.com>
* libvncserver.spec.in: split rpm into libvncserver, -devel and x11vnc
2005-07-12 Karl Runge <runge@karlrunge.com>
* x11vnc: tweaks for release, fix queue buildup under -viewonly
2005-07-10 Karl Runge <runge@karlrunge.com>
* x11vnc: -grab_buster for breaking XGrabServer deadlock, fix
scrolls and copyrect for -clip and -id cases.
2005-07-06 Karl Runge <runge@karlrunge.com>
* x11vnc: -gui tray now embeds in systray; more improvements to gui.
2005-07-01 Karl Runge <runge@karlrunge.com>
* libvncserver/httpd.c: make sure httpListenSock >=0 in rfbHttpCheckFds
* x11vnc: add simple "-gui tray" mode for small icon like x0rfbserver
had (someday/somehow to auto embed in a tray/dock)
2005-06-28 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* libvncclient/zrle.c: fix handling of raw and fill subtypes
(off-by-one and off-by-many bug)
2005-06-27 Karl Runge <runge@karlrunge.com>
* libvncserver/main.c: move deferUpdateTime and maxRectsPerUpdate
defaults to before rfbProcessArguments().
2005-06-18 Karl Runge <runge@karlrunge.com>
* configure.ac: don't use -R on HP-UX and OSF1.
* x11vnc: don't free the current cursor, close stderr
for -inetd -q and no -o logfile, set DISPLAY for -solid
external calls.
2005-06-14 Karl Runge <runge@karlrunge.com>
* configure.ac: XReadScreen and XReadDisplay checks.
* libvncserver/cursor.c: fix unsigned long crash for 64bits.
* x11vnc: first round of beta-testing fixes, RFE's.
2005-06-10 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* configure.ac: fix that annoying SUN /usr/ccs location of "ar"
2005-06-03 Karl Runge <runge@karlrunge.com>
* libvncserver/main.c: remove sraRgnSubtract from copyRegion
* x11vnc: scrollcopyrect under -scale, add -fixscreen.
2005-05-30 Karl Runge <runge@karlrunge.com>
* libvncserver/main.c: fix copyRect for non-cursor-shape-aware clients.
2005-05-24 Karl Runge <runge@karlrunge.com>
* x11vnc: scrollcopyrect: GrabServer detection, autorepeat throttling..
* prepare_x11vnc_dist.sh: grep out new libvncserver-config line.
2005-05-23 Karl Runge <runge@karlrunge.com>
* configure.ac: malloc(0) is never used, so we don't need the check
2005-05-15 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* acinclude.m4: fix compilation for systems without socklen_t
2005-05-17 Karl Runge <runge@karlrunge.com>
* x11vnc: more scrolling, -scr_term, -wait_ui, -nowait_bog
2005-05-15 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* almost every file: ANSIfy, fix warnings from Linus' sparse
2005-05-14 Karl Runge <runge@karlrunge.com>
* x11vnc: more work on -scrollcopyrect and -xkb modes.
2005-05-13 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* libvncserver/{main,rfbserver,sockets}.c: fix memory leaks (valgrind)
2005-05-07 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* libvncserver/rfbserver.c: fix memory leak pointed out by Tim Jansen
* libvncserver/{httpd,main,rfbserver,sockets}.c, rfb/rfb.h:
replace "rfbBool socketInitDone" by "enum rfbSocketState
socketState"
2005-05-03 Karl Runge <runge@karlrunge.com>
* libvncserver/main.c: fix leak in rfbDoCopyRect/rfbScheduleCopyRect
* configure.ac: guard against empty HAVE_X
2005-05-02 Karl Runge <runge@karlrunge.com>
* configure.ac: fatal error for x11vnc package if no X present
* configure.ac: give warnings and info about missing libjpeg/libz
* x11vnc: X RECORD heuristics to detect scrolls: -scrollcopyrect,
build customizations, bandwidth/latency estimates.
2005-04-27 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* clear requested region (long standing TODO, pointed out by Karl)
2005-04-19 Karl Runge <runge@karlrunge.com>
* x11vnc: -wireframe, -wirecopyrect. Back to the 90's with
wireframes to avoid window move/resize lurching.
* safer remote control defaults. -privremote, -safer, -nocmds.
* debug_xevents, debug_xdamage. -noviewonly for rawfb mode.
2005-04-10 Karl Runge <runge@karlrunge.com>
* configure.ac: add mmap
* x11vnc: -rawfb, -pipeinput, -xtrap, -flag, ...
2005-04-03 Karl Runge <runge@karlrunge.com>
* configure.ac: add conditional libXTrap checking
* x11vnc: use DEC-XTRAP on old X11R5 for grab control.
-shiftcmap n, -http, fix DAMAGE event leak.
2005-03-29 Karl Runge <runge@karlrunge.com>
* x11vnc: fix event leaks, build-time customizations, -nolookup
2005-03-19 Karl Runge <runge@karlrunge.com>
* x11vnc: scale cursors by default, -scale_cursor to tune,
-arrow n, -norepeat n, speed up integer magnification.
2005-03-12 Karl Runge <runge@karlrunge.com>
* x11vnc: X DAMAGE support, -clip WxH+X+Y, identd.
2005-03-05 Karl Runge <runge@karlrunge.com>
* autoconf: rpm -> rpmbuild and echo -n -> printf
2005-03-04 Karl Runge <runge@karlrunge.com>
* libvncserver/{cargs.c,sockets.c}: add -listen option and
rfbScreen member listenInterface.
* rfb/rfb.h: rfbListenOnTCPPort() and rfbListenOnUDPPort()
function prototypes changed to include network interface.
2005-02-14 Karl Runge <runge@karlrunge.com>
* x11vnc: -users lurk=, -solid for cde, -gui ez,.. beginner mode.
2005-02-10 Karl Runge <runge@karlrunge.com>
* x11vnc: -input option to fine tune allowed client input,
additions to remote control and gui for this.
2005-02-09 Karl Runge <runge@karlrunge.com>
* x11vnc: -users, fix -solid on gnome and kde.
* configure.ac: add pwd.h, wait.h, and utmpx.h checks.
2005-02-06 Karl Runge <runge@karlrunge.com>
* configure.ac: add /usr/sfw on Solaris when XFIXES, add
--with-jpeg=DIR --with-zlib=DIR, workaround bug when
--without-jpeg was supplied.
* prepare_x11vnc_dist.sh: few tweaks for next release
2005-02-05 Karl Runge <runge@karlrunge.com>
* x11vnc: -solid color, -opts/-?
* tightvnc-1.3dev5-vncviewer-alpha-cursor.patch: create, name
says it all.
2005-01-23 Karl Runge <runge@karlrunge.com>
* x11vnc: -timeout, -noalphablend. make -R norepeat work.
* sync with new draw cursor mechanism.
2005-01-20 Karl Runge <runge@karlrunge.com>
* libvncserver/{cursor.c,rfbserver.c}: fixed the "disappearing cursor"
problem
2005-01-18 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* rfb/rfb.h libvncserver/rfbserver.c: pointerClient was still static
* libvncserver/rfbserver.c: do not make requestedRegion empty without
reason.
* almost everything: the cursor handling for clients which don't handle
CursorShape updates was completely broken. It originally was very
complicated for performance reasons, however, in most cases it made
performance even worse, because at idle times there was way too much
checking going on, and furthermore, sometimes unnecessary updates
were inevitable.
The code now is much more elegant: the ClientRec structure knows
exactly where it last painted the cursor, and the ScreenInfo
structure knows where the cursor shall be.
As a consequence there is no more rfbDrawCursor()/rfbUndrawCursor(),
no more dontSendFramebufferUpdate, and no more isCursorDrawn.
It is now possible to have clients which understand CursorShape
updates and clients which don't at the same time.
* libvncserver/cursor.c: rfbSetCursor no longer has the option
freeOld; this is obsolete, as the cursor structure knows what
to free and what not.
2005-01-15 Karl Runge <runge@karlrunge.com>
* rfb/rfb.h: add alphaSource and alphaPreMultiplied to rfbCursor.
* libvncserver/cursor.c: do cursor alpha blending in rfbDrawCursor()
for non-cursorshapeupdates clients.
* x11vnc: -alphablend, cursors fixes, -snapfb, more tweaks and bug
fixes.
2004-12-27 Karl Runge <runge@karlrunge.com>
* x11vnc: improve alpha channel handling for XFIXES cursors.
* add more parameters to remote control.
2004-12-20 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* released version 0.7
2004-12-19 Karl Runge <runge@karlrunge.com>
* x11vnc: string cleanup, synchronous remote-control option -sync
* libvncserver/cursor.c: zero underCursorBufferLen when cursor freed.
2004-12-16 Karl Runge <runge@karlrunge.com>
* test/encodingstest.c: fix decl bug in main()
* x11vnc: use XFIXES extension to show the exact cursor shape.
* remote control nearly everything on the fly, -remote/-query
* tcl/tk gui based on the remote control, -gui
* support screen size changes with XRANDR ext., -xrandr, -padgeom
* Misc: -overlay visual support on IRIX, -id pick, -pointer_mode n,
-sb n, RFB_MODE set in env. under -accept/-gone.
2004-12-02 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* make LibVNCServer compile & work on MinGW32
2004-11-30 "Leiradella, Andre V Matos Da Cunha" <ANDRE.LEIRADELLA@bra.xerox.com>
* libvncclient/sockets.c: return TRUE in every case of success
2004-08-29 Karl Runge <runge@karlrunge.com>
* x11vnc: yet another pointer input handling algorithm in
check_user_input(), revert to previous with -old_pointer2.
* modifiy prepare_x11vnc_dist.sh to install tightvnc Java viewer
in $prefix/share/x11vnc/classes
2004-08-29 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* */*.[ch]: API changes: global functions/structures should have
* either "rfb", "sra" or "zrle" as prefix, while structure members
* should not...
2004-08-29 Karl Runge <runge@karlrunge.com>
* x11vnc: changes in cursor shape handling: use rfbSetCursor()
* cursor shape options: -cursor, -cursor (X|some|most)
* -vncconnect the default.
* configure.ac: add more macros for X extensions.
2004-08-15 Karl Runge <runge@karlrunge.com>
* x11vnc: -overlay to fix colors with Sun 8+24 overlay visuals.
* -sid option.
2004-08-03 Karl Runge <runge@karlrunge.com>
* x11vnc: manpage and README
* fix XKBlib.h detection on *BSD
2004-07-31 Karl Runge <runge@karlrunge.com>
* x11vnc: -cursorpos now the default
2004-07-28 Karl Runge <runge@karlrunge.com>
* x11vnc: -add_keysyms dynamically add missing keysyms to X server
2004-07-26 Karl Runge <runge@karlrunge.com>
* x11vnc: first pass at doing modtweak via XKEYBOARD extension (-xkb)
* -skip_keycodes; reset modtweaks on event MappingNotify.
* fix bugs wrt PRIMARY handling.
* continuation lines "\" in x11vncrc.
2004-07-15 Karl Runge <runge@karlrunge.com>
* x11vnc: modtweak is now the default
* check X11/XKBlib.h in configure.ac to work around Solaris 7 bug.
2004-07-10 Karl Runge <runge@karlrunge.com>
* x11vnc: norepeat to turn off X server autorepeat when clients exist,
let the client side do the autorepeating.
2004-06-26 Karl Runge <runge@karlrunge.com>
* x11vnc: add "-scale fraction" for global server-side scaling.
2004-06-17 Karl Runge <runge@karlrunge.com>
* x11vnc: simple ~/.x11vncrc config file support, -rc, -norc
2004-06-12 Karl Runge <runge@karlrunge.com>
* x11vnc: -clear_mods, -clear_keys, and -storepasswd,
* add RFB_SERVER_IP RFB_SERVER_PORT to -accept env.
2004-06-07 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* libvncserver/cursor.c, rfb/rfb.h: fix cursor trails
* */Makefile.am: stop automake nagging
* libvncclient/*, client_examples/*: streamline API, SDLvncviewer added
* examples/, libvncclient/, test/: moved tests to test/
2004-06-05 Karl Runge <runge@karlrunge.com>
* x11vnc: rearrange file for easier maintenance
* add RFB_CLIENT_COUNT to -accept and -gone commands
2004-05-27 Karl Runge <runge@karlrunge.com>
* x11vnc: -viewpasswd, viewonly passwds.
* some typos in prepare_x11vnc_dist.sh
* libvncserver: fix view-only plain passwd and view-only CutText
2004-05-25 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* moved the library into libvncserver/
* moved x11vnc into x11vnc/
2004-05-21 Karl Runge <runge@karlrunge.com>
* x11vnc: -gone, -passwdfile, -o logfile; add view-only to -accept
2004-05-08 Karl Runge <runge@karlrunge.com>
* x11vnc: add -accept some-command/xmessage/popup
2004-05-05 Karl Runge <runge@karlrunge.com>
* x11vnc: mouse button -> keystrokes and keystroke -> mouse button
mappings in -buttonmap and -remap
* shm OS blacklist revert to -onetile
2004-04-28 Karl Runge <runge@karlrunge.com>
* x11vnc: -auth, more -cursorpos and -nofb work
2004-04-19 Karl Runge <runge@karlrunge.com>
* x11vnc: -cursorpos, -sigpipe
2004-04-13 Karl Runge <runge@karlrunge.com>
* x11vnc: do not send selection unless all clients
are in RFB_NORMAL state.
* increase rfbMaxClientWait when threaded to avoid
ReadExact() timeouts for some viewers.
2004-04-08 Karl Runge <runge@karlrunge.com>
* x11vnc options -blackout, -xinerama, -xwarppointer
* modify configure.ac to pick up -lXinerama
* extend -remap to take mapping list.
* check cargs result for unused args.
2004-03-22 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* fix cargs.c (hopefully for the last time):
arguments were not correctly purged
2004-03-15 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* fix libvncserver-config to again return a linker when
called with --link
2004-03-10 Karl Runge <runge@karlrunge.com>
* x11vnc options -vncconnect, -connect, -remap,
-debug_pointer, and -debug_keyboard
* support reverse connections, vncconnect(1), etc.
* expt. with user supplied keysym remapping.
* debug output option for pointer and keyboard.
2004-02-29 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* fixed warning of valgrind for regiontest
2004-02-19 Karl Runge <runge@karlrunge.com>
* x11vnc options -nosel -noprimary -visual.
* add clipboard/selection handling.
* add visual option (mostly for testing and workarounds).
* improve shm cleanup on failures.
2004-02-04 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* Make examples (at least a few) compileable with g++,
as pointed out by Juan Jose Costello
2004-01-30 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* Thanks to Paul Fox from Bright Star Engineering,
a few more memory leaks were fixed.
2004-01-29 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* Honour the check for libz and libjpeg again.
2004-01-21 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* do not send unneccessary updates when drawing a cursor
* ignore SIGPIPE; it is handled by EPIPE
* add an example how to use rfbDoCopyRect
* add experimental progressive updating (off by default)
2004-01-19 Karl Runge <runge@karlrunge.com>
* handle mouse button number mismatch
* improved pointer input handling during drags, etc.
* somewhat faster copy_tiles() -> copy_tiles()
* x11vnc options -buttonmap -old_pointer -old_copytile
2004-01-16 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* compile fix for cygwin
2004-01-09 Karl Runge <runge@karlrunge.com>
* x11vnc options -allow, -localhost, -nodragging, -input_skip
* minimize memory usage under -nofb
2003-12-08 Karl Runge <runge@karlrunge.com>
* add check for XKEYBOARD extension in configure.ac
* support XBell events (disable: "-nobell"), "-nofb" in x11vnc
2003-11-07 Karl Runge <runge@karlrunge.com>
* support "-inetd", "-noshm", "-flipbyteorder" in x11vnc
2003-10-26 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* released Version 0.6
2003-09-11 Mark McLoughlin <mark@skynet.ie>
* Makefile.in, */Makefile.in, aclocal.m4,
bootstrap.sh, config.h.in, configure,
depcomp, install-sh, missing, mkinstalldirs,
Removed auto-generated files from CVS.
2003-09-11 Mark McLoughlin <mark@skynet.ie>
* rdr/Exception.h, rdr/FdInStream.cxx, rdr/FdInStream.h,
rdr/FdOutStream.cxx, rdr/FdOutStream.h, rdr/FixedMemOutStream.h,
rdr/InStream.cxx, rdr/InStream.h, rdr/MemInStream.h,
rdr/MemOutStream.h, rdr/NullOutStream.cxx, rdr/NullOutStream.h,
rdr/OutStream.h, rdr/ZlibInStream.cxx, rdr/ZlibInStream.h,
rdr/ZlibOutStream.cxx, rdr/ZlibOutStream.h, rdr/types.h,
zrle.cxx, zrleDecode.h, zrleEncode.h: remove original
C++ ZRLE implementation. Its been ported to C.
* NEWS: copy the existing ChangeLog to here and make
this a more detailed ChangeLog.

View File

@ -0,0 +1,182 @@
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.

View File

@ -0,0 +1,27 @@
if WITH_X11VNC
X11VNC=x11vnc
endif
SUBDIRS=libvncserver examples contrib libvncclient vncterm classes client_examples test $(X11VNC)
DIST_SUBDIRS=libvncserver examples contrib libvncclient vncterm classes client_examples test
bin_SCRIPTS = libvncserver-config
includedir=$(prefix)/include/rfb
#include_HEADERS=rfb.h rfbconfig.h rfbint.h rfbproto.h keysym.h rfbregion.h
include_HEADERS=rfb/rfb.h rfb/rfbconfig.h rfb/rfbint.h rfb/rfbproto.h \
rfb/keysym.h rfb/rfbregion.h rfb/rfbclient.h
$(PACKAGE)-$(VERSION).tar.gz: dist
if HAVE_RPM
# Rule to build RPM distribution package
rpm: $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE).spec
cp $(PACKAGE)-$(VERSION).tar.gz @RPMSOURCEDIR@
rpmbuild -ba $(PACKAGE).spec
endif
t:
$(MAKE) -C test test

View File

@ -0,0 +1,147 @@
Mark sent me patches to no longer need C++ for ZRLE encoding!
added --disable-cxx Option for configure
x11vnc changes from Karl Runge:
- Changed all those whimpy printf(...)'s into manly fprintf(stdxxx,...)'s.
- Added -q switch (quiet) to suppress printing all the debug-looking output.
- Added -bg switch to fork into background after everything is set up.
(checks for LIBVNCSERVER_HAVE_FORK and LIBVNCSERVER_HAVE_SETSID)
- Print this string out to stdout: 'PORT=XXXX' (usually XXXX = 5900).
Combining with -bg, easy to write a ssh/rsh wrapper with something like:
port=`ssh $host "x11vnc -bg .."` then run vncviewer based on $port output.
(tunneling the vnc traffic thru ssh a bit more messy, but doable)
- Quite a bit of code to be more careful when doing 8bpp indexed color, e.g.
not assuming NCOLORS is 256, handling 8bit TrueColor and Direct Color, etc
(I did all this probably in April, not quite clear in my mind now, but
I did test it out a fair amount on my old Sparcstation 20 wrt a user's
questions).
introduce rfbErr for Errors (Erik)
make rfbLog overridable (suggested by Erik)
don't reutrn on EINTR in WriteExact()/ReadExact() (suggested by Erik)
use AX_PREFIX_CONFIG_H to prefix constants in config.h to avoid
name clashes (also suggested by Erik)
transformed Bool, KeySym, Pixel to rfbBool, rfbKeySym, rfbPixel
(as suggested by Erik)
purged exit() calls (suggested by Erik)
fixed bug with maxRectsPerUpdate and Tight Encoding (these are incompatible)
checked sync with TightVNC 1.2.8:
viewonly/full passwords; if given a list, only the first is a full one
vncRandomBytes is a little more secure now
new weights for tight encoding
checked sync with RealVNC 3.3.7
introduced maxRectsPerUpdate
added first alpha version of LibVNCClient
added simple and simple15 example (really simple examples)
finally got around to fix configure in CVS
long standing http bug (.jar was sent twice) fixed by a friend of Karl named Mike
http options in cargs
when closing a client and no longer listening for new ones, don't crash
fixed a bug with ClientConnectionGone
endianness is checked at configure time
fixed a bug that prevented the first client from being closed
fixed that annoying "libvncserver-config --link" bug
make rfbReverseByte public (for rdp2vnc)
fixed compilation on OS X, IRIX, Solaris
install target for headers is now ${prefix}/include/rfb ("#include <rfb/rfb.h>")
renamed "sraRegion.h" to "rfbregion.h"
CARD{8,16,32} are more standard uint{8,16,32}_t now
fixed LinuxVNC colour handling
fixed a bug with pthreads where the connection was not closed
moved vncterm to main package (LinuxVNC included)
portability fixes (IRIX, OSX, Solaris)
more portable way to determine endianness and types of a given size
through autoconf based methods
0.5
rpm packaging through autoconf
autoconf'ed the whole package (including optional support for zlib,
pthreads and libjpeg as well as zrle/c++)
moved appropriate files to contrib/ and examples/ respectively
fixed long standing cargs bug (Justin "Zippy" Dearing)
Even better x11vnc from Karl J. Runge! (supports different kbd layouts of
client/server)
Better x11vnc from Karl J. Runge!
fixed severe bug (Const Kaplinsky)
got patch from Const Kaplisnky with CursorPosUpdate encoding and some Docs
sync'ed with newest RealVNC (ZRLE encoding)
a HTTP request for tunnelling was added (to fool strict web proxies)
sync'ed with TightVNC 1.2.5
0.4
support for NewFB from Const Kaplinsky
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 starting again with special options if compiling
with LOCAL_CONTROL defined
0.3
added x11vnc, a x0rfbserver clone
regard deferUpdateTime in processEvents, if usec<0
initialize deferUpdateTime (memory "leak"!)
changed command line handling (arguments are parsed and then removed)
added very simple example: zippy
added rfbDrawLine, rfbDrawPixel
0.2
inserted a deferUpdate mechanism (X11 independent).
removed deletion of requestedRegion
added rfbLoadConsoleFont
fixed font colour handling.
added rfbSelectBox
added rfbDrawCharWithClip to allow for clipping and a background colour.
fixed font colours
added rfbFillRect
added IO function to check password.
rfbNewClient now sets the socket in the fd_set (for the select() call)
when compiling the library with HAVE_PTHREADS and an application
which includes "rfb.h" without, the structures got mixed up.
So, the pthreads section is now always at the end, and also
you get a linker error for rfbInitServer when using two different
pthread setups.
fixed two deadlocks: when setting a cursor and when using CopyRect
fixed CopyRect when copying modified regions (they lost the modified
property)
WIN32 target compiles and works for example :-)
fixed CopyRect (was using the wrong order of rectangles...)
should also work with pthreads, because copyrects are
always sent immediately (so that two consecutive copy rects
cannot conflict).
changed rfbUndrawCursor(rfbClientPtr) to (rfbScreenInfoPtr), because
this makes more sense!
flag backgroundLoop in rfbScreenInfo (if having pthreads)
CopyRect & CopyRegion were implemented.
if you use a rfbDoCopyR* function, it copies the data in the
framebuffer. If you prefer to do that yourself, use rfbScheduleCopyR*
instead; this doesn't modify the frameBuffer.
added flag to optionally not send XCursor updates, but only RichCursor,
or if that is not possible, fall back to server side cursor.
This is useful if your cursor has many nice colours.
fixed java viewer on server side:
SendCursorUpdate would send data even before the client pixel format
was set, but the java applet doesn't like the server's format.
fixed two pthread issues:
rfbSendFramebuffer was sent by a ProcessClientMessage function
(unprotected by updateMutex).
cursor coordinates were set without protection by cursorMutex
source is now equivalent to TridiaVNC 1.2.1
pthreads now work (use iterators!)
cursors are supported (rfbSetCursor automatically undraws cursor)
support for 3 bytes/pixel (slow!)
server side colourmap support
fixed rfbCloseClient not to close the connection (pthreads!)
this is done lazily (and with proper signalling).
cleaned up mac.c (from original OSXvnc); now compiles (untested!)
compiles cleanly on Linux, IRIX, BSD, Apple (Darwin)
fixed prototypes
0.1
rewrote API to use pseudo-methods instead of required functions.
lots of clean up.
Example can show symbols now.
All encodings
HTTP

View File

@ -0,0 +1,439 @@
LibVNCServer: a library for easy implementation of a RDP/VNC server.
Copyright (C) 2001-2003 Johannes E. Schindelin
If you already used LibVNCServer, you probably want to read NEWS.
What is it?
-----------
VNC is a set of programs using the RFB (Remote Frame Buffer) protocol. They
are designed to "export" a frame buffer via net (if you don't know VNC, I
suggest you read "Basics" below). It is already in wide use for
administration, but it is not that easy to program a server yourself.
This has been changed by LibVNCServer.
There are two examples included:
- example, a shared scribble sheet
- pnmshow, a program to show PNMs (pictures) over the net.
The examples are not too well documented, but easy straight forward and a
good starting point.
Try example: it outputs on which port it listens (default: 5900), so it is
display 0. To view, call
vncviewer :0
You should see a sheet with a gradient and "Hello World!" written on it. Try
to paint something. Note that everytime you click, there is some bigger blot,
whereas when you drag the mouse while clicked you draw a line. The size of the
blot depends on the mouse button you click. Open a second vncviewer with
the same parameters and watch it as you paint in the other window. This also
works over internet. You just have to know either the name or the IP of your
machine. Then it is
vncviewer machine.where.example.runs.com:0
or similar for the remote client. Now you are ready to type something. Be sure
that your mouse sits still, because everytime the mouse moves, the cursor is
reset to the position of the pointer! If you are done with that demo, press
the down or up arrows. If your viewer supports it, then the dimensions of the
sheet change. Just press Escape in the viewer. Note that the server still
runs, even if you closed both windows. When you reconnect now, everything you
painted and wrote is still there. You can press "Page Up" for a blank page.
The demo pnmshow is much simpler: you either provide a filename as argument
or pipe a file through stdin. Note that the file has to be a raw pnm/ppm file,
i.e. a truecolour graphics. Only the Escape key is implemented. This may be
the best starting point if you want to learn how to use LibVNCServer. You
are confronted with the fact that the bytes per pixel can only be 8, 16 or 32.
Projects using it
----------------------------------------
VNC for KDE
http://www.tjansen.de/krfb
GemsVNC
http://www.elilabs.com/~rj/gemsvnc/
VNC for Netware
http://forge.novell.com/modules/xfmod/project/?vncnw
RDesktop
http://rdesktop.sourceforge.net
Mail me, if your application is missing!
How to use
----------
To make a server, you just have to initialise a server structure using the
function rfbDefaultScreenInit, like
rfbScreenInfoPtr rfbScreen =
rfbGetScreen(argc,argv,width,height,8,3,bpp);
where byte per pixel should be 1, 2 or 4. If performance doesn't matter,
you may try bpp=3 (internally one cannot use native data types in this
case; if you want to use this, look at pnmshow24).
You then can set hooks and io functions (see below) or other
options (see below).
And you allocate the frame buffer like this:
rfbScreen->frameBuffer = (char*)malloc(width*height*bpp);
After that, you initialize the server, like
rfbInitServer(rfbScreen);
You can use a blocking event loop, a background (pthread based) event loop,
or implement your own using the rfbProcessEvents function.
Making it interactive
---------------------
Input is handled by IO functions (see below).
Whenever you change something in the frame buffer, call rfbMarkRectAsModified.
You should make sure that the cursor is not drawn before drawing yourself
by calling rfbUndrawCursor. You can also draw the cursor using rfbDrawCursor,
but it hardly seems necessary. For cursor details, see below.
Utility functions
-----------------
Whenever you draw something, you have to call
rfbMarkRectAsModified(screen,x1,y1,x2,y2).
This tells LibVNCServer to send updates to all connected clients.
Before you draw something, be sure to call
rfbUndrawCursor(screen).
This tells LibVNCServer to hide the cursor.
Remark: There are vncviewers out there, which know a cursor encoding, so
that network traffic is low, and also the cursor doesn't need to be
drawn the cursor everytime an update is sent. LibVNCServer handles
all the details. Just set the cursor and don't bother any more.
To set the mouse coordinates (or emulate mouse clicks), call
defaultPtrAddEvent(buttonMask,x,y,cl);
IMPORTANT: do this at the end of your function, because this actually draws
the cursor if no cursor encoding is active.
What is the difference between rfbScreenInfoPtr and rfbClientPtr?
-----------------------------------------------------------------
The rfbScreenInfoPtr is a pointer to a rfbScreenInfo structure, which
holds information about the server, like pixel format, io functions,
frame buffer etc.
The rfbClientPtr is a pointer to an rfbClientRec structure, which holds
information about a client, like pixel format, socket of the
connection, etc.
A server can have several clients, but needn't have any. So, if you
have a server and three clients are connected, you have one instance
of a rfbScreenInfo and three instances of rfbClientRec's.
The rfbClientRec structure holds a member
rfbScreenInfoPtr screen
which points to the server and a member
rfbClientPtr next
to the next client.
The rfbScreenInfo structure holds a member
rfbClientPtr rfbClientHead
which points to the first client.
So, to access the server from the client structure, you use client->screen.
To access all clients from a server, get screen->rfbClientHead and
iterate using client->next.
If you change client settings, be sure to use the provided iterator
rfbGetClientIterator(rfbScreen)
with
rfbClientIteratorNext(iterator)
and
rfbReleaseClientIterator
to prevent thread clashes.
Other options
-------------
These options have to be set between rfbGetScreen and rfbInitServer.
If you already have a socket to talk to, just set rfbScreen->inetdSock
(originally this is for inetd handling, but why not use it for your purpose?).
To also start an HTTP server (running on port 5800+display_number), you have
to set rfbScreen->httpdDir to a directory containing vncviewer.jar and
index.vnc (like the included "classes" directory).
Hooks and IO functions
----------------------
There exist the following IO functions as members of rfbScreen:
kbdAddEvent, kbdReleaseAllKeys, ptrAddEvent and setXCutText
kbdAddEvent(rfbBool down,rfbKeySym key,rfbClientPtr cl)
is called when a key is pressed.
kbdReleaseAllKeys(rfbClientPtr cl)
is not called at all (maybe in the future).
ptrAddEvent(int buttonMask,int x,int y,rfbClientPtr cl)
is called when the mouse moves or a button is pressed.
WARNING: if you want to have proper cursor handling, call
defaultPtrAddEvent(buttonMask,x,y,cl)
in your own function. This sets the coordinates of the cursor.
setXCutText(char* str,int len,rfbClientPtr cl)
is called when the selection changes.
There are only two hooks:
newClientHook(rfbClientPtr cl)
is called when a new client has connected.
displayHook
is called just before a frame buffer update is sent.
You can also override the following methods:
getCursorPtr(rfbClientPtr cl)
This could be used to make an animated cursor (if you really want ...)
setTranslateFunction(rfbClientPtr cl)
If you insist on colour maps or something more obscure, you have to
implement this. Default is a trueColour mapping.
Cursor handling
---------------
The screen holds a pointer
rfbCursorPtr cursor
to the current cursor. Whenever you set it, remember that any dynamically
created cursor (like return value from rfbMakeXCursor) is not free'd!
The rfbCursor structure consists mainly of a mask and a source. The mask
describes, which pixels are drawn for the cursor (a cursor needn't be
rectangular). The source describes, which colour those pixels should have.
The standard is an XCursor: a cursor with a foreground and a background
colour (stored in backRed,backGreen,backBlue and the same for foreground
in a range from 0-0xffff). Therefore, the arrays "mask" and "source"
contain pixels as single bits stored in bytes in MSB order. The rows are
padded, such that each row begins with a new byte (i.e. a 10x4
cursor's mask has 2x4 bytes, because 2 bytes are needed to hold 10 bits).
It is however very easy to make a cursor like this:
char* cur=" "
" xx "
" x "
" ";
char* mask="xxxx"
"xxxx"
"xxxx"
"xxx ";
rfbCursorPtr c=rfbMakeXCursor(4,4,cur,mask);
You can even set "mask" to NULL in this call and LibVNCServer will calculate
a mask for you (dynamically, so you have to free it yourself).
There is also an array named "richSource" for colourful cursors. They have
the same format as the frameBuffer (i.e. if the server is 32 bit,
a 10x4 cursor has 4x10x4 bytes).
History
-------
LibVNCServer is based on Tridia VNC and OSXvnc, which in turn are based on
the original code from ORL/AT&T.
When I began hacking with computers, my first interest was speed. So, when I
got around assembler, I programmed the floppy to do much of the work, because
it's clock rate was higher than that of my C64. This was my first experience
with client/server techniques.
When I came around Xwindows (much later), I was at once intrigued by the
elegance of such connectedness between the different computers. I used it
a lot - not the least priority lay on games. However, when I tried it over
modem from home, it was no longer that much fun.
When I started working with ASP (Application Service Provider) programs, I
tumbled across Tarantella and Citrix. Being a security fanatic, the idea of
running a server on windows didn't appeal to me, so Citrix went down the
basket. However, Tarantella has it's own problems (security as well as the
high price). But at the same time somebody told me about this "great little
administrator's tool" named VNC. Being used to windows programs' sizes, the
surprise was reciprocal inverse to the size of VNC!
At the same time, the program "rdesktop" (a native Linux client for the
Terminal Services of Windows servers) came to my attention. There where even
works under way to make a protocol converter "rdp2vnc" out of this. However,
my primary goal was a slow connection and rdp2vnc could only speak RRE
encoding, which is not that funny with just 5kB/s. Tim Edmonds, the original
author of rdp2vnc, suggested that I adapt it to Hextile Encoding, which is
better. I first tried that, but had no success at all (crunchy pictures).
Also, I liked the idea of an HTTP server included and possibly other
encodings like the Tight Encodings from Const Kaplinsky. So I started looking
for libraries implementing a VNC server where I could steal what I can't make.
I found some programs based on the demo server from AT&T, which was also the
basis for rdp2vnc (can only speak Raw and RRE encoding). There were some
rumors that GGI has a VNC backend, but I didn't find any code, so probably
there wasn't a working version anyway.
All of a sudden, everything changed: I read on freshmeat that "OSXvnc" was
released. I looked at the code and it was not much of a problem to work out
a simple server - using every functionality there is in Xvnc. It became clear
to me that I *had* to build a library out of it, so everybody can use it.
Every change, every new feature can propagate to every user of it.
It also makes everything easier:
You don't care about the cursor, once set (or use the standard cursor).
You don't care about those sockets. You don't care about encodings.
You just change your frame buffer and inform the library about it. Every once
in a while you call rfbProcessEvents and that's it.
Basics
------
VNC (Virtual network computing) works like this: You set up a server and can
connect to it via vncviewers. The communication uses a protocol named RFB
(Remote Frame Buffer). If the server supports HTTP, you can also connect
using a java enabled browser. In this case, the server sends back a
vncviewer applet with the correct settings.
There exist several encodings for VNC, which are used to compress the regions
which have changed before they are sent to the client. A client need not be
able to understand every encoding, but at least Raw encoding. Which encoding
it understands is negotiated by the RFB protocol.
The following encodings are known to me:
Raw, RRE, CoRRE, Hextile, CopyRect from the original AT&T code and
Tight, ZLib, LastRect, XCursor, RichCursor from Const Kaplinsky et al.
If you are using a modem, you want to try the "new" encodings. Especially
with my 56k modem I like ZLib or Tight with Quality 0. In my tests, it even
beats Tarantella.
There is the possibility to set a password, which is also negotiated by the
RFB protocol, but IT IS NOT SECURE. Anybody sniffing your net can get the
password. You really should tunnel through SSH.
Windows or: why do you do that to me?
--------------------------------------------
If you love products from Redmod, you better skip this paragraph.
I am always amazed how people react whenever Microsoft(tm) puts in some
features into their products which were around for a long time. Especially
reporters seem to not know dick about what they are reporting about! But
what is everytime annoying again, is that they don't do it right. Every
concept has it's new name (remember what enumerators used to be until
Mickeysoft(tm) claimed that enumerators are what we thought were iterators.
Yeah right, enumerators are also containers. They are not separated. Muddy.)
There are three packages you want to get hold of: zlib, jpeg and pthreads.
The latter is not strictly necessary, but when you put something like this
into your source:
#define MUTEX(s)
struct {
int something;
MUTEX(latex);
}
Microsoft's C++ compiler doesn't do it. It complains that this is an error.
This, however, is how I implemented mutexes in case you don't need pthreads,
and so don't need the mutex.
You can find the packages at
http://www.gimp.org/win32/extralibs-dev-20001007.zip
Thanks go to all the GIMP team!
What are those other targets in the Makefile?
---------------------------------------------
OSXvnc-server is the original OSXvnc adapted to use the library, which was in
turn adapted from OSXvnc. As you easily can see, the OSX dependend part is
minimal.
storepasswd is the original program to save a vnc style password in a file.
Unfortunately, authentication as every vncviewer speaks it means the server
has to know the plain password. You really should tunnel via ssh or use
your own PasswordCheck to build a PIN/TAN system.
sratest is a test unit. Run it to assert correct behaviour of sraRegion. I
wrote this to test my iterator implementation.
blooptest is a test of pthreads. It is just the example, but with a background
loop to hunt down thread lockups.
pnmshow24 is like pnmshow, but it uses 3 bytes/pixel internally, which is not
as efficient as 4 bytes/pixel for translation, because there is no native data
type of that size, so you have to memcpy pixels and be real cautious with
endianness. Anyway, it works.
fontsel is a test for rfbSelectBox and rfbLoadConsoleFont. If you have Linux
console fonts, you can browse them via VNC. Directory browsing not implemented
yet :-(
Why I don't feel bad about GPL
------------------------------
At the beginning of this projects I would have liked to make it a BSD
license. However, it is based on plenty of GPL'ed code, so it has to be
a GPL. I hear BeeGee complaining: "but that's invasive, every derivative
work, even just linking, makes my software GPL!"
Yeah. That's right. It is because there are nasty jarheads out there who
would take anybody's work and claim it their own, selling it for much too
much money, stealing freedom and innovation from others, saying they were
the maintainers of innovation, lying, making money with that.
The people at AT&T worked really well to produce something as clean and lean
as VNC. The managers decided that for their fame, they would release the
program for free. But not only that! They realized that by releasing also
the code for free, VNC would become an evolving little child, conquering
new worlds, making it's parents very proud. As well they can be! To protect
this innovation, they decided to make it GPL, not BSD. The principal
difference is: You can make closed source programs deriving from BSD, not
from GPL. You have to give proper credit with both.
Now, why not BSD? Well, imagine your child being some famous actor. Along
comes a manager who exploits your child exclusively, that is: nobody else
can profit from the child, it itself included. Got it?
What reason do you have now to use this library commercially?
Several: You don't have to give away your product. Then you have effectively
circumvented the GPL, because you have the benefits of other's work and you
don't give back anything and you will be in hell for that. In fact, this
library, as my other projects, is a payback for all the free software I can
use (and sometimes, make better). For example, just now, I am using XEmacs
on top of XFree86, all running under Linux.
Better: Use a concept like MySQL. This is free software, however, they make
money with it. If you want something implemented, you have the choice:
Ask them to do it (and pay a fair price), or do it yourself, normally giving
back your enhancements to the free world of computing.
Learn from it: If you like the style this is written, learn how to imitate
it. If you don't like the style, learn how to avoid those things you don't
like. I learnt so much, just from looking at code like Linux, XEmacs,
LilyPond, STL, etc.
License
-------
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.dfdf
Contact
-------
To contact me, mail me: Johannes dot Schindelin at gmx dot de

View File

@ -0,0 +1,22 @@
If you check out CVS of LibVNCServer, everything should build as usual:
./configure && make
If your machine complains not having the right version of automake (which should
not be necessary, because every needed file is checked in), try
find -name Makefile.in -exec touch {} \;
and rerun ./configure && make
If you want to make changes which require automake or autoconf (i.e. you
check for other headers or add files), you have to have a current
(>2.50) version of autoconf. Also, you need automake.
Then, just do
sh autogen.sh && make
in LibVNCServer's directory, and you should see plenty of output and
finally have a complete build of LibVNCServer.
Happy VNC'ing!

View File

@ -0,0 +1,42 @@
## LibVNCServer with the Tight PNG encoding
### LibVNCServer
Copyright (C) 2001-2003 Johannes E. Schindelin
[LibVNCServer](http://sourceforge.net/projects/libvncserver/) is
a library for easy implementation of a RDP/VNC server.
### Tight PNG
Copyright (C) 2010 Joel Martin
The [Tight PNG encoding](http://wiki.qemu.org/VNC_Tight_PNG) is
similar to the Tight encoding, but the basic compression (zlib) is
replaced with PNG data.
This encoding allows for simple, fast clients and bandwidth efficient
clients:
* The PNG data can be rendered directly by the client so there is
negligible decode work needed in the VNC client itself.
* PNG images are zlib compressed internally (along with other
optimizations) so tightPng is comparable in bandwith to tight.
* PNG images are natively supported in the browsers. This is optimal
for web based VNC clients such as
[noVNC](http://github.com/kanaka/noVNC)
### Usage
See INSTALL for build instructions. To build with the tightPng
encoding, you must also have libpng development libraries install. For
example:
sudo apt-get install libpng-dev
### TODO
- Handle palette mode (non-truecolor).

View File

@ -0,0 +1,26 @@
immediate:
----------
make SDLvncviewer more versatile
- test for missing keys (especially "[]{}" with ./examples/mac),
- map Apple/Linux/Windows keys onto each other,
- handle selection
- handle scroll wheel
style fixes: use Linux' coding guidelines & ANSIfy tightvnc-filetransfer:
discuss on list
LibVNCClient cleanup: prefix with "rfbClient", and make sure it does
not deliberately die() or exit() anywhere!
java vncviewer doesn't do colour cursors?
MinGW32 doesn't do fcntl on sockets; use setsockopt instead...
make corre work again (libvncclient or libvncserver?)
teach SDLvncviewer about CopyRect...
implement "-record" in libvncclient
later:
------
selectbox: scroll bars
authentification schemes (secure vnc)
IO function ptr exists; now explain how to tunnel and implement a
client address restriction scheme.
VisualNaCro testing

View File

@ -0,0 +1,22 @@
aclocal.m4
autom4te.cache
config.guess
config.log
config.status
config.sub
configure
COPYING
.cvsignore
INSTALL
install-sh
Makefile
Makefile.in
missing
mkinstalldirs
nacro.pm
nacro.so
nacro_wrap.c
visualnacro-*
.deps
.in
depcomp

View File

@ -0,0 +1,5 @@
/COPYING
/INSTALL
/nacro.pm
/nacro.so
/nacro_wrap.c

View File

@ -0,0 +1,2 @@
Johannes Schindelin <Johannes.Schindelin@gmx.de>

View File

@ -0,0 +1,15 @@
2006-10-10: Johannes Schindelin <Johannes.Schindelin@gmx.de>
* implement --compact and --compact-dragging to shut up the
script about mouse movements or drags.
* add 'i', 'c' and 'r' menu keys.
2006-09-12: Johannes Schindelin <Johannes.Schindelin@gmx.de>
* the reference rectangle is selected with a rubber band,
and can be shown with 'd'.
2006-06-15: Johannes Schindelin <Johannes.Schindelin@gmx.de>
* added timing: you can record the events with their timestamps now
2005-01-13: Johannes Schindelin <Johannes.Schindelin@gmx.de>
* started the project

View File

@ -0,0 +1,51 @@
INTERFACE=nacro.h
SRCS=nacro.c
OBJS=nacro.o
ISRCS=nacro_wrap.c
IOBJS=nacro_wrap.o
TARGET=nacro
LIBS= @LIBVNCSERVERLIBS@
nacro_CFLAGS= @LIBVNCSERVERCFLAGS@
SWIGOPT=
EXTRA_DIST=autogen.sh $(INTERFACE) $(SRCS) $(ISRCS) nacro.pm recorder.pl
all: $(LIBPREFIX)$(TARGET)$(SO)
# the following is borrowed from SWIG
SWIG= @SWIG@
##################################################################
##### PERL 5 ######
##################################################################
# You need to set this variable to the Perl5 directory containing the
# files "perl.h", "EXTERN.h" and "XSUB.h". With Perl5.003, it's
# usually something like /usr/local/lib/perl5/arch-osname/5.003/CORE.
PERL5_INCLUDE= @PERL5EXT@
# Extra Perl specific dynamic linking options
PERL5_DLNK = @PERL5DYNAMICLINKING@
PERL5_CCFLAGS = @PERL5CCFLAGS@
# ----------------------------------------------------------------
# Build a Perl5 dynamically loadable module (C)
# ----------------------------------------------------------------
$(ISRCS): $(INTERFACE)
@test -n "$(SWIG)" || (echo "Need SWIG" && exit 1)
$(SWIG) -perl5 $(SWIGOPT) $(INTERFACE)
$(OBJS): $(SRCS) $(INTERFACE)
$(CC) -c -Dbool=char $(CCSHARED) $(CFLAGS) -o $@ $< $(LIBVNCSERVERCFLAGS) $(INCLUDES) -I$(PERL5_INCLUDE)
$(IOBJS): $(ISRCS) $(INTERFACE)
$(CC) -c -Dbool=char $(CCSHARED) $(CFLAGS) -o $@ $< $(INCLUDES) $(PERL5_CCFLAGS) -I$(PERL5_INCLUDE)
$(LIBPREFIX)$(TARGET)$(SO): $(OBJS) $(IOBJS)
$(LDSHARED) $(OBJS) $(IOBJS) $(PERL5_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)

View File

@ -0,0 +1,10 @@
With --timing, you can actually record action scripts which are meaningful...
Earlier, the events just got garbled, because the GUI could not react as
fast as the events were churned out.
Clipboard is supported (thanks to Uwe).
Keys are recorded by their symbols with the --symbolic switch, provided you
have the X11::Keysyms module.
After pressing Control twice, you can show the last reference image with 'd'.

View File

@ -0,0 +1,88 @@
This is VisualNaCro.
DISCLAIMER: recorder.pl is not yet functional.
What does it?
It is a Perl module meant to remote control a VNC server.
It includes a recorder (written in Perl) to make it easy to
record a macro, which is just a Perl script, and which you can
modify to your heart's content.
The most important feature, however, is that you can mark a
rectangle which the Perl script will try to find again when you
run it. Thus when you play a game and want to hit a certain button,
you just hit the Ctrl key twice, mark the button, and from then on,
all mouse movements will be repeated relative to that button, even
if the button is somewhere else when you run the script the next
time.
If you know Tcl Expect, you will recognize this approach. Only this
time, it is not text, but an image which is expected.
How does it work?
It acts as a VNC proxy: your Perl script starts its own VNC server.
The script now can intercept inputs and outputs, and act upon them.
In order to write a macro, start
recorder.pl --script my-macro.pl --timing host:port
connect with a vncviewer of your choice to <host2>:23, where <host2>
is the computer on which recorder.pl was started (not necessarily the
same as the VNC server!). Now your actions are recorded into
my_macro.pl, and the images you want to grep for will be saved as
my_macro-1.pnm, my_macro-2.pnm, ...
In order to finish the script, hit Ctrl twice and say "q".
Why did I do it?
Because I could ;-)
No really, I needed a way to write automated tests. While there
exist a lot of OpenSource programs for web testing, I found none
of them easy to use, and for GUI testing I found xautomation.
Xautomation has this "visual grep" (or "graphical expect") feature:
given an image it tries to find it on the desktop and returns the
coordinates. Unfortunately, there is no easy way to record macros
with it, and it only works on X11.
As I know VNC pretty well, and there are VNC servers for every OS
and gadget, I thought it might be cool to have this feature to
control a VNC server.
Actually, it makes it even easier: with plain X11, for example, you
can not know where on the screen the action is if you don't check
the whole screen. This complex problem is beautifully addressed
in Karl Runge's x11vnc.
My main purpose is to run regression tests on different browsers,
which I can easily do by starting Xvnc and using VisualNaCro.
How did I do it?
I wondered long about how to do it. I couldn't take the same approach
as xautomation: I cannot connect to the VNC server thousand times
per second. So I decided to create an interface of LibVNCServer/
LibVNCClient for use in a script language.
Fortunately, this task is made very, very easy by SWIG. As Perl
is one of my favorite script languages, I decided to use this.
But SWIG makes it easy to use the very same interface for other
popular languages, so you are welcome to port VisualNaCro to
the language of your choice!
Isn't it pronounced "Visual Macro"?
Yes. But I liked the Visual Na Cro play of acronyms. I'm sorry if
you don't find it funny.
What's the license?
GPL. It is based on LibVNCServer/LibVNCClient, so it has to be.
If you want to port this package to use vncreflector, which has a
BSD license, go ahead.

View File

@ -0,0 +1,55 @@
#! /bin/sh
# Run this to generate all the initial makefiles, etc.
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
DIE=0
AUTOMAKE=automake-1.4
ACLOCAL=aclocal-1.4
($AUTOMAKE --version) < /dev/null > /dev/null 2>&1 || {
AUTOMAKE=automake
ACLOCAL=aclocal
}
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have autoconf installed to compile VisualNaCro."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
($AUTOMAKE --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have automake installed to compile VisualNaCro."
echo "Get ftp://sourceware.cygnus.com/pub/automake/automake-1.4.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
}
if test "$DIE" -eq 1; then
exit 1
fi
(test -f $srcdir/nacro.h) || {
echo "You must run this script in the top-level VisualNaCro directory"
exit 1
}
if test -z "$*"; then
echo "I am going to run ./configure with no arguments - if you wish "
echo "to pass any to it, please specify them on the $0 command line."
fi
$ACLOCAL $ACLOCAL_FLAGS
#autoheader
$AUTOMAKE --add-missing --copy
autoconf
echo "Running ./configure --enable-maintainer-mode" "$@"
$srcdir/configure --enable-maintainer-mode "$@"
echo "Now type 'make' to compile VisualNaCro."

View File

@ -0,0 +1,252 @@
dnl Process this file with autoconf to produce a configure script.
dnl The macros which aren't shipped with the autotools are stored in the
dnl Tools/config directory in .m4 files.
AC_INIT([VisualNaCro],[0.1],[http://libvncserver.sourceforge.net])
AC_PREREQ(2.54)
AC_CANONICAL_HOST
AM_INIT_AUTOMAKE
dnl Checks for programs.
AC_CHECK_PROG(SWIG,swig,swig)
AC_CHECK_PROG(LIBVNCSERVERCONFIG,libvncserver-config,yes,no)
if test "$LIBVNCSERVERCONFIG" != "yes"; then
AC_MSG_ERROR([Need to have libvncserver-config in PATH])
exit 1
fi
AC_PROG_CC
AC_PROG_RANLIB
AC_EXEEXT
AC_OBJEXT
LIBVNCSERVERCFLAGS=`libvncserver-config --cflags`
LIBVNCSERVERLIBS=`libvncserver-config --libs`
AC_SUBST(LIBVNCSERVERCFLAGS)
AC_SUBST(LIBVNCSERVERLIBS)
dnl Checks for header files.
AC_HEADER_STDC
dnl How to specify include directories that may be system directories.
# -I should not be used on system directories (GCC)
if test "$GCC" = yes; then
ISYSTEM="-isystem "
else
ISYSTEM="-I"
fi
# Set info about shared libraries.
AC_SUBST(SO)
AC_SUBST(LDSHARED)
AC_SUBST(CCSHARED)
AC_SUBST(LINKFORSHARED)
# SO is the extension of shared libraries `(including the dot!)
AC_MSG_CHECKING(SO)
if test -z "$SO"
then
case $host in
*-*-hp*) SO=.sl;;
*-*-darwin*) SO=.bundle;;
*-*-cygwin* | *-*-mingw*) SO=.dll;;
*) SO=.so;;
esac
fi
AC_MSG_RESULT($SO)
# LDSHARED is the ld *command* used to create shared library
# -- "ld" on SunOS 4.x.x, "ld -G" on SunOS 5.x, "ld -shared" on IRIX 5
# (Shared libraries in this instance are shared modules to be loaded into
# Python, as opposed to building Python itself as a shared library.)
AC_MSG_CHECKING(LDSHARED)
if test -z "$LDSHARED"
then
case $host in
*-*-aix*) LDSHARED="\$(srcdir)/ld_so_aix \$(CC)";;
*-*-cygwin* | *-*-mingw*)
if test "$GCC" = yes; then
LDSHARED="dllwrap --driver-name gcc --dlltool dlltool --export-all-symbols --as as --dllname \$(LIBPREFIX)\$(TARGET)\$(SO)"
else
if test "cl" = $CC ; then
# Microsoft Visual C++ (MSVC)
LDSHARED="$CC -nologo -LD"
else
# Unknown compiler try gcc approach
LDSHARED="$CC -shared"
fi
fi ;;
*-*-irix5*) LDSHARED="ld -shared";;
*-*-irix6*) LDSHARED="ld ${SGI_ABI} -shared -all";;
*-*-sunos4*) LDSHARED="ld";;
*-*-solaris*) LDSHARED="ld -G";;
*-*-hp*) LDSHARED="ld -b";;
*-*-osf*) LDSHARED="ld -shared -expect_unresolved \"*\"";;
*-sequent-sysv4) LDSHARED="ld -G";;
*-*-next*)
if test "$ns_dyld"
then LDSHARED='$(CC) $(LDFLAGS) -bundle -prebind'
else LDSHARED='$(CC) $(CFLAGS) -nostdlib -r';
fi
if test "$with_next_framework" ; then
LDSHARED="$LDSHARED \$(LDLIBRARY)"
fi ;;
*-*-linux*) LDSHARED="gcc -shared";;
*-*-dgux*) LDSHARED="ld -G";;
*-*-freebsd3*) LDSHARED="gcc -shared";;
*-*-freebsd* | *-*-openbsd*) LDSHARED="ld -Bshareable";;
*-*-netbsd*)
if [[ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ]]
then
LDSHARED="cc -shared"
else
LDSHARED="ld -Bshareable"
fi;;
*-sco-sysv*) LDSHARED="cc -G -KPIC -Ki486 -belf -Wl,-Bexport";;
*-*-darwin*) LDSHARED="cc -bundle -undefined suppress -flat_namespace";;
*) LDSHARED="ld";;
esac
fi
AC_MSG_RESULT($LDSHARED)
# CCSHARED are the C *flags* used to create objects to go into a shared
# library (module) -- this is only needed for a few systems
AC_MSG_CHECKING(CCSHARED)
if test -z "$CCSHARED"
then
case $host in
*-*-hp*) if test "$GCC" = yes;
then CCSHARED="-fpic";
else CCSHARED="+z";
fi;;
*-*-linux*) CCSHARED="-fpic";;
*-*-freebsd* | *-*-openbsd*) CCSHARED="-fpic";;
*-*-netbsd*) CCSHARED="-fPIC";;
*-sco-sysv*) CCSHARED="-KPIC -dy -Bdynamic";;
*-*-irix6*) case $CC in
*gcc*) CCSHARED="-shared";;
*) CCSHARED="";;
esac;;
esac
fi
AC_MSG_RESULT($CCSHARED)
# RPATH is the path used to look for shared library files.
AC_MSG_CHECKING(RPATH)
if test -z "$RPATH"
then
case $host in
*-*-solaris*) RPATH='-R. -R$(exec_prefix)/lib';;
*-*-irix*) RPATH='-rpath .:$(exec_prefix)/lib';;
*-*-linux*) RPATH='-Xlinker -rpath $(exec_prefix)/lib -Xlinker -rpath .';;
*) RPATH='';;
esac
fi
AC_MSG_RESULT($RPATH)
AC_SUBST(RPATH)
# LINKFORSHARED are the flags passed to the $(CC) command that links
# the a few executables -- this is only needed for a few systems
AC_MSG_CHECKING(LINKFORSHARED)
if test -z "$LINKFORSHARED"
then
case $host in
*-*-aix*) LINKFORSHARED='-Wl,-bE:$(srcdir)/python.exp -lld';;
*-*-hp*)
LINKFORSHARED="-Wl,-E -Wl,+s -Wl,+b\$(BINLIBDEST)/lib-dynload";;
*-*-linux*) LINKFORSHARED="-Xlinker -export-dynamic";;
*-*-next*) LINKFORSHARED="-u libsys_s";;
*-sco-sysv*) LINKFORSHARED="-Bdynamic -dy -Wl,-Bexport";;
*-*-irix6*) LINKFORSHARED="-all";;
esac
fi
AC_MSG_RESULT($LINKFORSHARED)
# This variation is needed on OS-X because there is no (apparent) consistency in shared libary naming.
# Sometimes .bundle works, but sometimes .so is needed. It depends on the target language
# Optional CFLAGS used to silence compiler warnings on some platforms.
AC_SUBST(PLATFLAGS)
case $host in
*-*-darwin*) PLATFLAGS="-Wno-long-double";;
*) PLATFLAGS="";;
esac
#----------------------------------------------------------------
# Look for Perl5
#----------------------------------------------------------------
PERLBIN=
AC_ARG_WITH(perl5,[ --with-perl5=path Set location of Perl5 executable],[ PERLBIN="$withval"], [PERLBIN=])
# First figure out what the name of Perl5 is
if test -z "$PERLBIN"; then
AC_CHECK_PROGS(PERL, perl perl5.8.1 perl5.6.1 perl5.6.0 perl5.004 perl5.003 perl5.002 perl5.001 perl5 perl)
else
PERL="$PERLBIN"
fi
AC_MSG_CHECKING(for Perl5 header files)
if test -n "$PERL"; then
PERL5DIR=`($PERL -e 'use Config; print $Config{archlib}, "\n";') 2>/dev/null`
if test "$PERL5DIR" != ""; then
dirs="$PERL5DIR $PERL5DIR/CORE"
PERL5EXT=none
for i in $dirs; do
if test -r $i/perl.h; then
AC_MSG_RESULT($i)
PERL5EXT="$i"
break;
fi
done
if test "$PERL5EXT" = none; then
PERL5EXT="$PERL5DIR/CORE"
AC_MSG_RESULT(could not locate perl.h...using $PERL5EXT)
fi
AC_MSG_CHECKING(for Perl5 library)
PERL5LIB=`($PERL -e 'use Config; $_=$Config{libperl}; s/^lib//; s/$Config{_a}$//; print $_, "\n"') 2>/dev/null`
if test "$PERL5LIB" = "" ; then
AC_MSG_RESULT(not found)
else
AC_MSG_RESULT($PERL5LIB)
fi
AC_MSG_CHECKING(for Perl5 compiler options)
PERL5CCFLAGS=`($PERL -e 'use Config; print $Config{ccflags}, "\n"' | sed "s/-I/$ISYSTEM/") 2>/dev/null`
if test "$PERL5CCFLAGS" = "" ; then
AC_MSG_RESULT(not found)
else
AC_MSG_RESULT($PERL5CCFLAGS)
fi
else
AC_MSG_RESULT(unable to determine perl5 configuration)
PERL5EXT=$PERL5DIR
fi
else
AC_MSG_RESULT(could not figure out how to run perl5)
fi
# Cygwin (Windows) needs the library for dynamic linking
case $host in
*-*-cygwin* | *-*-mingw*) PERL5DYNAMICLINKING="-L$PERL5EXT -l$PERL5LIB";;
*)PERL5DYNAMICLINKING="";;
esac
AC_SUBST(PERL)
AC_SUBST(PERL5EXT)
AC_SUBST(PERL5DYNAMICLINKING)
AC_SUBST(PERL5LIB)
AC_SUBST(PERL5CCFLAGS)
#----------------------------------------------------------------
# Miscellaneous
#----------------------------------------------------------------
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
dnl configure.in ends here

View File

@ -0,0 +1,261 @@
static unsigned char default8x16FontData[4096+1]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xbd,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00,
0x00,0x00,0x7e,0xff,0xdb,0xff,0xff,0xc3,0xe7,0xff,0xff,0x7e,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x6c,0xfe,0xfe,0xfe,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x10,0x38,0x7c,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x18,0x3c,0x3c,0xe7,0xe7,0xe7,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x18,0x3c,0x7e,0xff,0xff,0x7e,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,0x00,0x00,0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,0x1e,0x0e,0x1a,0x32,0x78,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00,
0x00,0x00,0x3c,0x66,0x66,0x66,0x66,0x3c,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x3f,0x33,0x3f,0x30,0x30,0x30,0x30,0x70,0xf0,0xe0,0x00,0x00,0x00,0x00,
0x00,0x00,0x7f,0x63,0x7f,0x63,0x63,0x63,0x63,0x67,0xe7,0xe6,0xc0,0x00,0x00,0x00,
0x00,0x00,0x00,0x18,0x18,0xdb,0x3c,0xe7,0x3c,0xdb,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfe,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x00,0x00,0x00,
0x00,0x02,0x06,0x0e,0x1e,0x3e,0xfe,0x3e,0x1e,0x0e,0x06,0x02,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00,
0x00,0x00,0x7f,0xdb,0xdb,0xdb,0x7b,0x1b,0x1b,0x1b,0x1b,0x1b,0x00,0x00,0x00,0x00,
0x00,0x7c,0xc6,0x60,0x38,0x6c,0xc6,0xc6,0x6c,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xfe,0xfe,0xfe,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x18,0x0c,0xfe,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xfe,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0xc0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x24,0x66,0xff,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7c,0x7c,0xfe,0xfe,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xfe,0xfe,0x7c,0x7c,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x3c,0x3c,0x3c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x6c,0x6c,0xfe,0x6c,0x6c,0x6c,0xfe,0x6c,0x6c,0x00,0x00,0x00,0x00,
0x18,0x18,0x7c,0xc6,0xc2,0xc0,0x7c,0x06,0x06,0x86,0xc6,0x7c,0x18,0x18,0x00,0x00,
0x00,0x00,0x00,0x00,0xc2,0xc6,0x0c,0x18,0x30,0x60,0xc6,0x86,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x6c,0x6c,0x38,0x76,0xdc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x0c,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0c,0x00,0x00,0x00,0x00,
0x00,0x00,0x30,0x18,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x18,0x30,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0xc0,0x80,0x00,0x00,0x00,0x00,
0x00,0x00,0x7c,0xc6,0xc6,0xce,0xde,0xf6,0xe6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x00,0x00,0x00,0x00,
0x00,0x00,0x7c,0xc6,0x06,0x0c,0x18,0x30,0x60,0xc0,0xc6,0xfe,0x00,0x00,0x00,0x00,
0x00,0x00,0x7c,0xc6,0x06,0x06,0x3c,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x00,0x0c,0x1c,0x3c,0x6c,0xcc,0xfe,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00,
0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xfc,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x60,0xc0,0xc0,0xfc,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x00,0xfe,0xc6,0x06,0x06,0x0c,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,
0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7c,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7e,0x06,0x06,0x06,0x0c,0x78,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x06,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x06,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x60,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x60,0x00,0x00,0x00,0x00,
0x00,0x00,0x7c,0xc6,0xc6,0x0c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xde,0xde,0xde,0xdc,0xc0,0x7c,0x00,0x00,0x00,0x00,
0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x66,0x66,0x66,0x66,0xfc,0x00,0x00,0x00,0x00,
0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x00,0x00,0x00,0x00,
0x00,0x00,0xf8,0x6c,0x66,0x66,0x66,0x66,0x66,0x66,0x6c,0xf8,0x00,0x00,0x00,0x00,
0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00,
0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xde,0xc6,0xc6,0x66,0x3a,0x00,0x00,0x00,0x00,
0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
0x00,0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
0x00,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00,
0x00,0x00,0xe6,0x66,0x66,0x6c,0x78,0x78,0x6c,0x66,0x66,0xe6,0x00,0x00,0x00,0x00,
0x00,0x00,0xf0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00,
0x00,0x00,0xc3,0xe7,0xff,0xff,0xdb,0xc3,0xc3,0xc3,0xc3,0xc3,0x00,0x00,0x00,0x00,
0x00,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xd6,0xde,0x7c,0x0c,0x0e,0x00,0x00,
0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x6c,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00,
0x00,0x00,0x7c,0xc6,0xc6,0x60,0x38,0x0c,0x06,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x00,0xff,0xdb,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x00,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0xc3,0xc3,0xc3,0xc3,0xc3,0xdb,0xdb,0xff,0x66,0x66,0x00,0x00,0x00,0x00,
0x00,0x00,0xc3,0xc3,0x66,0x3c,0x18,0x18,0x3c,0x66,0xc3,0xc3,0x00,0x00,0x00,0x00,
0x00,0x00,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
0x00,0x00,0xff,0xc3,0x86,0x0c,0x18,0x30,0x60,0xc1,0xc3,0xff,0x00,0x00,0x00,0x00,
0x00,0x00,0x3c,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3c,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x80,0xc0,0xe0,0x70,0x38,0x1c,0x0e,0x06,0x02,0x00,0x00,0x00,0x00,
0x00,0x00,0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,0x00,0x00,0x00,0x00,
0x10,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,
0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0xe0,0x60,0x60,0x78,0x6c,0x66,0x66,0x66,0x66,0x7c,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc0,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x00,0x1c,0x0c,0x0c,0x3c,0x6c,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0xcc,0x78,0x00,
0x00,0x00,0xe0,0x60,0x60,0x6c,0x76,0x66,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
0x00,0x00,0x06,0x06,0x00,0x0e,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00,
0x00,0x00,0xe0,0x60,0x60,0x66,0x6c,0x78,0x78,0x6c,0x66,0xe6,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xe6,0xff,0xdb,0xdb,0xdb,0xdb,0xdb,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xf0,0x00,
0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x1e,0x00,
0x00,0x00,0x00,0x00,0x00,0xdc,0x76,0x66,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0x60,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x00,0x10,0x30,0x30,0xfc,0x30,0x30,0x30,0x30,0x36,0x1c,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0xc3,0xdb,0xdb,0xff,0x66,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xc3,0x66,0x3c,0x18,0x3c,0x66,0xc3,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0xf8,0x00,
0x00,0x00,0x00,0x00,0x00,0xfe,0xcc,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00,
0x00,0x00,0x0e,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0e,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x70,0x18,0x18,0x18,0x0e,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00,
0x00,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xc6,0xfe,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x0c,0x06,0x7c,0x00,0x00,
0x00,0x00,0xcc,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
0x00,0x0c,0x18,0x30,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x10,0x38,0x6c,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0xcc,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
0x00,0x60,0x30,0x18,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
0x00,0x38,0x6c,0x38,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x3c,0x66,0x60,0x60,0x66,0x3c,0x0c,0x06,0x3c,0x00,0x00,0x00,
0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
0x00,0x18,0x3c,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
0x00,0xc6,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
0x38,0x6c,0x38,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
0x18,0x30,0x60,0x00,0xfe,0x66,0x60,0x7c,0x60,0x60,0x66,0xfe,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x6e,0x3b,0x1b,0x7e,0xd8,0xdc,0x77,0x00,0x00,0x00,0x00,
0x00,0x00,0x3e,0x6c,0xcc,0xcc,0xfe,0xcc,0xcc,0xcc,0xcc,0xce,0x00,0x00,0x00,0x00,
0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x30,0x78,0xcc,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
0x00,0x60,0x30,0x18,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0xc6,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0x78,0x00,
0x00,0xc6,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0xc6,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x18,0x18,0x7e,0xc3,0xc0,0xc0,0xc0,0xc3,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xe6,0xfc,0x00,0x00,0x00,0x00,
0x00,0x00,0xc3,0x66,0x3c,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0xfc,0x66,0x66,0x7c,0x62,0x66,0x6f,0x66,0x66,0x66,0xf3,0x00,0x00,0x00,0x00,
0x00,0x0e,0x1b,0x18,0x18,0x18,0x7e,0x18,0x18,0x18,0x18,0x18,0xd8,0x70,0x00,0x00,
0x00,0x18,0x30,0x60,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
0x00,0x0c,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
0x00,0x18,0x30,0x60,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x18,0x30,0x60,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0x76,0xdc,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
0x76,0xdc,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
0x00,0x3c,0x6c,0x6c,0x3e,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x38,0x6c,0x6c,0x38,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xc0,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00,
0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x60,0xce,0x9b,0x06,0x0c,0x1f,0x00,0x00,
0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x66,0xce,0x96,0x3e,0x06,0x06,0x00,0x00,
0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3c,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x36,0x6c,0xd8,0x6c,0x36,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xd8,0x6c,0x36,0x6c,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,
0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,
0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,
0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x3f,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x18,0x18,0x18,0x18,0x18,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x18,0x18,0x18,0x18,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,
0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0xd8,0xd8,0xd8,0xdc,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0x78,0xcc,0xcc,0xcc,0xd8,0xcc,0xc6,0xc6,0xc6,0xcc,0x00,0x00,0x00,0x00,
0x00,0x00,0xfe,0xc6,0xc6,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xfe,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xfe,0xc6,0x60,0x30,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7e,0xd8,0xd8,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xc0,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x76,0xdc,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x7e,0x18,0x3c,0x66,0x66,0x66,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0x6c,0x38,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x6c,0xc6,0xc6,0xc6,0x6c,0x6c,0x6c,0x6c,0xee,0x00,0x00,0x00,0x00,
0x00,0x00,0x1e,0x30,0x18,0x0c,0x3e,0x66,0x66,0x66,0x66,0x3c,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7e,0xdb,0xdb,0xdb,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x03,0x06,0x7e,0xdb,0xdb,0xf3,0x7e,0x60,0xc0,0x00,0x00,0x00,0x00,
0x00,0x00,0x1c,0x30,0x60,0x60,0x7c,0x60,0x60,0x60,0x30,0x1c,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0xff,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x00,0x7e,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x00,0x7e,0x00,0x00,0x00,0x00,
0x00,0x00,0x0e,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7e,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x38,0x6c,0x6c,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x0f,0x0c,0x0c,0x0c,0x0c,0x0c,0xec,0x6c,0x6c,0x3c,0x1c,0x00,0x00,0x00,0x00,
0x00,0xd8,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x70,0xd8,0x30,0x60,0xc8,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
static int default8x16FontMetaData[256*5+1]={
0,8,16,0,0,16,8,16,0,0,32,8,16,0,0,48,8,16,0,0,64,8,16,0,0,80,8,16,0,0,96,8,16,0,0,112,8,16,0,0,128,8,16,0,0,144,8,16,0,0,160,8,16,0,0,176,8,16,0,0,192,8,16,0,0,208,8,16,0,0,224,8,16,0,0,240,8,16,0,0,256,8,16,0,0,272,8,16,0,0,288,8,16,0,0,304,8,16,0,0,320,8,16,0,0,336,8,16,0,0,352,8,16,0,0,368,8,16,0,0,384,8,16,0,0,400,8,16,0,0,416,8,16,0,0,432,8,16,0,0,448,8,16,0,0,464,8,16,0,0,480,8,16,0,0,496,8,16,0,0,512,8,16,0,0,528,8,16,0,0,544,8,16,0,0,560,8,16,0,0,576,8,16,0,0,592,8,16,0,0,608,8,16,0,0,624,8,16,0,0,640,8,16,0,0,656,8,16,0,0,672,8,16,0,0,688,8,16,0,0,704,8,16,0,0,720,8,16,0,0,736,8,16,0,0,752,8,16,0,0,768,8,16,0,0,784,8,16,0,0,800,8,16,0,0,816,8,16,0,0,832,8,16,0,0,848,8,16,0,0,864,8,16,0,0,880,8,16,0,0,896,8,16,0,0,912,8,16,0,0,928,8,16,0,0,944,8,16,0,0,960,8,16,0,0,976,8,16,0,0,992,8,16,0,0,1008,8,16,0,0,1024,8,16,0,0,1040,8,16,0,0,1056,8,16,0,0,1072,8,16,0,0,1088,8,16,0,0,1104,8,16,0,0,1120,8,16,0,0,1136,8,16,0,0,1152,8,16,0,0,1168,8,16,0,0,1184,8,16,0,0,1200,8,16,0,0,1216,8,16,0,0,1232,8,16,0,0,1248,8,16,0,0,1264,8,16,0,0,1280,8,16,0,0,1296,8,16,0,0,1312,8,16,0,0,1328,8,16,0,0,1344,8,16,0,0,1360,8,16,0,0,1376,8,16,0,0,1392,8,16,0,0,1408,8,16,0,0,1424,8,16,0,0,1440,8,16,0,0,1456,8,16,0,0,1472,8,16,0,0,1488,8,16,0,0,1504,8,16,0,0,1520,8,16,0,0,1536,8,16,0,0,1552,8,16,0,0,1568,8,16,0,0,1584,8,16,0,0,1600,8,16,0,0,1616,8,16,0,0,1632,8,16,0,0,1648,8,16,0,0,1664,8,16,0,0,1680,8,16,0,0,1696,8,16,0,0,1712,8,16,0,0,1728,8,16,0,0,1744,8,16,0,0,1760,8,16,0,0,1776,8,16,0,0,1792,8,16,0,0,1808,8,16,0,0,1824,8,16,0,0,1840,8,16,0,0,1856,8,16,0,0,1872,8,16,0,0,1888,8,16,0,0,1904,8,16,0,0,1920,8,16,0,0,1936,8,16,0,0,1952,8,16,0,0,1968,8,16,0,0,1984,8,16,0,0,2000,8,16,0,0,2016,8,16,0,0,2032,8,16,0,0,2048,8,16,0,0,2064,8,16,0,0,2080,8,16,0,0,2096,8,16,0,0,2112,8,16,0,0,2128,8,16,0,0,2144,8,16,0,0,2160,8,16,0,0,2176,8,16,0,0,2192,8,16,0,0,2208,8,16,0,0,2224,8,16,0,0,2240,8,16,0,0,2256,8,16,0,0,2272,8,16,0,0,2288,8,16,0,0,2304,8,16,0,0,2320,8,16,0,0,2336,8,16,0,0,2352,8,16,0,0,2368,8,16,0,0,2384,8,16,0,0,2400,8,16,0,0,2416,8,16,0,0,2432,8,16,0,0,2448,8,16,0,0,2464,8,16,0,0,2480,8,16,0,0,2496,8,16,0,0,2512,8,16,0,0,2528,8,16,0,0,2544,8,16,0,0,2560,8,16,0,0,2576,8,16,0,0,2592,8,16,0,0,2608,8,16,0,0,2624,8,16,0,0,2640,8,16,0,0,2656,8,16,0,0,2672,8,16,0,0,2688,8,16,0,0,2704,8,16,0,0,2720,8,16,0,0,2736,8,16,0,0,2752,8,16,0,0,2768,8,16,0,0,2784,8,16,0,0,2800,8,16,0,0,2816,8,16,0,0,2832,8,16,0,0,2848,8,16,0,0,2864,8,16,0,0,2880,8,16,0,0,2896,8,16,0,0,2912,8,16,0,0,2928,8,16,0,0,2944,8,16,0,0,2960,8,16,0,0,2976,8,16,0,0,2992,8,16,0,0,3008,8,16,0,0,3024,8,16,0,0,3040,8,16,0,0,3056,8,16,0,0,3072,8,16,0,0,3088,8,16,0,0,3104,8,16,0,0,3120,8,16,0,0,3136,8,16,0,0,3152,8,16,0,0,3168,8,16,0,0,3184,8,16,0,0,3200,8,16,0,0,3216,8,16,0,0,3232,8,16,0,0,3248,8,16,0,0,3264,8,16,0,0,3280,8,16,0,0,3296,8,16,0,0,3312,8,16,0,0,3328,8,16,0,0,3344,8,16,0,0,3360,8,16,0,0,3376,8,16,0,0,3392,8,16,0,0,3408,8,16,0,0,3424,8,16,0,0,3440,8,16,0,0,3456,8,16,0,0,3472,8,16,0,0,3488,8,16,0,0,3504,8,16,0,0,3520,8,16,0,0,3536,8,16,0,0,3552,8,16,0,0,3568,8,16,0,0,3584,8,16,0,0,3600,8,16,0,0,3616,8,16,0,0,3632,8,16,0,0,3648,8,16,0,0,3664,8,16,0,0,3680,8,16,0,0,3696,8,16,0,0,3712,8,16,0,0,3728,8,16,0,0,3744,8,16,0,0,3760,8,16,0,0,3776,8,16,0,0,3792,8,16,0,0,3808,8,16,0,0,3824,8,16,0,0,3840,8,16,0,0,3856,8,16,0,0,3872,8,16,0,0,3888,8,16,0,0,3904,8,16,0,0,3920,8,16,0,0,3936,8,16,0,0,3952,8,16,0,0,3968,8,16,0,0,3984,8,16,0,0,4000,8,16,0,0,4016,8,16,0,0,4032,8,16,0,0,4048,8,16,0,0,4064,8,16,0,0,4080,8,16,0,0,};
static rfbFontData default8x16Font = { default8x16FontData, default8x16FontMetaData };

View File

@ -0,0 +1,799 @@
#include <assert.h>
#include <string.h>
#include <rfb/rfb.h>
#include <rfb/rfbclient.h>
#include "nacro.h"
/* for visual grepping */
typedef struct image_t {
int width,height;
char* buffer;
} image_t;
/* this is a VNC connection */
typedef struct private_resource_t {
int listen_port;
rfbScreenInfo* server;
rfbClient* client;
uint32_t keysym;
rfbBool keydown;
int x,y;
int buttons;
char* text_client;
char* text_server;
image_t* grep_image;
int x_origin,y_origin;
enum { SLEEP,VISUALGREP,WAITFORUPDATE } state;
result_t result;
} private_resource_t;
/* resource management */
#define MAX_RESOURCE_COUNT 20
static private_resource_t resource_pool[MAX_RESOURCE_COUNT];
static int resource_count=0;
static private_resource_t* get_resource(int resource)
{
if(resource>=MAX_RESOURCE_COUNT || resource<0 || resource_pool[resource].client==0)
return NULL;
return resource_pool+resource;
}
static private_resource_t* get_next_resource(void)
{
if(resource_count<MAX_RESOURCE_COUNT) {
memset(resource_pool+resource_count,0,sizeof(private_resource_t));
resource_count++;
return resource_pool+resource_count-1;
} else {
int i;
for(i=0;i<MAX_RESOURCE_COUNT && resource_pool[i].client;i++);
if(i<MAX_RESOURCE_COUNT)
return resource_pool+i;
}
return NULL;
}
static void free_resource(int resource)
{
private_resource_t* res=get_resource(resource);
if(res)
res->client=NULL;
}
/* hooks */
static void got_key(rfbBool down,rfbKeySym keysym,rfbClientRec* cl)
{
private_resource_t* res=(private_resource_t*)cl->screen->screenData;
res->keydown=down;
res->keysym=keysym;
res->result|=RESULT_KEY;
}
static void got_mouse(int buttons,int x,int y,rfbClientRec* cl)
{
private_resource_t* res=(private_resource_t*)cl->screen->screenData;
res->buttons=buttons;
res->x=x;
res->y=y;
res->result|=RESULT_MOUSE;
}
static void got_text(char* str,int len,rfbClientRec* cl)
{
private_resource_t* res=(private_resource_t*)cl->screen->screenData;
if (res->text_client)
free(res->text_client);
res->text_client=strdup(str);
res->result|=RESULT_TEXT_CLIENT;
}
static void got_text_from_server(rfbClient* cl, const char *str, int textlen)
{
private_resource_t* res=(private_resource_t*)cl->clientData;
if (res->text_server)
free(res->text_server);
res->text_server=strdup(str);
res->result|=RESULT_TEXT_SERVER;
}
static rfbBool malloc_frame_buffer(rfbClient* cl)
{
private_resource_t* res=(private_resource_t*)cl->clientData;
if(!res->server) {
int w=cl->width,h=cl->height;
res->client->frameBuffer=malloc(w*4*h);
res->server=rfbGetScreen(NULL,NULL,w,h,8,3,4);
res->server->screenData=res;
res->server->port=res->listen_port;
res->server->frameBuffer=res->client->frameBuffer;
res->server->kbdAddEvent=got_key;
res->server->ptrAddEvent=got_mouse;
res->server->setXCutText=got_text;
rfbInitServer(res->server);
} else {
/* TODO: realloc if necessary */
/* TODO: resolution change: send NewFBSize */
/* TODO: if the origin is out of bounds, reset to 0 */
}
}
static bool_t do_visual_grep(private_resource_t* res,int x,int y,int w,int h)
{
rfbClient* cl;
image_t* image;
int x_start,y_start,x_end=x+w-1,y_end=y+h-1;
bool_t found=0;
if(res==0 || (cl=res->client)==0 || (image=res->grep_image)==0)
return 0;
x_start=x-image->width;
y_start=y-image->height;
if(x_start<0) x_start=0;
if(y_start<0) y_start=0;
if(x_end+image->width>cl->width) x_end=cl->width-image->width;
if(y_end+image->height>cl->height) y_end=cl->height-image->height;
/* find image and set x_origin,y_origin if found */
for(y=y_start;y<y_end;y++)
for(x=x_start;x<x_end;x++) {
bool_t matching=1;
int i,j;
for(j=0;matching && j<image->height;j++)
for(i=0;matching && i<image->width;i++)
if(memcmp(cl->frameBuffer+4*(x+i+cl->width*(y+j)),image->buffer+4*(i+image->width*j),3))
matching=0;
if(matching) {
private_resource_t* res=(private_resource_t*)cl->clientData;
res->x_origin=x;
res->y_origin=y;
return -1;
}
}
return 0;
}
static void got_frame_buffer(rfbClient* cl,int x,int y,int w,int h)
{
private_resource_t* res=(private_resource_t*)cl->clientData;
assert(res->server);
if(res->grep_image && do_visual_grep(res,x,y,w,h)) {
res->result|=RESULT_FOUNDIMAGE;
}
if(res->server) {
rfbMarkRectAsModified(res->server,x,y,x+w,y+h);
}
res->result|=RESULT_SCREEN;
}
/* init/shutdown functions */
resource_t initvnc(const char* server,int server_port,int listen_port)
{
private_resource_t* res=get_next_resource();
int dummy=0;
if(res==0)
return -1;
/* remember for later */
res->listen_port=listen_port;
res->text_client = NULL;
res->text_server = NULL;
res->client=rfbGetClient(8,3,4);
res->client->clientData=(void*)res;
res->client->GotFrameBufferUpdate=got_frame_buffer;
res->client->MallocFrameBuffer=malloc_frame_buffer;
res->client->GotXCutText=got_text_from_server;
res->client->serverHost=strdup(server);
res->client->serverPort=server_port;
res->client->appData.encodingsString="raw";
if(!rfbInitClient(res->client,&dummy,NULL)) {
res->client=NULL;
return -1;
}
return res-resource_pool;
}
void closevnc(resource_t resource)
{
private_resource_t* res=get_resource(resource);
if(res==0)
return;
if(res->server)
rfbScreenCleanup(res->server);
assert(res->client);
rfbClientCleanup(res->client);
res->client=NULL;
}
/* PNM (image) helpers */
bool_t savepnm(resource_t resource,const char* filename,int x1,int y1,int x2,int y2)
{
private_resource_t* res=get_resource(resource);
int i,j,w,h;
uint32_t* buffer;
FILE* f;
if(res==0 || res->client==0)
return 0;
assert(res->client->format.depth==24);
w=res->client->width;
h=res->client->height;
buffer=(uint32_t*)res->client->frameBuffer;
if(res==0 || x1>x2 || y1>y2 || x1<0 || x2>=w || y1<0 || y2>=h)
return FALSE;
f=fopen(filename,"wb");
if(f==0)
return FALSE;
fprintf(f,"P6\n%d %d\n255\n",1+x2-x1,1+y2-y1);
for(j=y1;j<=y2;j++)
for(i=x1;i<=x2;i++) {
fwrite(buffer+i+j*w,3,1,f);
}
if(fclose(f))
return FALSE;
return TRUE;
}
static image_t* loadpnm(const char* filename)
{
FILE* f=fopen(filename,"rb");
char buffer[1024];
int i,j,w,h;
image_t* image;
if(f==0)
return NULL;
if(!fgets(buffer,1024,f) || strcmp("P6\n",buffer)) {
fclose(f);
return NULL;
}
do {
fgets(buffer,1024,f);
if(feof(f)) {
fclose(f);
return NULL;
}
} while(buffer[0]=='#');
if( sscanf(buffer,"%d %d",&w,&h)!=2
|| !fgets(buffer,1024,f) || strcmp("255\n",buffer)) {
fclose(f);
return NULL;
}
image=(image_t*)malloc(sizeof(image_t));
image->width=w;
image->height=h;
image->buffer=malloc(w*4*h);
if(!image->buffer) {
fclose(f);
free(image);
return NULL;
}
for(j=0;j<h;j++)
for(i=0;i<w;i++)
if(fread(image->buffer+4*(i+w*j),3,1,f)!=1) {
fprintf(stderr,"Could not read 3 bytes at %d,%d\n",i,j);
fclose(f);
free(image->buffer);
free(image);
return NULL;
}
fclose(f);
return image;
}
static void free_image(image_t* image)
{
if(image->buffer)
free(image->buffer);
free(image);
}
static void copy_line(rfbScreenInfo *dest, char *backup,
int x0, int y0, int x1, int y1, int color_offset)
{
uint8_t *d = (uint8_t *)dest->frameBuffer, *s = (uint8_t *)backup;
int i;
int steps0 = x1 > x0 ? x1 - x0 : x0 - x1;
int steps1 = y1 > y0 ? y1 - y0 : y0 - y1;
if (steps1 > steps0)
steps0 = steps1;
else if (steps0 == 0)
steps0 = 1;
for (i = 0; i <= steps0; i++) {
int j, index = 4 * (x0 + i * (x1 - x0) / steps0
+ dest->width * (y0 + i * (y1 - y0) / steps0));
for (j = 0; j < 4; j++)
d[index + j] = s[index + j] + color_offset;
}
rfbMarkRectAsModified(dest, x0 - 5, y0 - 5, x1 + 1, y1 + 2);
}
result_t displaypnm(resource_t resource, const char *filename,
coordinate_t x, coordinate_t y, bool_t border,
timeout_t timeout_in_seconds)
{
private_resource_t* res = get_resource(resource);
image_t *image;
char* fake_frame_buffer;
char* backup;
int w, h, i, j, w2, h2;
result_t result;
if (res == NULL || res->server == NULL ||
(image = loadpnm(filename)) == NULL)
return 0;
w = res->server->width;
h = res->server->height;
fake_frame_buffer = malloc(w * 4 * h);
if(!fake_frame_buffer)
return 0;
memcpy(fake_frame_buffer, res->server->frameBuffer, w * 4 * h);
backup = res->server->frameBuffer;
res->server->frameBuffer = fake_frame_buffer;
w2 = image->width;
if (x + w2 > w)
w2 = w - x;
h2 = image->height;
if (y + h2 > h)
h2 = h - y;
for (j = 0; j < h2; j++)
memcpy(fake_frame_buffer + 4 * (x + (y + j) * w),
image->buffer + j * 4 * image->width, 4 * w2);
free(image);
if (border) {
copy_line(res->server, backup, x, y, x + w2, y, 0x80);
copy_line(res->server, backup, x, y, x, y + h2, 0x80);
copy_line(res->server, backup, x + w2, y, x + w2, y + h2, 0x80);
copy_line(res->server, backup, x, y + h2, x + w2, y + h2, 0x80);
}
rfbMarkRectAsModified(res->server,
x - 1, y - 1, x + w2 + 1, y + h2 + 1);
result = waitforinput(resource, timeout_in_seconds);
res->server->frameBuffer=backup;
free(fake_frame_buffer);
rfbMarkRectAsModified(res->server,
x - 1, y - 1, x + w2 + 1, y + h2 + 1);
return result;
}
/* process() and friends */
/* this function returns only if res->result in return_mask */
static result_t private_process(resource_t resource,timeout_t timeout_in_seconds,result_t return_mask)
{
private_resource_t* res=get_resource(resource);
fd_set fds;
struct timeval tv,tv_start,tv_end;
unsigned long timeout=(unsigned long)(timeout_in_seconds*1000000UL);
int count,max_fd;
if(res==0)
return 0;
assert(res->client);
gettimeofday(&tv_start,NULL);
res->result=0;
do {
unsigned long timeout_done;
if(res->server) {
rfbBool loop;
do {
loop=rfbProcessEvents(res->server,res->server->deferUpdateTime);
} while(loop && (res->result&return_mask)==0
&& rfbIsActive(res->server));
if(!rfbIsActive(res->server))
return RESULT_SHUTDOWN;
if((res->result&return_mask)!=0)
return res->result;
memcpy((char*)&fds,(const char*)&(res->server->allFds),sizeof(fd_set));
max_fd=res->server->maxFd;
} else {
FD_ZERO(&fds);
max_fd=0;
}
FD_SET(res->client->sock,&fds);
if(res->client->sock>max_fd)
max_fd=res->client->sock;
gettimeofday(&tv_end,NULL);
timeout_done=tv_end.tv_usec-tv_start.tv_usec+
1000000L*(tv_end.tv_sec-tv_start.tv_sec);
if(timeout_done>=timeout)
return RESULT_TIMEOUT;
tv.tv_usec=((timeout-timeout_done)%1000000);
tv.tv_sec=(timeout-timeout_done)/1000000;
count=select(max_fd+1,&fds,NULL,NULL,&tv);
if(count<0)
return 0;
if(count>0) {
if(FD_ISSET(res->client->sock,&fds)) {
if(!HandleRFBServerMessage(res->client)) {
closevnc(resource);
return 0;
}
if((res->result&return_mask)!=0)
return res->result;
}
} else {
res->result|=RESULT_TIMEOUT;
return res->result;
}
} while(1);
return RESULT_TIMEOUT;
}
result_t process(resource_t res,timeout_t timeout)
{
return private_process(res,timeout,RESULT_TIMEOUT);
}
result_t waitforanything(resource_t res,timeout_t timeout)
{
return private_process(res,timeout,-1);
}
result_t waitforinput(resource_t res,timeout_t timeout)
{
return private_process(res,timeout,RESULT_KEY|RESULT_MOUSE|RESULT_TIMEOUT);
}
result_t waitforupdate(resource_t res,timeout_t timeout)
{
return private_process(res,timeout,RESULT_SCREEN|RESULT_TIMEOUT);
}
result_t visualgrep(resource_t resource,const char* filename,timeout_t timeout)
{
private_resource_t* res=get_resource(resource);
image_t* image;
result_t result;
if(res==0 || res->client==0)
return 0;
/* load filename and set res->grep_image to this image */
image=loadpnm(filename);
if(image==0)
return 0;
if(res->grep_image)
free_image(res->grep_image);
res->grep_image=image;
if(do_visual_grep(res,0,0,res->client->width,res->client->height))
return RESULT_FOUNDIMAGE;
result=private_process(resource,timeout,RESULT_FOUNDIMAGE|RESULT_TIMEOUT);
/* free image */
if(res->grep_image) {
free_image(res->grep_image);
res->grep_image=NULL;
}
return result;
}
/* auxiliary function for alert */
#include "default8x16.h"
static void center_text(rfbScreenInfo* screen,const char* message,int* x,int* y,int* w,int* h)
{
rfbFontData* font=&default8x16Font;
const char* pointer;
int j,x1,y1,x2,y2,line_count=0;
if(message==0 || screen==0)
return;
rfbWholeFontBBox(font,&x1,&y1,&x2,&y2);
for(line_count=1,pointer=message;*pointer;pointer++)
if(*pointer=='\n')
line_count++;
*h=(y2-y1)*line_count;
assert(*h>0);
if(*h>screen->height)
*h=screen->height;
*x=0; *w=screen->width; *y=(screen->height-*h)/2;
rfbFillRect(screen,*x,*y,*x+*w,*y+*h,0xff0000);
for(pointer=message,j=0;j<line_count;j++) {
const char* eol;
int x_cur,y_cur=*y-y1+j*(y2-y1),width;
for(width=0,eol=pointer;*eol && *eol!='\n';eol++)
width+=rfbWidthOfChar(font,*eol);
if(width>screen->width)
width=screen->width;
x_cur=(screen->width-width)/2;
for(;pointer!=eol;pointer++)
x_cur+=rfbDrawCharWithClip(screen,font,
x_cur,y_cur,*pointer,
0,0,screen->width,screen->height,
0xffffffff,0xffffffff);
pointer++;
}
rfbMarkRectAsModified(screen,*x,*y,*x+*w,*y+*h);
}
/* this is an overlay which is shown for a certain time */
result_t alert(resource_t resource,const char* message,timeout_t timeout)
{
private_resource_t* res=get_resource(resource);
char* fake_frame_buffer;
char* backup;
int x,y,w,h;
result_t result;
if(res == NULL || res->server==NULL)
return -1;
w=res->server->width;
h=res->server->height;
fake_frame_buffer=malloc(w*4*h);
if(!fake_frame_buffer)
return -1;
memcpy(fake_frame_buffer,res->server->frameBuffer,w*4*h);
backup=res->server->frameBuffer;
res->server->frameBuffer=fake_frame_buffer;
center_text(res->server,message,&x,&y,&w,&h);
fprintf(stderr,"%s\n",message);
result=waitforinput(resource,timeout);
res->server->frameBuffer=backup;
free(fake_frame_buffer);
rfbMarkRectAsModified(res->server,x,y,x+w,y+h);
return result;
}
/* inspect last events */
keysym_t getkeysym(resource_t res)
{
private_resource_t* r=get_resource(res);
return r->keysym;
}
bool_t getkeydown(resource_t res)
{
private_resource_t* r=get_resource(res);
return r->keydown;
}
coordinate_t getx(resource_t res)
{
private_resource_t* r=get_resource(res);
return r->x;
}
coordinate_t gety(resource_t res)
{
private_resource_t* r=get_resource(res);
return r->y;
}
buttons_t getbuttons(resource_t res)
{
private_resource_t* r=get_resource(res);
return r->buttons;
}
const char *gettext_client(resource_t res)
{
private_resource_t* r=get_resource(res);
return r->text_client;
}
result_t rubberband(resource_t resource, coordinate_t x0, coordinate_t y0)
{
private_resource_t* res=get_resource(resource);
char* fake_frame_buffer;
char* backup;
int w, h, x, y;
if(res == NULL || res->server==NULL)
return -1;
x = res->x;
y = res->y;
w = res->server->width;
h = res->server->height;
fake_frame_buffer = malloc(w * 4 * h);
if(!fake_frame_buffer)
return 0;
memcpy(fake_frame_buffer, res->server->frameBuffer, w * 4 * h);
backup = res->server->frameBuffer;
res->server->frameBuffer = fake_frame_buffer;
while (res->buttons) {
result_t r = waitforinput(resource, 1000000L);
if (x == res->x && y == res->y)
continue;
copy_line(res->server, backup, x0, y0, x, y0, 0);
copy_line(res->server, backup, x0, y0, x0, y, 0);
copy_line(res->server, backup, x, y0, x, y, 0);
copy_line(res->server, backup, x0, y, x, y, 0);
x = res->x;
y = res->y;
copy_line(res->server, backup, x0, y0, x, y0, 0x80);
copy_line(res->server, backup, x0, y0, x0, y, 0x80);
copy_line(res->server, backup, x, y0, x, y, 0x80);
copy_line(res->server, backup, x0, y, x, y, 0x80);
}
copy_line(res->server, backup, x0, y0, x, y0, 0);
copy_line(res->server, backup, x0, y0, x0, y, 0);
copy_line(res->server, backup, x, y0, x, y, 0);
copy_line(res->server, backup, x0, y, x, y, 0);
res->server->frameBuffer=backup;
free(fake_frame_buffer);
return RESULT_MOUSE;
}
const char *gettext_server(resource_t res)
{
private_resource_t* r=get_resource(res);
return r->text_server;
}
/* send events to the server */
bool_t sendkey(resource_t res,keysym_t keysym,bool_t keydown)
{
private_resource_t* r=get_resource(res);
if(r==NULL)
return 0;
return SendKeyEvent(r->client,keysym,keydown);
}
bool_t sendascii(resource_t res,const char *string)
{
timeout_t delay = 0.1;
private_resource_t* r=get_resource(res);
int i;
if(r==NULL)
return 0;
while (*string) {
int keysym = *string;
int need_shift = 0;
if (keysym >= 8 && keysym < ' ')
keysym += 0xff00;
else if (keysym >= 'A' && keysym <= 'Z')
need_shift = 1;
else if (keysym > '~') {
fprintf(stderr, "String contains non-ASCII "
"character 0x%02x\n", *string);
return FALSE;
}
if (need_shift) {
if (!SendKeyEvent(r->client,0xffe1,1))
return FALSE;
waitforinput(r,delay);
}
for (i = 1; i >= 0; i--) {
if (!SendKeyEvent(r->client,keysym,i))
return FALSE;
waitforinput(r,delay);
}
if (need_shift) {
if (!SendKeyEvent(r->client,0xffe1,0))
return FALSE;
waitforinput(r,delay);
}
string++;
}
return TRUE;
}
bool_t sendmouse(resource_t res,coordinate_t x,coordinate_t y,buttons_t buttons)
{
private_resource_t* r=get_resource(res);
if(r==NULL)
return 0;
return SendPointerEvent(r->client,x,y,buttons);
}
bool_t sendtext(resource_t res, const char *string)
{
private_resource_t* r=get_resource(res);
if(r==NULL)
return 0;
return SendClientCutText(r->client, (char *)string, (int)strlen(string));
}
bool_t sendtext_to_server(resource_t res, const char *string)
{
private_resource_t* r=get_resource(res);
if(r==NULL)
return 0;
rfbSendServerCutText(r->server, (char *)string, (int)strlen(string));
return 1;
}
/* for visual grepping */
coordinate_t getxorigin(resource_t res)
{
private_resource_t* r=get_resource(res);
return r->x_origin;
}
coordinate_t getyorigin(resource_t res)
{
private_resource_t* r=get_resource(res);
return r->y_origin;
}

View File

@ -0,0 +1,120 @@
#ifndef NACRO_H
#define NACRO_H
#ifdef SWIG
%module nacro
%{
/* types used */
/* 0=false, every other value=true */
typedef int bool_t;
/* a keysym: identical with ASCII for values between 0-127 */
typedef int keysym_t;
/* this can be negative, because of a new origin set via visual grep */
typedef int coordinate_t;
/* left button is 1<<0, middle button is 1<<1, right button is 1<<2 */
typedef unsigned char buttons_t;
/* this is sort of a "file descriptor" for the proxy */
typedef int resource_t;
/* the timeout, specified in microseconds, for process() and friends */
typedef double timeout_t;
/* the return values of process() and friends */
typedef int result_t;
/*
%constant int RESULT_TIMEOUT=1;
%constant int RESULT_KEY=2;
%constant int RESULT_MOUSE=4;
%constant int RESULT_TEXT_CLIENT=8;
%constant int RESULT_TEXT_CLIENT=16;
%constant int RESULT_SCREEN=32;
%constant int RESULT_FOUNDIMAGE=64;
%constant int RESULT_SHUTDOWN=128;
*/
%}
#endif // SWIG
typedef int bool_t;
typedef int keysym_t;
typedef int coordinate_t;
typedef unsigned char buttons_t;
typedef int resource_t;
typedef double timeout_t;
typedef int result_t;
#define RESULT_TIMEOUT 1
#define RESULT_KEY 2
#define RESULT_MOUSE 4
#define RESULT_TEXT_CLIENT 8
#define RESULT_TEXT_SERVER 16
#define RESULT_SCREEN 32
#define RESULT_FOUNDIMAGE 64
#define RESULT_SHUTDOWN 128
/* init/shutdown */
resource_t initvnc(const char* server,int serverPort,int listenPort);
void closevnc(resource_t res);
/* run the event loop for a while: process() and friends:
* process() returns only on timeout,
* waitforanything returns on any event (input, output or timeout),
* waitforupdate() returns only on timeout or screen update,
* waitforinput() returns only on timeout or user input,
* visualgrep() returns only on timeout or if the specified PNM was found
* (in that case, x_origin and y_origin are set to the upper left
* corner of the matched image). */
result_t process(resource_t res,timeout_t seconds);
result_t waitforanything(resource_t res,timeout_t seconds);
result_t waitforupdate(resource_t res,timeout_t seconds);
result_t waitforinput(resource_t res,timeout_t seconds);
result_t visualgrep(resource_t res,const char* filename,timeout_t seconds);
/* inspect last events */
keysym_t getkeysym(resource_t res);
bool_t getkeydown(resource_t res);
coordinate_t getx(resource_t res);
coordinate_t gety(resource_t res);
buttons_t getbuttons(resource_t res);
const char *gettext_client(resource_t res);
const char *gettext_server(resource_t res);
/* send events to the server */
bool_t sendkey(resource_t res,keysym_t keysym,bool_t keydown);
bool_t sendascii(resource_t res,const char *string);
bool_t sendmouse(resource_t res,coordinate_t x,coordinate_t y,buttons_t buttons);
bool_t sendtext(resource_t res, const char *string);
bool_t sendtext_to_server(resource_t res, const char *string);
/* for visual grepping */
coordinate_t getxorigin(resource_t res);
coordinate_t getyorigin(resource_t res);
bool_t savepnm(resource_t res,const char* filename,coordinate_t x1, coordinate_t y1, coordinate_t x2, coordinate_t y2);
result_t displaypnm(resource_t res, const char *filename, coordinate_t x, coordinate_t y, bool_t border, timeout_t timeout);
/* this displays an overlay which is shown for a certain time */
result_t alert(resource_t res,const char* message,timeout_t timeout);
/* display a rectangular rubber band between (x0, y0) and the current
mouse pointer, as long as a button us pressed. */
result_t rubberband(resource_t res, coordinate_t x0, coordinate_t y0);
#endif

View File

@ -0,0 +1,282 @@
#!/usr/bin/perl
use Getopt::Long;
use nacro;
$output="my_script";
$server="localhost";
$port=5900;
$listen_port=5923;
$timing=0;
$symbolic=0;
$compact=0;
$compact_dragging=0;
if(!GetOptions(
"script:s" => \$output,
"listen:i" => \$listen_port,
"timing" => \$timing,
"symbolic" => \$symbolic,
"compact" => \$compact,
"compact-dragging" => \$compact_dragging,
) || $#ARGV!=0) {
print STDERR "Usage: $ARGV0 [--script output_name] [--listen listen_port] [--timing]\n\t[--symbolic] [--compact] [--compact-dragging] server[:port]\n";
exit 2;
}
$output=~s/\.pl$//;
if ($timing) {
eval 'use Time::HiRes';
$timing=0 if $@;
$starttime=-1;
}
if ($symbolic) {
eval 'use X11::Keysyms qw(%Keysyms)';
$symbolic=0 if $@;
%sym_name = reverse %Keysyms;
}
$server=$ARGV[0];
if($server=~/^(.*):(\d+)$/) {
$server=$1;
$port=$2;
if($2<100) {
$port+=5900;
}
}
if($listen_port<100) {
$listen_port+=5900;
}
# do not overwrite script
if(stat("$output.pl")) {
print STDERR "Will not overwrite $output.pl\n";
exit 2;
}
# start connection
$vnc=nacro::initvnc($server,$port,$listen_port);
if($vnc<0) {
print STDERR "Could not initialize $server:$port\n";
exit 1;
}
open OUT, ">$output.pl";
print OUT "#!/usr/bin/perl\n";
print OUT "\n";
if ($symbolic) {
print OUT "use X11::Keysyms qw(\%sym);\n";
}
print OUT "use nacro;\n";
print OUT "\n";
print OUT "\$x_origin=0; \$y_origin=0;\n";
print OUT "\$vnc=nacro::initvnc(\"$server\",$port,$listen_port);\n";
$mode="passthru";
$image_counter=1;
$magickey=0;
$x_origin=0; $y_origin=0;
sub writetiming () {
if ($timing) {
$now=Time::HiRes::time();
if ($starttime>0) {
print OUT "nacro::process(\$vnc," . ($now - $starttime) . ");\n";
}
$starttime=$now;
}
}
$last_button = -1;
sub handle_mouse {
my $x = shift;
my $y = shift;
my $buttons = shift;
if(nacro::sendmouse($vnc,$x,$y,$buttons)) {
$x-=$x_origin; $y-=$y_origin;
writetiming();
print OUT "nacro::sendmouse(\$vnc,\$x_origin"
. ($x>=0?"+":"")."$x,\$y_origin"
. ($y>=0?"+":"")."$y,$buttons);\n";
}
}
sub toggle_text {
my $text = shift;
if ($text eq "Timing") {
return $text . " is " . ($timing ? "on" : "off");
} elsif ($text eq "Key presses") {
return $text . " are recorded " . ($symbolic ? "symbolically"
: "numerically");
} elsif ($text eq "Mouse moves") {
return $text . " are recorded " . ($compact ? "compacted"
: "verbosely");
} elsif ($text eq "Mouse drags") {
return $text . " are recorded " . ($compact ? "compacted"
: "verbosely");
}
return $text . ": <unknown>";
}
$menu_message = "VisualNaCro: press 'q' to quit,\n"
. "'i' to display current settings,\n"
. "'c', 'r' to toggle compact mouse movements or drags,\n"
. "'d' to display current reference image,\n"
. "or mark reference rectangle by dragging";
while(1) {
$result=nacro::waitforinput($vnc,999999);
if($result==0) {
# server went away
close OUT;
exit 0;
}
if($mode eq "passthru") {
if($result&$nacro::RESULT_KEY) {
$keysym=nacro::getkeysym($vnc);
$keydown=nacro::getkeydown($vnc);
if(nacro::sendkey($vnc,$keysym,$keydown)) {
writetiming();
if ($symbolic and exists $sym_name{$keysym}) {
print OUT 'nacro::sendkey($vnc,$sym{'.$sym_name{$keysym}."},$keydown);\n";
} else {
print OUT "nacro::sendkey(\$vnc,$keysym,$keydown);\n";
}
}
if($keysym==0xffe3 || $keysym==0xffe4) {
if (!$keydown) {
# Control pressed
$magickey++;
if ($magickey > 1) {
$magickey = 0;
$mode = "menu";
nacro::alert($vnc,
$menu_message, 10);
}
}
} else {
$magickey=0;
}
}
if($result&$nacro::RESULT_MOUSE) {
$x=nacro::getx($vnc);
$y=nacro::gety($vnc);
$buttons=nacro::getbuttons($vnc);
if ($buttons != $last_buttons) {
if (!$buttons && $compact_dragging) {
handle_mouse($x, $y, $last_buttons);
}
$last_buttons = $buttons;
} else {
if (($buttons && $compact_dragging) ||
(!$buttons && $compact)) {
next;
}
}
handle_mouse($x, $y, $buttons);
}
if ($result & $nacro::RESULT_TEXT_CLIENT) {
my $text = nacro::gettext_client($vnc);
if (nacro::sendtext($vnc,$text)) {
writetiming();
print OUT "nacro::sendtext(\$vnc, q(\Q$text\E));\n";
print "got text from client: $text\n";
}
}
if ($result & $nacro::RESULT_TEXT_SERVER) {
my $text = nacro::gettext_server($vnc);
if (nacro::sendtext_to_server($vnc,$text)) {
writetiming();
print OUT "nacro::sendtext_to_server(\$vnc, q(\Q$text\E));\n";
print "got text from server: $text\n";
}
}
} else {
if($result&$nacro::RESULT_KEY) {
$keysym=nacro::getkeysym($vnc);
$keydown=nacro::getkeydown($vnc);
if($keysym==ord('q')) {
# shutdown
close OUT;
nacro::closevnc($vnc);
exit 0;
} elsif ($keysym == ord('d')) {
$pnm=$output.($image_counter - 1).".pnm";
$res = nacro::displaypnm($vnc, $pnm,
$x_origin, $y_origin, 1, 10);
#0, 0, 1, 10);
if ($res == 0) {
nacro::alert($vnc, "Error displaying "
. $pnm, 10);
}
} elsif ($keysym == ord('i')) {
nacro::alert($vnc, "Current settings:\n"
. "\n"
. "Script: $output\n"
. "Server: $server\n"
. "Listening on port: $port\n"
. toggle_text("Timing") . "\n"
. toggle_text("Key presses") . "\n"
. toggle_text("Mouse moves") . "\n"
. toggle_text("Mouse drags"), 10);
} elsif ($keysym == ord('c')) {
$compact = !$compact;
nacro::alert($vnc,
toggle_text("Mouse moves"), 10);
} elsif ($keysym == ord('r')) {
$compact_dragging = !$compact_dragging;
nacro::alert($vnc,
toggle_text("Mouse drags"), 10);
} else {
nacro::alert($vnc,"Unknown key",10);
}
$mode="passthru";
}
if($result&$nacro::RESULT_MOUSE) {
$x=nacro::getx($vnc);
$y=nacro::gety($vnc);
$buttons=nacro::getbuttons($vnc);
if(($buttons&1)==1) {
print STDERR "start draggin: $x $y\n";
$start_x=$x;
$start_y=$y;
nacro::rubberband($vnc, $x, $y);
$x=nacro::getx($vnc);
$y=nacro::gety($vnc);
if($start_x==$x && $start_y==$y) {
# reset
print OUT "\$x_origin=0; \$y_origin=0;\n";
} else {
if($start_x>$x) {
$dummy=$x; $x=$start_x; $start_x=$dummy;
}
if($start_y>$y) {
$dummy=$y; $y=$start_y; $start_y=$dummy;
}
$pnm=$output.$image_counter.".pnm";
$image_counter++;
if(!nacro::savepnm($vnc,$pnm,$start_x,$start_y,$x,$y)) {
nacro::alert($vnc,"Saving $pnm failed!",10);
} else {
$x_origin=$start_x;
$y_origin=$start_y;
nacro::alert($vnc,"Got new origin: $x_origin $y_origin",10);
print OUT "if(nacro::visualgrep(\$vnc,\"$pnm\",999999)) {\n"
. "\t\$x_origin=nacro::getxorigin(\$vnc);\n"
. "\t\$y_origin=nacro::getyorigin(\$vnc);\n}\n";
}
}
$mode="passthru";
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,57 @@
#! /bin/sh
# Run this to generate all the initial makefiles, etc.
set -e
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
DIE=0
AUTOMAKE=automake-1.4
ACLOCAL=aclocal-1.4
($AUTOMAKE --version) < /dev/null > /dev/null 2>&1 || {
AUTOMAKE=automake
ACLOCAL=aclocal
}
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have autoconf installed to compile libvncserver."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
($AUTOMAKE --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have automake installed to compile libvncserver."
echo "Get ftp://sourceware.cygnus.com/pub/automake/automake-1.4.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
}
if test "$DIE" -eq 1; then
exit 1
fi
(test -f $srcdir/rfb/rfb.h) || {
echo "You must run this script in the top-level libvncserver directory"
exit 1
}
if test -z "$*"; then
echo "I am going to run ./configure with no arguments - if you wish "
echo "to pass any to it, please specify them on the $0 command line."
fi
$ACLOCAL $ACLOCAL_FLAGS
autoheader
$AUTOMAKE --add-missing --copy
autoconf
echo "Running ./configure --enable-maintainer-mode" "$@"
$srcdir/configure --enable-maintainer-mode "$@"
echo "Now type 'make' to compile libvncserver."

View File

@ -0,0 +1,60 @@
#!/usr/bin/perl
@encodings=();
for($i=0;$i<256*5;$i++) {
$encodings[$i]="0";
}
$out="";
$counter=0;
$fontname="default";
$i=0;
$searchfor="";
$nullx="0x";
while(<>) {
if(/^FONT (.*)$/) {
$fontname=$1;
$fontname=~y/\"//d;
} elsif(/^ENCODING (.*)$/) {
$glyphindex=$1;
$searchfor="BBX";
$dwidth=0;
} elsif(/^DWIDTH (.*) (.*)/) {
$dwidth=$1;
} elsif(/^BBX (.*) (.*) (.*) (.*)$/) {
($width,$height,$x,$y)=($1,$2,$3,$4);
@encodings[$glyphindex*5..($glyphindex*5+4)]=($counter,$width,$height,$x,$y);
if($dwidth != 0) {
$encodings[$glyphindex*5+1]=$dwidth;
} else {
$dwidth=$width;
}
$searchfor="BITMAP";
} elsif(/^BITMAP/) {
$i=1;
} elsif($i>0) {
if($i>$height) {
$i=0;
$out.=" /* $glyphindex */\n";
} else {
if(int(($dwidth+7)/8) > int(($width+7)/8)) {
$_ .= "00"x(int(($dwidth+7)/8)-int(($width+7)/8));
}
$_=substr($_,0,(int(($dwidth+7)/8)*2));
$counter+=(int(($dwidth+7)/8));
s/(..)/$nullx$1,/g;
$out.=$_;
$i++;
}
}
}
print "unsigned char " . $fontname . "FontData[$counter]={\n" . $out;
print "};\nint " . $fontname . "FontMetaData[256*5]={\n";
for($i=0;$i<256*5;$i++) {
print $encodings[$i] . ",";
}
print "};\nrfbFontData " . $fontname . "Font={" .
$fontname . "FontData, " . $fontname . "FontMetaData};\n";

View File

@ -0,0 +1,3 @@
Makefile
Makefile.in

View File

@ -0,0 +1,5 @@
EXTRA_DIST=VncViewer.jar index.vnc javaviewer.pseudo_proxy.patch
SUBDIRS = ssl
DIST_SUBDIRS = ssl

Binary file not shown.

View File

@ -0,0 +1,18 @@
<!-- index.vnc - default html page for Java VNC viewer applet. On any file
ending in .vnc, the HTTP server embedded in Xvnc will substitute the
following variables when preceded by a dollar: USER, DESKTOP, DISPLAY,
APPLETWIDTH, APPLETHEIGHT, WIDTH, HEIGHT, PORT, PARAMS. Use two dollar
signs ($$) to get a dollar sign in the generated html. -->
<HTML>
<TITLE>
$USER's $DESKTOP desktop ($DISPLAY)
</TITLE>
<APPLET CODE=VncViewer.class ARCHIVE=VncViewer.jar
WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
<param name=PORT value=$PORT>
<param name="Open New Window" value=yes>
</APPLET>
<BR>
<A href="http://www.tightvnc.com/">www.TightVNC.com</A>
</HTML>

View File

@ -0,0 +1,141 @@
diff -ru vnc_javasrc/OptionsFrame.java proxy_vnc_javasrc/OptionsFrame.java
--- vnc_javasrc/OptionsFrame.java Fri Jul 5 08:17:23 2002
+++ proxy_vnc_javasrc/OptionsFrame.java Thu Aug 22 23:24:44 2002
@@ -70,6 +70,12 @@
Label[] labels = new Label[names.length];
Choice[] choices = new Choice[names.length];
+
+ Label proxyHostLabel;
+ TextField proxyHostEdit;
+ Label proxyPortLabel;
+ TextField proxyPortEdit;
+
Button closeButton;
VncViewer viewer;
@@ -93,6 +99,9 @@
boolean shareDesktop;
boolean viewOnly;
+ String proxyHost;
+ int proxyPort;
+
//
// Constructor. Set up the labels and choices from the names and values
// arrays.
@@ -126,6 +135,32 @@
}
}
+ // TODO: find a way to set these to defaults from browser
+ proxyPort = viewer.readIntParameter("Use Proxy Port", -1);
+ if(proxyPort>-1) {
+ proxyHost = viewer.readParameter("Use Proxy Host", false);
+ if(proxyHost == null)
+ proxyHost = viewer.host;
+
+ proxyHostLabel = new Label("Proxy Host");
+ gbc.gridwidth = 1;
+ gridbag.setConstraints(proxyHostLabel,gbc);
+ add(proxyHostLabel);
+ proxyHostEdit = new TextField();
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ gridbag.setConstraints(proxyHostEdit,gbc);
+ add(proxyHostEdit);
+
+ proxyPortLabel = new Label("Proxy Port");
+ gbc.gridwidth = 1;
+ gridbag.setConstraints(proxyPortLabel,gbc);
+ add(proxyPortLabel);
+ proxyPortEdit = new TextField();
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ gridbag.setConstraints(proxyPortEdit,gbc);
+ add(proxyPortEdit);
+ }
+
closeButton = new Button("Close");
gbc.gridwidth = GridBagConstraints.REMAINDER;
gridbag.setConstraints(closeButton, gbc);
@@ -161,6 +196,11 @@
}
}
+ if(proxyPort>-1) {
+ proxyPortEdit.setText(Integer.toString(proxyPort));
+ proxyHostEdit.setText(proxyHost);
+ }
+
// Make the booleans and encodings array correspond to the state of the GUI
setEncodings();
@@ -361,8 +401,12 @@
//
public void actionPerformed(ActionEvent evt) {
- if (evt.getSource() == closeButton)
+ if (evt.getSource() == closeButton) {
setVisible(false);
+ proxyHost = proxyHostEdit.getText();
+ proxyPort = Integer.parseInt(proxyPortEdit.getText());
+ System.err.println("proxy is " + proxyHost + ":" + proxyPort);
+ }
}
//
diff -ru vnc_javasrc/RfbProto.java proxy_vnc_javasrc/RfbProto.java
--- vnc_javasrc/RfbProto.java Sun Aug 4 18:39:35 2002
+++ proxy_vnc_javasrc/RfbProto.java Thu Aug 22 22:53:53 2002
@@ -119,12 +119,51 @@
viewer = v;
host = h;
port = p;
- sock = new Socket(host, port);
+ if(viewer.options.proxyPort>-1)
+ sock = new Socket(viewer.options.proxyHost, viewer.options.proxyPort);
+ else
+ sock = new Socket(host, port);
is = new DataInputStream(new BufferedInputStream(sock.getInputStream(),
16384));
os = sock.getOutputStream();
+ if(viewer.options.proxyPort>-1)
+ negotiateProxy(host,port);
}
+ // this is inefficient as hell, but only used once per connection
+ String readLine() {
+ byte[] ba = new byte[1];
+ String s = new String("");
+
+ ba[0]=0;
+ try {
+ while(ba[0] != 0xa) {
+ ba[0] = (byte)is.readUnsignedByte();
+ s += new String(ba);
+ }
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ return s;
+ }
+
+ void negotiateProxy(String realHost,int realPort) throws IOException {
+ String line;
+
+ // this would be the correct way, but we want to trick strict proxies.
+ // line = "CONNECT " + realHost + ":" + realPort + " HTTP/1.1\r\nHost: " + realHost + ":" + realPort + "\r\n\r\n";
+ line = "GET " + realHost + ":" + realPort + "/proxied.connection HTTP/1.0\r\nPragma: No-Cache\r\nProxy-Connection: Keep-Alive\r\n\r\n";
+ os.write(line.getBytes());
+
+ line = readLine();
+ System.err.println("Proxy said: " + line);
+ if(!(line.substring(0,7)+line.substring(8,12)).equalsIgnoreCase("HTTP/1. 200")) {
+ IOException e = new IOException(line);
+ throw e;
+ }
+ while(!line.equals("\r\n") && !line.equals("\n"))
+ line = readLine();
+ }
void close() {
try {

View File

@ -0,0 +1,2 @@
EXTRA_DIST=VncViewer.jar index.vnc SignedVncViewer.jar proxy.vnc README ss_vncviewer onetimekey UltraViewerSSL.jar SignedUltraViewerSSL.jar ultra.vnc ultrasigned.vnc ultraproxy.vnc

View File

@ -0,0 +1,338 @@
This directory contains a patched Java applet VNC viewer that is SSL
enabled.
The patches in the *.patch files are relative to the source tarball:
tightvnc-1.3dev7_javasrc.tar.gz
currently (4/06) available here:
http://prdownloads.sourceforge.net/vnc-tight/tightvnc-1.3dev7_javasrc.tar.gz?download
It also includes some simple patches to:
- fix richcursor colors
- make the Java Applet cursor (not the cursor drawn to the canvas
framebuffer) invisible when it is inside the canvas.
- allow Tab (and some other) keystrokes to be sent to the vnc
server instead of doing widget traversal.
This SSL applet should work with any VNC viewer that has an SSL tunnel in
front of it. It has been tested on x11vnc and using the stunnel tunnel
to other VNC servers.
By default this Vnc Viewer will only do SSL. To do unencrypted traffic
see the "DisableSSL" applet parameter (e.g. set it to Yes in index.vnc).
Proxies: they are a general problem with java socket applets (a socket
connection does not go through the proxy). See the info in the proxy.vnc
file for a workaround. It uses SignedVncViewer.jar which is simply
a signed version of VncViewer.jar. The basic idea is the user clicks
"Yes" to trust the applet and then it can connect directly to the proxy
and issue a CONNECT request.
This applet has been tested on versions 1.4.2 and 1.5.0 of the Sun
Java plugin. It may not work on older releases or different vendor VM's.
Send full Java Console output for failures.
---------------------------------------------------------------
Tips:
When doing single-port proxy connections (e.g. both VNC and HTTPS
thru port 5900) it helps to move through the 'do you trust this site'
dialogs quickly. x11vnc has to wait to see if the traffic is VNC or
HTTP and this can cause timeouts if you don't move thru them quickly.
You may have to restart your browser completely if it gets into a
weird state. For one case we saw the JVM requesting VncViewer.class
even when no such file exists.
---------------------------------------------------------------
Extras:
ss_vncviewer (not Java):
Wrapper script for native VNC viewer to connect to x11vnc in
SSL mode. Script launches stunnel(8) and then connects to it
via localhost which in turn is then redirected to x11vnc via an
SSL tunnel. stunnel(8) must be installed and available in PATH.
Running Java SSL VncViewer from the command line:
From this directory:
java -cp ./VncViewer.jar VncViewer HOST <thehost> PORT <theport>
substitute <thehost> and <theport> with the actual values.
You can add any other parameters, e.g.: ignoreProxy yes
---------------------------------------------------------------
UltraVNC:
The UltraVNC java viewer has also been patched to support SSL. Various
bugs in the UltraVNC java viewer were also fixed. This viewer can be
useful because is support UltraVNC filetransfer, and so it works on
Unix, etc.
UltraViewerSSL.jar
SignedUltraViewerSSL.jar
ultra.vnc
ultraproxy.vnc
ultravnc-102-JavaViewer-ssl-etc.patch
---------------------------------------------------------------
Applet Parameters:
Some additional applet parameters can be set via the URL, e.g.
http://host:5800/?param=value
http://host:5800/ultra.vnc?param=value
https://host:5900/ultra.vnc?param=value
etc. If running java from command line as show above, it comes
in as java ... VncViewer param value ...
There is a limitation with libvncserver that param and value can
only be alphanumeric, underscore, "+" (for space), or "."
We have added some applet parameters to the stock VNC java
viewers. Here are the applet parameters:
Both TightVNC and UltraVNC Java viewers:
HOST
string, default: none.
The Hostname to connect to.
PORT
number, default: 0
The VNC server port to connect to.
Open New Window
yes/no, default: no
Run applet in separate frame.
Show Controls
yes/no, default: yes
Show Controls button panel.
Show Offline Desktop
yes/no, default: no
Do we continue showing desktop on remote disconnect?
Defer screen updates
number, default: 20
Milliseconds delay
Defer cursor updates
number, default: 10
Milliseconds delay
Defer update requests
number, default: 50
Milliseconds delay
PASSWORD
string, default: none
VNC session password in plain text.
ENCPASSWORD
string, default: none
VNC session password in encrypted in DES with KNOWN FIXED
key. It is a hex string. This is like the ~/.vnc/passwd format.
The following are added by x11vnc and/or ssvnc project
VNCSERVERPORT
number, default: 0
Like PORT, but if there is a firewall this is the Actual VNC
server port. PORT might be a redir port on the firewall.
DisableSSL
yes/no, default: no
Do unencrypted connection, no SSL.
httpsPort
number, default: none
When checking for proxy, use this at the url port number.
CONNECT
string, default: none
Sets to host:port for the CONNECT line to a Web proxy.
The Web proxy should connect us to it.
GET
yes/no, default: no
Set to do a special HTTP GET (/request.https.vnc.connection)
to the vnc server that will cause it to switch to VNC instead.
This is to speedup/make more robust, the single port HTTPS and VNC
mode of x11vnc (e.g. both services thru port 5900, etc)
urlPrefix
string, default: none
set to a string that will be prefixed to all URL's when contacting
the VNC server. Idea is a special proxy will use this to indicate
internal hostname, etc.
oneTimeKey
string, default: none
set a special hex "key" to correspond to an SSL X.509 cert+key.
See the 'onetimekey' helper script. Can also be PROMPT to prompt
the user to paste the hex key string in.
This provides a Client-Side cert+key that the client will use to
authenticate itself by SSL To the VNC Server.
This is to try to work around the problem that the Java applet
cannot keep an SSL keystore on disk, etc. E.g. if they log
into an HTTPS website via password they are authenticated and
encrypted, then the website can safely put oneTimeKey=... on the
URL. The Vncviewer authenticates the VNC server with this key.
Note that there is currently a problem in that if x11vnc requires
Client Certificates the user cannot download the index.vnc HTML
and VncViewer.jar from the same x11vnc. Those need to come from
a different x11vnc or from a web server.
Note that the HTTPS website can also put the VNC Password
(e.g. a temporary/one-time one) in the parameter PASSWORD.
The Java Applet will automatically supply this VNC password
instead of prompting.
serverCert
string, default: none
set a special hex "cert" to correspond to an SSL X.509 cert
See the 'onetimekey -certonly' helper script.
This provides a Server-Side cert that the client will authenticate
the VNC Server against by SSL.
This is to try to work around the problem that the Java applet
cannot keep an SSL keystore on disk, etc. E.g. if they log
into an HTTPS website via password they are authenticated and
encrypted, then the website can safely put serverCert=... on the
URL.
Of course the VNC Server is sending this string to the Java
Applet, so this is only reasonable security if the VNC Viewer
already trusts the HTTPS retrieval of the URL + serverCert param
that it gets. This should be done over HTTPS not HTTP.
proxyHost
string, default: none
Do not try to guess the proxy's hostname, use the value in
proxyHost. Does not imply forceProxy (below.)
proxyPort
string, default: none
Do not try to guess the proxy's port number, use the value in
proxyPort. Does not imply forceProxy (below.)
forceProxy
yes/no, default: no
Assume there is a proxy and force its use.
If a string other than "yes" or "no" is given, it implies "yes"
and uses the string for proxyHost and proxyPort (see above).
In this case the string must be of the form "hostname+port".
Note that it is "+" and not ":" before the port number.
ignoreProxy
yes/no, default: no
Don't check for a proxy, assume there is none.
trustAllVncCerts
yes/no, default: no
Automatically trust any cert received from the VNC server
(obviously this could be dangerous and lead to man in the
middle attack). Do not ask the user to verify any of these
certs from the VNC server.
trustUrlVncCert
yes/no, default: no
Automatically trust any cert that the web browsers has accepted.
E.g. the user said "Yes" or "Continue" to a web browser dialog
regarding a certificate. If we get the same cert (chain) from
the VNC server we trust it without prompting the user.
debugCerts
yes/no, default: no
Print out every cert in the Server, TrustUrl, TrustAll chains.
TightVNC Java viewer only:
Offer Relogin
yes/no, default: yes
"Offer Relogin" set to "No" disables "Login again"
SocketFactory
string, default: none
set Java Socket class factory.
UltraVNC Java viewer only:
None.
The following are added by x11vnc and/or ssvnc project
ftpDropDown
string, default: none
Sets the file transfer "drives" dropdown to the "." separated
list. Use "+" for space. The default is
My+Documents.Desktop.Home
for 3 entries in the dropdown in addition to the "drives"
(e.g. C:\) These items should be expanded properly by the VNC
Server. x11vnc will prepend $HOME to them, which is normally
what one wants. To include a "/" use "_2F_". Another example:
Home.Desktop.bin_2F_linux
If an item is prefixed with "TOP_" then the item is inserted at
the top of the drop down rather than being appended to the end.
E.g. to try to initially load the user homedir instead of /:
TOP_Home.My+Documents.Desktop
If ftpDropDown is set to the empty string, "", then no special
locations, [Desktop] etc., are placed in the drop down. Only the
ultravnc "drives" will appear.
ftpOnly
yes/no, default: no
The VNC viewer only shows the filetransfer panel, no desktop
is displayed.
graftFtp
yes/no, default: no
As ftpOnly, the VNC viewer only shows the filetransfer panel,
no desktop is displayed, however it is "grafted" onto an existing
SSVNC unix vncviewer. The special SSVNC vncviewer merges the two
channels.
dsmActive
yes/no, default: no
Special usage mode with the SSVNC unix vncviewer. The UltraVNC
DSM encryption is active. Foolishly, UltraVNC DSM encryption
*MODIFIES* the VNC protocol when active (it is not a pure tunnel).
This option indicates to modify the VNC protocol to make this work.
Usually only used with graftFtp and SSVNC unix vncviewer.
delayAuthPanel
yes/no, default: no
This is another special usage mode with the SSVNC unix vncviewer.
A login panel is delayed (not shown at startup.) Could be useful
for non SSVNC usage too.
ignoreMSLogonCheck
yes/no, default: no
Similar to delayAuthPanel, do not put up a popup asking for
Windows username, etc.

View File

@ -0,0 +1,26 @@
<!--
index.vnc - default HTML page for TightVNC Java viewer applet, to be
used with Xvnc. On any file ending in .vnc, the HTTP server embedded in
Xvnc will substitute the following variables when preceded by a dollar:
USER, DESKTOP, DISPLAY, APPLETWIDTH, APPLETHEIGHT, WIDTH, HEIGHT, PORT,
PARAMS. Use two dollar signs ($$) to get a dollar sign in the generated
HTML page.
NOTE: the $PARAMS variable is not supported by the standard VNC, so
make sure you have TightVNC on the server side, if you're using this
variable.
-->
<HTML>
<TITLE>
$USER's $DESKTOP desktop ($DISPLAY)
</TITLE>
<APPLET CODE=VncViewer.class ARCHIVE=VncViewer.jar
WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
<param name=PORT value=$PORT>
<param name="Open New Window" value=yes>
$PARAMS
</APPLET>
<BR>
<A href="http://www.karlrunge.com/x11vnc">x11vnc site</A>
</HTML>

View File

@ -0,0 +1,65 @@
#!/bin/sh
#
# usage: onetimekey path/to/mycert.pem
# onetimekey -certonly path/to/mycert.pem
#
# Takes an openssl cert+key pem file and turns into a long string
# for the x11vnc SSL VNC Java Viewer.
#
# The Java applet URL parameter can be oneTimeKey=<str> where str is
# the output of this program, or can be oneTimeKey=PROMPT in which
# case the applet will ask you to paste in the string.
#
# The problem trying to be solved here is it is difficult to get
# the Java applet to have or use a keystore with the key saved
# in it. Also, as the name implies, an HTTPS server can create
# a one time key to send to the applet (the user has already
# logged in via password to the HTTPS server).
#
# Note oneTimeKey is to provide a CLIENT Certificate for the viewer
# to authenticate itself to the VNC Server.
#
# There is also the serverCert=<str> Applet parameter. This is
# a cert to authenticate the VNC server against. To create that
# string with this tool specify -certonly as the first argument.
certonly=""
if [ "X$1" = "X-certonly" ]; then
shift
certonly=1
fi
in=$1
der=/tmp/1time$$.der
touch $der
chmod 600 $der
openssl pkcs8 -topk8 -nocrypt -in "$in" -out "$der" -outform der
pbinhex=/tmp/pbinhex.$$
cat > $pbinhex <<END
#!/usr/bin/perl
\$str = '';
while (1) {
\$c = getc(STDIN);
last if \$c eq '';
\$str .= sprintf("%02x", unpack("C", \$c));
}
print "\$str\n";
END
chmod 700 $pbinhex
str1=`$pbinhex < "$der"`
rm -f "$der"
n=`grep -n 'BEGIN CERTIFICATE' $in | awk -F: '{print $1}' | head -1`
str2=`tail +$n $in | $pbinhex`
if [ "X$certonly" = "X1" ]; then
echo "$str2"
else
echo "$str1,$str2"
fi
rm -f $pbinhex

View File

@ -0,0 +1,73 @@
<!--
index.vnc - default HTML page for TightVNC Java viewer applet, to be
used with Xvnc. On any file ending in .vnc, the HTTP server embedded in
Xvnc will substitute the following variables when preceded by a dollar:
USER, DESKTOP, DISPLAY, APPLETWIDTH, APPLETHEIGHT, WIDTH, HEIGHT, PORT,
PARAMS. Use two dollar signs ($$) to get a dollar sign in the generated
HTML page.
NOTE: the $PARAMS variable is not supported by the standard VNC, so
make sure you have TightVNC on the server side, if you're using this
variable.
-->
<!--
The idea behind using the signed applet in SignedVncViewer.jar for
firewall proxies:
Java socket applets and http proxies do not get along well.
Java security allows the applet to connect back via a socket to the
originating host, but the browser/plugin Proxy settings are not used for
socket connections (only http and the like). So the socket connection
fails in the proxy environment.
The applet is not allowed to open a socket connection to the proxy (since
that would let it connect to just about any host, e.g. CONNECT method).
This is indpendent of SSL but of course fails for that socket connection
as well. I.e. this is a problem for non-SSL VNC Viewers as well.
Solution? Sign the applet and have the user click on "Yes" that they
fully trust the applet. Then the applet can connect to any host via
sockets, in particular the proxy. It next issues the request
CONNECT host:port HTTP/1.1
Host: host:port
and if the proxy supports the CONNECT method we are finally connected to
the VNC server.
For SSL connections, SSL is layered on top of this socket. However note
this scheme will work for non-SSL applet proxy tunnelling as well.
It should be able to get non-SSL VNC connections to work via GET
command but that has not been done yet.
Note that some proxies only allow CONNECT to only these the ports 443
(HTTPS) and 563 (SNEWS). So you would have to run the VNC server on
those ports.
SignedVncViewer.jar is just a signed version of VncViewer.jar
The URL to use for this file: https://host:port/proxy.vnc
Note VNCSERVERPORT, we assume $PARAMS will have the correct PORT setting
(e.g. 563), not the one libvncserver puts in....
-->
<HTML>
<TITLE>
$USER's $DESKTOP desktop ($DISPLAY)
</TITLE>
<APPLET CODE=VncViewer.class ARCHIVE=SignedVncViewer.jar
WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
<param name=VNCSERVERPORT value=$PORT>
<param name="Open New Window" value=yes>
$PARAMS
</APPLET>
<BR>
<A href="http://www.karlrunge.com/x11vnc">x11vnc site</A>
</HTML>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,57 @@
--- vnc_javasrc.orig/VncCanvas.java 2004-10-10 02:15:54.000000000 -0400
+++ vnc_javasrc/VncCanvas.java 2006-03-27 22:34:02.000000000 -0500
@@ -28,6 +28,7 @@
import java.lang.*;
import java.util.zip.*;
+import java.util.Collections;
//
// VncCanvas is a subclass of Canvas which draws a VNC desktop on it.
@@ -81,6 +82,20 @@
cm8 = new DirectColorModel(8, 7, (7 << 3), (3 << 6));
cm24 = new DirectColorModel(24, 0xFF0000, 0x00FF00, 0x0000FF);
+ // kludge to not show any Java cursor in the canvas since we are
+ // showing the soft cursor (should be a user setting...)
+ Cursor dot = Toolkit.getDefaultToolkit().createCustomCursor(
+ Toolkit.getDefaultToolkit().createImage(new byte[4]), new Point(0,0),
+ "dot");
+ this.setCursor(dot);
+
+ // while we are at it... get rid of the keyboard traversals that
+ // make it so we can't type a Tab character:
+ this.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
+ Collections.EMPTY_SET);
+ this.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
+ Collections.EMPTY_SET);
+
colors = new Color[256];
for (int i = 0; i < 256; i++)
colors[i] = new Color(cm8.getRGB(i));
@@ -1387,9 +1402,9 @@
result = cm8.getRGB(pixBuf[i]);
} else {
result = 0xFF000000 |
- (pixBuf[i * 4 + 1] & 0xFF) << 16 |
- (pixBuf[i * 4 + 2] & 0xFF) << 8 |
- (pixBuf[i * 4 + 3] & 0xFF);
+ (pixBuf[i * 4 + 2] & 0xFF) << 16 |
+ (pixBuf[i * 4 + 1] & 0xFF) << 8 |
+ (pixBuf[i * 4 + 0] & 0xFF);
}
} else {
result = 0; // Transparent pixel
@@ -1403,9 +1418,9 @@
result = cm8.getRGB(pixBuf[i]);
} else {
result = 0xFF000000 |
- (pixBuf[i * 4 + 1] & 0xFF) << 16 |
- (pixBuf[i * 4 + 2] & 0xFF) << 8 |
- (pixBuf[i * 4 + 3] & 0xFF);
+ (pixBuf[i * 4 + 2] & 0xFF) << 16 |
+ (pixBuf[i * 4 + 1] & 0xFF) << 8 |
+ (pixBuf[i * 4 + 0] & 0xFF);
}
} else {
result = 0; // Transparent pixel

View File

@ -0,0 +1,28 @@
<!--
index.vnc - default HTML page for TightVNC Java viewer applet, to be
used with Xvnc. On any file ending in .vnc, the HTTP server embedded in
Xvnc will substitute the following variables when preceded by a dollar:
USER, DESKTOP, DISPLAY, APPLETWIDTH, APPLETHEIGHT, WIDTH, HEIGHT, PORT,
PARAMS. Use two dollar signs ($$) to get a dollar sign in the generated
HTML page.
NOTE: the $PARAMS variable is not supported by the standard VNC, so
make sure you have TightVNC on the server side, if you're using this
variable.
-->
<HTML>
<TITLE>
$USER's $DESKTOP desktop ($DISPLAY)
</TITLE>
<APPLET CODE=VncViewer.class ARCHIVE=UltraViewerSSL.jar
WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
<param name=PORT value=$PORT>
<param name="Open New Window" value=yes>
<param name="ignoreMSLogonCheck" value=yes>
<param name="delayAuthPanel" value=yes>
$PARAMS
</APPLET>
<BR>
<A href="http://www.karlrunge.com/x11vnc">x11vnc site</A>
</HTML>

View File

@ -0,0 +1,28 @@
<!--
index.vnc - default HTML page for TightVNC Java viewer applet, to be
used with Xvnc. On any file ending in .vnc, the HTTP server embedded in
Xvnc will substitute the following variables when preceded by a dollar:
USER, DESKTOP, DISPLAY, APPLETWIDTH, APPLETHEIGHT, WIDTH, HEIGHT, PORT,
PARAMS. Use two dollar signs ($$) to get a dollar sign in the generated
HTML page.
NOTE: the $PARAMS variable is not supported by the standard VNC, so
make sure you have TightVNC on the server side, if you're using this
variable.
-->
<HTML>
<TITLE>
$USER's $DESKTOP desktop ($DISPLAY)
</TITLE>
<APPLET CODE=VncViewer.class ARCHIVE=SignedUltraViewerSSL.jar
WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
<param name="Open New Window" value=yes>
<param name="ignoreMSLogonCheck" value=yes>
<param name="delayAuthPanel" value=yes>
<param name=VNCSERVERPORT value=$PORT>
$PARAMS
</APPLET>
<BR>
<A href="http://www.karlrunge.com/x11vnc">x11vnc site</A>
</HTML>

View File

@ -0,0 +1,28 @@
<!--
index.vnc - default HTML page for TightVNC Java viewer applet, to be
used with Xvnc. On any file ending in .vnc, the HTTP server embedded in
Xvnc will substitute the following variables when preceded by a dollar:
USER, DESKTOP, DISPLAY, APPLETWIDTH, APPLETHEIGHT, WIDTH, HEIGHT, PORT,
PARAMS. Use two dollar signs ($$) to get a dollar sign in the generated
HTML page.
NOTE: the $PARAMS variable is not supported by the standard VNC, so
make sure you have TightVNC on the server side, if you're using this
variable.
-->
<HTML>
<TITLE>
$USER's $DESKTOP desktop ($DISPLAY)
</TITLE>
<APPLET CODE=VncViewer.class ARCHIVE=SignedUltraViewerSSL.jar
WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
<param name=PORT value=$PORT>
<param name="Open New Window" value=yes>
<param name="ignoreMSLogonCheck" value=yes>
<param name="delayAuthPanel" value=yes>
$PARAMS
</APPLET>
<BR>
<A href="http://www.karlrunge.com/x11vnc">x11vnc site</A>
</HTML>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
.deps
Makefile
Makefile.in
SDLvncviewer
ppmtest
vnc2mpg
*.avi
*.mpg

View File

@ -0,0 +1,33 @@
INCLUDES = -I$(top_srcdir)
LDADD = ../libvncclient/libvncclient.la @WSOCKLIB@
if WITH_FFMPEG
FFMPEG_HOME=@with_ffmpeg@
if HAVE_MP3LAME
MP3LAME_LIB=-lmp3lame
endif
vnc2mpg_CFLAGS=-I$(FFMPEG_HOME)/libavformat -I$(FFMPEG_HOME)/libavcodec -I$(FFMPEG_HOME)/libavutil
vnc2mpg_LDADD=$(LDADD) $(FFMPEG_HOME)/libavformat/libavformat.a $(FFMPEG_HOME)/libavcodec/libavcodec.a $(MP3LAME_LIB) -lm
FFMPEG_CLIENT=vnc2mpg
endif
if HAVE_LIBSDL
SDLVIEWER=SDLvncviewer
SDLvncviewer_CFLAGS=$(SDL_CFLAGS)
if HAVE_X11
X11_LIB=-lX11
endif
# thanks to autoconf, this looks ugly
SDLvncviewer_LDADD=$(LDADD) $(SDL_LIBS) $(X11_LIB)
endif
noinst_PROGRAMS=ppmtest $(SDLVIEWER) $(FFMPEG_CLIENT) backchannel

View File

@ -0,0 +1,553 @@
#include <SDL.h>
#include <signal.h>
#include <rfb/rfbclient.h>
#include "scrap.c"
struct { int sdl; int rfb; } buttonMapping[]={
{1, rfbButton1Mask},
{2, rfbButton2Mask},
{3, rfbButton3Mask},
{4, rfbButton4Mask},
{5, rfbButton5Mask},
{0,0}
};
static int enableResizable, viewOnly, listenLoop, buttonMask;
#ifdef SDL_ASYNCBLIT
int sdlFlags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
#else
int sdlFlags = SDL_HWSURFACE | SDL_HWACCEL;
#endif
static int realWidth, realHeight, bytesPerPixel, rowStride;
static char *sdlPixels;
static int rightAltKeyDown, leftAltKeyDown;
static rfbBool resize(rfbClient* client) {
int width=client->width,height=client->height,
depth=client->format.bitsPerPixel;
if (enableResizable)
sdlFlags |= SDL_RESIZABLE;
client->updateRect.x = client->updateRect.y = 0;
client->updateRect.w = width; client->updateRect.h = height;
rfbBool okay=SDL_VideoModeOK(width,height,depth,sdlFlags);
if(!okay)
for(depth=24;!okay && depth>4;depth/=2)
okay=SDL_VideoModeOK(width,height,depth,sdlFlags);
if(okay) {
SDL_Surface* sdl=SDL_SetVideoMode(width,height,depth,sdlFlags);
rfbClientSetClientData(client, SDL_Init, sdl);
client->width = sdl->pitch / (depth / 8);
if (sdlPixels) {
free(client->frameBuffer);
sdlPixels = NULL;
}
client->frameBuffer=sdl->pixels;
client->format.bitsPerPixel=depth;
client->format.redShift=sdl->format->Rshift;
client->format.greenShift=sdl->format->Gshift;
client->format.blueShift=sdl->format->Bshift;
client->format.redMax=sdl->format->Rmask>>client->format.redShift;
client->format.greenMax=sdl->format->Gmask>>client->format.greenShift;
client->format.blueMax=sdl->format->Bmask>>client->format.blueShift;
SetFormatAndEncodings(client);
} else {
SDL_Surface* sdl=rfbClientGetClientData(client, SDL_Init);
rfbClientLog("Could not set resolution %dx%d!\n",
client->width,client->height);
if(sdl) {
client->width=sdl->pitch / (depth / 8);
client->height=sdl->h;
} else {
client->width=0;
client->height=0;
}
return FALSE;
}
SDL_WM_SetCaption(client->desktopName, "SDL");
return TRUE;
}
static rfbKeySym SDL_key2rfbKeySym(SDL_KeyboardEvent* e) {
rfbKeySym k = 0;
switch(e->keysym.sym) {
case SDLK_BACKSPACE: k = XK_BackSpace; break;
case SDLK_TAB: k = XK_Tab; break;
case SDLK_CLEAR: k = XK_Clear; break;
case SDLK_RETURN: k = XK_Return; break;
case SDLK_PAUSE: k = XK_Pause; break;
case SDLK_ESCAPE: k = XK_Escape; break;
case SDLK_SPACE: k = XK_space; break;
case SDLK_DELETE: k = XK_Delete; break;
case SDLK_KP0: k = XK_KP_0; break;
case SDLK_KP1: k = XK_KP_1; break;
case SDLK_KP2: k = XK_KP_2; break;
case SDLK_KP3: k = XK_KP_3; break;
case SDLK_KP4: k = XK_KP_4; break;
case SDLK_KP5: k = XK_KP_5; break;
case SDLK_KP6: k = XK_KP_6; break;
case SDLK_KP7: k = XK_KP_7; break;
case SDLK_KP8: k = XK_KP_8; break;
case SDLK_KP9: k = XK_KP_9; break;
case SDLK_KP_PERIOD: k = XK_KP_Decimal; break;
case SDLK_KP_DIVIDE: k = XK_KP_Divide; break;
case SDLK_KP_MULTIPLY: k = XK_KP_Multiply; break;
case SDLK_KP_MINUS: k = XK_KP_Subtract; break;
case SDLK_KP_PLUS: k = XK_KP_Add; break;
case SDLK_KP_ENTER: k = XK_KP_Enter; break;
case SDLK_KP_EQUALS: k = XK_KP_Equal; break;
case SDLK_UP: k = XK_Up; break;
case SDLK_DOWN: k = XK_Down; break;
case SDLK_RIGHT: k = XK_Right; break;
case SDLK_LEFT: k = XK_Left; break;
case SDLK_INSERT: k = XK_Insert; break;
case SDLK_HOME: k = XK_Home; break;
case SDLK_END: k = XK_End; break;
case SDLK_PAGEUP: k = XK_Page_Up; break;
case SDLK_PAGEDOWN: k = XK_Page_Down; break;
case SDLK_F1: k = XK_F1; break;
case SDLK_F2: k = XK_F2; break;
case SDLK_F3: k = XK_F3; break;
case SDLK_F4: k = XK_F4; break;
case SDLK_F5: k = XK_F5; break;
case SDLK_F6: k = XK_F6; break;
case SDLK_F7: k = XK_F7; break;
case SDLK_F8: k = XK_F8; break;
case SDLK_F9: k = XK_F9; break;
case SDLK_F10: k = XK_F10; break;
case SDLK_F11: k = XK_F11; break;
case SDLK_F12: k = XK_F12; break;
case SDLK_F13: k = XK_F13; break;
case SDLK_F14: k = XK_F14; break;
case SDLK_F15: k = XK_F15; break;
case SDLK_NUMLOCK: k = XK_Num_Lock; break;
case SDLK_CAPSLOCK: k = XK_Caps_Lock; break;
case SDLK_SCROLLOCK: k = XK_Scroll_Lock; break;
case SDLK_RSHIFT: k = XK_Shift_R; break;
case SDLK_LSHIFT: k = XK_Shift_L; break;
case SDLK_RCTRL: k = XK_Control_R; break;
case SDLK_LCTRL: k = XK_Control_L; break;
case SDLK_RALT: k = XK_Alt_R; break;
case SDLK_LALT: k = XK_Alt_L; break;
case SDLK_RMETA: k = XK_Meta_R; break;
case SDLK_LMETA: k = XK_Meta_L; break;
#if 0
/* TODO: find out keysyms */
case SDLK_LSUPER: k = XK_LSuper; break; /* left "windows" key */
case SDLK_RSUPER: k = XK_RSuper; break; /* right "windows" key */
case SDLK_COMPOSE: k = XK_Compose; break;
#endif
case SDLK_MODE: k = XK_Mode_switch; break;
case SDLK_HELP: k = XK_Help; break;
case SDLK_PRINT: k = XK_Print; break;
case SDLK_SYSREQ: k = XK_Sys_Req; break;
case SDLK_BREAK: k = XK_Break; break;
default: break;
}
if (k == 0 && e->keysym.sym >= SDLK_a && e->keysym.sym <= SDLK_z) {
k = XK_a + e->keysym.sym - SDLK_a;
if (e->keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT))
k &= ~0x20;
}
if (k == 0) {
if (e->keysym.unicode < 0x100)
k = e->keysym.unicode;
else
rfbClientLog("Unknown keysym: %d\n",e->keysym.sym);
}
return k;
}
static uint32_t get(rfbClient *cl, int x, int y)
{
switch (bytesPerPixel) {
case 1: return ((uint8_t *)cl->frameBuffer)[x + y * cl->width];
case 2: return ((uint16_t *)cl->frameBuffer)[x + y * cl->width];
case 4: return ((uint32_t *)cl->frameBuffer)[x + y * cl->width];
default:
rfbClientErr("Unknown bytes/pixel: %d", bytesPerPixel);
exit(1);
}
}
static void put(int x, int y, uint32_t v)
{
switch (bytesPerPixel) {
case 1: ((uint8_t *)sdlPixels)[x + y * rowStride] = v; break;
case 2: ((uint16_t *)sdlPixels)[x + y * rowStride] = v; break;
case 4: ((uint32_t *)sdlPixels)[x + y * rowStride] = v; break;
default:
rfbClientErr("Unknown bytes/pixel: %d", bytesPerPixel);
exit(1);
}
}
static void resizeRectangleToReal(rfbClient *cl, int x, int y, int w, int h)
{
int i0 = x * realWidth / cl->width;
int i1 = ((x + w) * realWidth - 1) / cl->width + 1;
int j0 = y * realHeight / cl->height;
int j1 = ((y + h) * realHeight - 1) / cl->height + 1;
int i, j;
for (j = j0; j < j1; j++)
for (i = i0; i < i1; i++) {
int x0 = i * cl->width / realWidth;
int x1 = ((i + 1) * cl->width - 1) / realWidth + 1;
int y0 = j * cl->height / realHeight;
int y1 = ((j + 1) * cl->height - 1) / realHeight + 1;
uint32_t r = 0, g = 0, b = 0;
for (y = y0; y < y1; y++)
for (x = x0; x < x1; x++) {
uint32_t v = get(cl, x, y);
#define REDSHIFT cl->format.redShift
#define REDMAX cl->format.redMax
#define GREENSHIFT cl->format.greenShift
#define GREENMAX cl->format.greenMax
#define BLUESHIFT cl->format.blueShift
#define BLUEMAX cl->format.blueMax
r += (v >> REDSHIFT) & REDMAX;
g += (v >> GREENSHIFT) & GREENMAX;
b += (v >> BLUESHIFT) & BLUEMAX;
}
r /= (x1 - x0) * (y1 - y0);
g /= (x1 - x0) * (y1 - y0);
b /= (x1 - x0) * (y1 - y0);
put(i, j, (r << REDSHIFT) | (g << GREENSHIFT) |
(b << BLUESHIFT));
}
}
static void update(rfbClient* cl,int x,int y,int w,int h) {
if (sdlPixels) {
resizeRectangleToReal(cl, x, y, w, h);
w = ((x + w) * realWidth - 1) / cl->width + 1;
h = ((y + h) * realHeight - 1) / cl->height + 1;
x = x * realWidth / cl->width;
y = y * realHeight / cl->height;
w -= x;
h -= y;
}
SDL_UpdateRect(rfbClientGetClientData(cl, SDL_Init), x, y, w, h);
}
static void setRealDimension(rfbClient *client, int w, int h)
{
SDL_Surface* sdl;
if (w < 0) {
const SDL_VideoInfo *info = SDL_GetVideoInfo();
w = info->current_h;
h = info->current_w;
}
if (w == realWidth && h == realHeight)
return;
if (!sdlPixels) {
int size;
sdlPixels = (char *)client->frameBuffer;
rowStride = client->width;
bytesPerPixel = client->format.bitsPerPixel / 8;
size = client->width * bytesPerPixel * client->height;
client->frameBuffer = malloc(size);
if (!client->frameBuffer) {
rfbClientErr("Could not allocate %d bytes", size);
exit(1);
}
memcpy(client->frameBuffer, sdlPixels, size);
}
sdl = rfbClientGetClientData(client, SDL_Init);
if (sdl->w != w || sdl->h != h) {
int depth = sdl->format->BitsPerPixel;
sdl = SDL_SetVideoMode(w, h, depth, sdlFlags);
rfbClientSetClientData(client, SDL_Init, sdl);
sdlPixels = sdl->pixels;
rowStride = sdl->pitch / (depth / 8);
}
realWidth = w;
realHeight = h;
update(client, 0, 0, client->width, client->height);
}
static void kbd_leds(rfbClient* cl, int value, int pad) {
/* note: pad is for future expansion 0=unused */
fprintf(stderr,"Led State= 0x%02X\n", value);
fflush(stderr);
}
/* trivial support for textchat */
static void text_chat(rfbClient* cl, int value, char *text) {
switch(value) {
case rfbTextChatOpen:
fprintf(stderr,"TextChat: We should open a textchat window!\n");
TextChatOpen(cl);
break;
case rfbTextChatClose:
fprintf(stderr,"TextChat: We should close our window!\n");
break;
case rfbTextChatFinished:
fprintf(stderr,"TextChat: We should close our window!\n");
break;
default:
fprintf(stderr,"TextChat: Received \"%s\"\n", text);
break;
}
fflush(stderr);
}
#ifdef __MINGW32__
#define LOG_TO_FILE
#endif
#ifdef LOG_TO_FILE
#include <stdarg.h>
static void
log_to_file(const char *format, ...)
{
FILE* logfile;
static char* logfile_str=0;
va_list args;
char buf[256];
time_t log_clock;
if(!rfbEnableClientLogging)
return;
if(logfile_str==0) {
logfile_str=getenv("VNCLOG");
if(logfile_str==0)
logfile_str="vnc.log";
}
logfile=fopen(logfile_str,"a");
va_start(args, format);
time(&log_clock);
strftime(buf, 255, "%d/%m/%Y %X ", localtime(&log_clock));
fprintf(logfile,buf);
vfprintf(logfile, format, args);
fflush(logfile);
va_end(args);
fclose(logfile);
}
#endif
static void cleanup(rfbClient* cl)
{
/*
just in case we're running in listenLoop:
close viewer window by restarting SDL video subsystem
*/
SDL_QuitSubSystem(SDL_INIT_VIDEO);
SDL_InitSubSystem(SDL_INIT_VIDEO);
if(cl)
rfbClientCleanup(cl);
}
static rfbBool handleSDLEvent(rfbClient *cl, SDL_Event *e)
{
switch(e->type) {
#if SDL_MAJOR_VERSION > 1 || SDL_MINOR_VERSION >= 2
case SDL_VIDEOEXPOSE:
SendFramebufferUpdateRequest(cl, 0, 0,
cl->width, cl->height, FALSE);
break;
#endif
case SDL_MOUSEBUTTONUP:
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEMOTION:
{
int x, y, state, i;
if (viewOnly)
break;
if (e->type == SDL_MOUSEMOTION) {
x = e->motion.x;
y = e->motion.y;
state = e->motion.state;
}
else {
x = e->button.x;
y = e->button.y;
state = e->button.button;
for (i = 0; buttonMapping[i].sdl; i++)
if (state == buttonMapping[i].sdl) {
state = buttonMapping[i].rfb;
if (e->type == SDL_MOUSEBUTTONDOWN)
buttonMask |= state;
else
buttonMask &= ~state;
break;
}
}
if (sdlPixels) {
x = x * cl->width / realWidth;
y = y * cl->height / realHeight;
}
SendPointerEvent(cl, x, y, buttonMask);
buttonMask &= ~(rfbButton4Mask | rfbButton5Mask);
break;
}
case SDL_KEYUP:
case SDL_KEYDOWN:
if (viewOnly)
break;
SendKeyEvent(cl, SDL_key2rfbKeySym(&e->key),
e->type == SDL_KEYDOWN ? TRUE : FALSE);
if (e->key.keysym.sym == SDLK_RALT)
rightAltKeyDown = e->type == SDL_KEYDOWN;
if (e->key.keysym.sym == SDLK_LALT)
leftAltKeyDown = e->type == SDL_KEYDOWN;
break;
case SDL_QUIT:
if(listenLoop)
{
cleanup(cl);
return FALSE;
}
else
{
rfbClientCleanup(cl);
exit(0);
}
case SDL_ACTIVEEVENT:
if (!e->active.gain && rightAltKeyDown) {
SendKeyEvent(cl, XK_Alt_R, FALSE);
rightAltKeyDown = FALSE;
rfbClientLog("released right Alt key\n");
}
if (!e->active.gain && leftAltKeyDown) {
SendKeyEvent(cl, XK_Alt_L, FALSE);
leftAltKeyDown = FALSE;
rfbClientLog("released left Alt key\n");
}
if (e->active.gain && lost_scrap()) {
static char *data = NULL;
static int len = 0;
get_scrap(T('T', 'E', 'X', 'T'), &len, &data);
if (len)
SendClientCutText(cl, data, len);
}
break;
case SDL_SYSWMEVENT:
clipboard_filter(e);
break;
case SDL_VIDEORESIZE:
setRealDimension(cl, e->resize.w, e->resize.h);
break;
default:
rfbClientLog("ignore SDL event: 0x%x\n", e->type);
}
return TRUE;
}
static void got_selection(rfbClient *cl, const char *text, int len)
{
put_scrap(T('T', 'E', 'X', 'T'), len, text);
}
#ifdef mac
#define main SDLmain
#endif
int main(int argc,char** argv) {
rfbClient* cl;
int i, j;
SDL_Event e;
#ifdef LOG_TO_FILE
rfbClientLog=rfbClientErr=log_to_file;
#endif
for (i = 1, j = 1; i < argc; i++)
if (!strcmp(argv[i], "-viewonly"))
viewOnly = 1;
else if (!strcmp(argv[i], "-resizable"))
enableResizable = 1;
else if (!strcmp(argv[i], "-listen")) {
listenLoop = 1;
argv[i] = "-listennofork";
++j;
}
else {
if (i != j)
argv[j] = argv[i];
j++;
}
argc = j;
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);
SDL_EnableUNICODE(1);
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,
SDL_DEFAULT_REPEAT_INTERVAL);
atexit(SDL_Quit);
signal(SIGINT, exit);
do {
/* 16-bit: cl=rfbGetClient(5,3,2); */
cl=rfbGetClient(8,3,4);
cl->MallocFrameBuffer=resize;
cl->canHandleNewFBSize = TRUE;
cl->GotFrameBufferUpdate=update;
cl->HandleKeyboardLedState=kbd_leds;
cl->HandleTextChat=text_chat;
cl->GotXCutText = got_selection;
cl->listenPort = LISTEN_PORT_OFFSET;
if(!rfbInitClient(cl,&argc,argv))
{
cl = NULL; /* rfbInitClient has already freed the client struct */
cleanup(cl);
break;
}
init_scrap();
while(1) {
if(SDL_PollEvent(&e)) {
/*
handleSDLEvent() return 0 if user requested window close.
In this case, handleSDLEvent() will have called cleanup().
*/
if(!handleSDLEvent(cl, &e))
break;
}
else {
i=WaitForMessage(cl,500);
if(i<0)
{
cleanup(cl);
break;
}
if(i)
if(!HandleRFBServerMessage(cl))
{
cleanup(cl);
break;
}
}
}
}
while(listenLoop);
return 0;
}

View File

@ -0,0 +1,99 @@
/* A simple example of an RFB client */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <rfb/rfbclient.h>
static void HandleRect(rfbClient* client, int x, int y, int w, int h) {
}
/*
* The client part of the back channel extension example.
*
*/
#define rfbBackChannel 155
typedef struct backChannelMsg {
uint8_t type;
uint8_t pad1;
uint16_t pad2;
uint32_t size;
} backChannelMsg;
static void sendMessage(rfbClient* client, char* text)
{
backChannelMsg msg;
uint32_t length = strlen(text)+1;
msg.type = rfbBackChannel;
msg.size = rfbClientSwap32IfLE(length);
if(!WriteToRFBServer(client, (char*)&msg, sizeof(msg)) ||
!WriteToRFBServer(client, text, length)) {
rfbClientLog("enableBackChannel: write error (%d: %s)", errno, strerror(errno));
}
}
static rfbBool handleBackChannelMessage(rfbClient* client,
rfbServerToClientMsg* message)
{
backChannelMsg msg;
char* text;
if(message->type != rfbBackChannel)
return FALSE;
rfbClientSetClientData(client, sendMessage, sendMessage);
if(!ReadFromRFBServer(client, ((char*)&msg)+1, sizeof(msg)-1))
return TRUE;
msg.size = rfbClientSwap32IfLE(msg.size);
text = malloc(msg.size);
if(!ReadFromRFBServer(client, text, msg.size)) {
free(text);
return TRUE;
}
rfbClientLog("got back channel message: %s\n", text);
free(text);
return TRUE;
}
static int backChannelEncodings[] = { rfbBackChannel, 0 };
static rfbClientProtocolExtension backChannel = {
backChannelEncodings, /* encodings */
NULL, /* handleEncoding */
handleBackChannelMessage, /* handleMessage */
NULL /* next extension */
};
int
main(int argc, char **argv)
{
rfbClient* client = rfbGetClient(8,3,4);
client->GotFrameBufferUpdate = HandleRect;
rfbClientRegisterExtension(&backChannel);
if (!rfbInitClient(client,&argc,argv))
return 1;
while (1) {
/* After each idle second, send a message */
if(WaitForMessage(client,1000000)>0)
HandleRFBServerMessage(client);
else if(rfbClientGetClientData(client, sendMessage))
sendMessage(client, "Dear Server,\n"
"thank you for understanding "
"back channel messages!");
}
rfbClientCleanup(client);
return 0;
}

View File

@ -0,0 +1,97 @@
/* A simple example of an RFB client */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <rfb/rfbclient.h>
static void PrintRect(rfbClient* client, int x, int y, int w, int h) {
rfbClientLog("Received an update for %d,%d,%d,%d.\n",x,y,w,h);
}
static void SaveFramebufferAsPPM(rfbClient* client, int x, int y, int w, int h) {
static time_t t=0,t1;
FILE* f;
int i,j;
rfbPixelFormat* pf=&client->format;
int bpp=pf->bitsPerPixel/8;
int row_stride=client->width*bpp;
/* save one picture only if the last is older than 2 seconds */
t1=time(NULL);
if(t1-t>2)
t=t1;
else
return;
/* assert bpp=4 */
if(bpp!=4 && bpp!=2) {
rfbClientLog("bpp = %d (!=4)\n",bpp);
return;
}
f=fopen("framebuffer.ppm","wb");
if(!f) {
rfbClientErr("Could not open framebuffer.ppm\n");
return;
}
fprintf(f,"P6\n# %s\n%d %d\n255\n",client->desktopName,client->width,client->height);
for(j=0;j<client->height*row_stride;j+=row_stride)
for(i=0;i<client->width*bpp;i+=bpp) {
unsigned char* p=client->frameBuffer+j+i;
unsigned int v;
if(bpp==4)
v=*(unsigned int*)p;
else if(bpp==2)
v=*(unsigned short*)p;
else
v=*(unsigned char*)p;
fputc((v>>pf->redShift)*256/(pf->redMax+1),f);
fputc((v>>pf->greenShift)*256/(pf->greenMax+1),f);
fputc((v>>pf->blueShift)*256/(pf->blueMax+1),f);
}
fclose(f);
}
int
main(int argc, char **argv)
{
rfbClient* client = rfbGetClient(8,3,4);
time_t t=time(NULL);
if(argc>1 && !strcmp("-print",argv[1])) {
client->GotFrameBufferUpdate = PrintRect;
argv[1]=argv[0]; argv++; argc--;
} else
client->GotFrameBufferUpdate = SaveFramebufferAsPPM;
/* The -listen option is used to make us a daemon process which listens for
incoming connections from servers, rather than actively connecting to a
given server. The -tunnel and -via options are useful to create
connections tunneled via SSH port forwarding. We must test for the
-listen option before invoking any Xt functions - this is because we use
forking, and Xt doesn't seem to cope with forking very well. For -listen
option, when a successful incoming connection has been accepted,
listenForIncomingConnections() returns, setting the listenSpecified
flag. */
if (!rfbInitClient(client,&argc,argv))
return 1;
/* TODO: better wait for update completion */
while (time(NULL)-t<5) {
static int i=0;
fprintf(stderr,"\r%d",i++);
if(WaitForMessage(client,50)<0)
break;
if(!HandleRFBServerMessage(client))
break;
}
rfbClientCleanup(client);
return 0;
}

View File

@ -0,0 +1,558 @@
/* Handle clipboard text and data in arbitrary formats */
#include <stdio.h>
#include <limits.h>
#ifdef WIN32
#include <SDL.h>
#include <SDL_syswm.h>
#else
#include <SDL/SDL.h>
#include <SDL/SDL_syswm.h>
#endif
#include "scrap.h"
#include "rfb/rfbconfig.h"
/* Determine what type of clipboard we are using */
#if defined(__unix__) && !defined(__QNXNTO__) && defined(LIBVNCSERVER_HAVE_X11)
#define X11_SCRAP
#elif defined(__WIN32__)
#define WIN_SCRAP
#elif defined(__QNXNTO__)
#define QNX_SCRAP
#else
#warning Unknown window manager for clipboard handling
#endif /* scrap type */
/* System dependent data types */
#if defined(X11_SCRAP)
typedef Atom scrap_type;
static Atom XA_TARGETS, XA_TEXT, XA_COMPOUND_TEXT, XA_UTF8_STRING;
#elif defined(WIN_SCRAP)
typedef UINT scrap_type;
#elif defined(QNX_SCRAP)
typedef uint32_t scrap_type;
#define Ph_CL_TEXT T('T', 'E', 'X', 'T')
#else
typedef int scrap_type;
#endif /* scrap type */
/* System dependent variables */
#if defined(X11_SCRAP)
static Display *SDL_Display;
static Window SDL_Window;
static void (*Lock_Display)(void);
static void (*Unlock_Display)(void);
static Atom XA_UTF8_STRING;
#elif defined(WIN_SCRAP)
static HWND SDL_Window;
#elif defined(QNX_SCRAP)
static unsigned short InputGroup;
#endif /* scrap type */
#define FORMAT_PREFIX "SDL_scrap_0x"
static scrap_type convert_format(int type)
{
switch (type) {
case T('T', 'E', 'X', 'T'):
#if defined(X11_SCRAP)
return XA_UTF8_STRING ? XA_UTF8_STRING : XA_STRING;
#elif defined(WIN_SCRAP)
return CF_TEXT;
#elif defined(QNX_SCRAP)
return Ph_CL_TEXT;
#endif /* scrap type */
default:
{
char format[sizeof(FORMAT_PREFIX)+8+1];
sprintf(format, "%s%08lx", FORMAT_PREFIX,
(unsigned long)type);
#if defined(X11_SCRAP)
return XInternAtom(SDL_Display, format, False);
#elif defined(WIN_SCRAP)
return RegisterClipboardFormat(format);
#endif /* scrap type */
}
}
}
/* Convert internal data to scrap format */
static int convert_data(int type, char *dst, const char *src, int srclen)
{
int dstlen;
dstlen = 0;
switch (type) {
case T('T', 'E', 'X', 'T'):
if (dst) {
while (--srclen >= 0) {
#if defined(__unix__)
if (*src == '\r') {
*dst++ = '\n';
++dstlen;
}
else
#elif defined(__WIN32__)
if (*src == '\r') {
*dst++ = '\r';
++dstlen;
*dst++ = '\n';
++dstlen;
}
else
#endif
{
*dst++ = *src;
++dstlen;
}
++src;
}
*dst = '\0';
++dstlen;
}
else {
while (--srclen >= 0) {
#if defined(__unix__)
if (*src == '\r')
++dstlen;
else
#elif defined(__WIN32__)
if (*src == '\r') {
++dstlen;
++dstlen;
}
else
#endif
{
++dstlen;
}
++src;
}
++dstlen;
}
break;
default:
if (dst) {
*(int *)dst = srclen;
dst += sizeof(int);
memcpy(dst, src, srclen);
}
dstlen = sizeof(int)+srclen;
break;
}
return(dstlen);
}
/* Convert scrap data to internal format */
static int convert_scrap(int type, char *dst, char *src, int srclen)
{
int dstlen;
dstlen = 0;
switch (type) {
case T('T', 'E', 'X', 'T'):
{
if (srclen == 0)
srclen = strlen(src);
if (dst) {
while (--srclen >= 0) {
#if defined(__WIN32__)
if (*src == '\r')
/* drop extraneous '\r' */;
else
#endif
if (*src == '\n') {
*dst++ = '\r';
++dstlen;
}
else {
*dst++ = *src;
++dstlen;
}
++src;
}
*dst = '\0';
++dstlen;
}
else {
while (--srclen >= 0) {
#if defined(__WIN32__)
/* drop extraneous '\r' */;
if (*src != '\r')
#endif
++dstlen;
++src;
}
++dstlen;
}
break;
}
default:
dstlen = *(int *)src;
if (dst)
memcpy(dst, src + sizeof(int),
srclen ? srclen - sizeof(int) : dstlen);
break;
}
return dstlen;
}
int init_scrap(void)
{
SDL_SysWMinfo info;
int retval;
/* Grab the window manager specific information */
retval = -1;
SDL_SetError("SDL is not running on known window manager");
SDL_VERSION(&info.version);
if (SDL_GetWMInfo(&info)) {
/* Save the information for later use */
#if defined(X11_SCRAP)
if (info.subsystem == SDL_SYSWM_X11) {
SDL_Display = info.info.x11.display;
SDL_Window = info.info.x11.window;
Lock_Display = info.info.x11.lock_func;
Unlock_Display = info.info.x11.unlock_func;
/* Enable the special window hook events */
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
SDL_SetEventFilter(clipboard_filter);
XA_TARGETS = XInternAtom(SDL_Display, "TARGETS", False);
XA_TEXT = XInternAtom(SDL_Display, "TEXT", False);
XA_COMPOUND_TEXT = XInternAtom(SDL_Display,
"COMPOUND_TEXT", False);
XA_UTF8_STRING = XInternAtom(SDL_Display,
"UTF8_STRING", False);
retval = 0;
}
else
SDL_SetError("SDL is not running on X11");
#elif defined(WIN_SCRAP)
SDL_Window = info.window;
retval = 0;
#elif defined(QNX_SCRAP)
InputGroup = PhInputGroup(NULL);
retval = 0;
#endif /* scrap type */
}
return(retval);
}
int lost_scrap(void)
{
int retval;
#if defined(X11_SCRAP)
if (Lock_Display)
Lock_Display();
retval = (XGetSelectionOwner(SDL_Display, XA_PRIMARY) != SDL_Window);
if (Unlock_Display)
Unlock_Display();
#elif defined(WIN_SCRAP)
retval = (GetClipboardOwner() != SDL_Window);
#elif defined(QNX_SCRAP)
retval = (PhInputGroup(NULL) != InputGroup);
#endif /* scrap type */
return(retval);
}
void put_scrap(int type, int srclen, const char *src)
{
scrap_type format;
int dstlen;
char *dst;
format = convert_format(type);
dstlen = convert_data(type, NULL, src, srclen);
#if defined(X11_SCRAP)
dst = (char *)malloc(dstlen);
if (dst != NULL) {
if (Lock_Display)
Lock_Display();
convert_data(type, dst, src, srclen);
XChangeProperty(SDL_Display, DefaultRootWindow(SDL_Display),
XA_CUT_BUFFER0, format, 8, PropModeReplace,
(unsigned char *)dst, dstlen);
free(dst);
if (lost_scrap())
XSetSelectionOwner(SDL_Display, XA_PRIMARY,
SDL_Window, CurrentTime);
if (Unlock_Display)
Unlock_Display();
}
#elif defined(WIN_SCRAP)
if (OpenClipboard(SDL_Window)) {
HANDLE hMem;
hMem = GlobalAlloc((GMEM_MOVEABLE|GMEM_DDESHARE), dstlen);
if (hMem != NULL) {
dst = (char *)GlobalLock(hMem);
convert_data(type, dst, src, srclen);
GlobalUnlock(hMem);
EmptyClipboard();
SetClipboardData(format, hMem);
}
CloseClipboard();
}
#elif defined(QNX_SCRAP)
#if (_NTO_VERSION < 620) /* before 6.2.0 releases */
#define PhClipboardHdr PhClipHeader
#endif
{
PhClipboardHdr clheader = { Ph_CLIPBOARD_TYPE_TEXT, 0, NULL };
int* cldata;
int status;
dst = (char *)malloc(dstlen+4);
if (dst != NULL) {
cldata = (int*)dst;
*cldata = type;
convert_data(type, dst+4, src, srclen);
clheader.data = dst;
#if (_NTO_VERSION < 620) /* before 6.2.0 releases */
if (dstlen > 65535)
/* maximum photon clipboard size :(*/
clheader.length = 65535;
else
#endif
clheader.length = dstlen+4;
status = PhClipboardCopy(InputGroup, 1, &clheader);
if (status == -1)
fprintf(stderr,
"Photon: copy to clipboard failed!\n");
free(dst);
}
}
#endif /* scrap type */
}
void get_scrap(int type, int *dstlen, char **dst)
{
scrap_type format;
*dstlen = 0;
format = convert_format(type);
#if defined(X11_SCRAP)
{
Window owner;
Atom selection;
Atom seln_type;
int seln_format;
unsigned long nbytes;
unsigned long overflow;
char *src;
if (Lock_Display)
Lock_Display();
owner = XGetSelectionOwner(SDL_Display, XA_PRIMARY);
if (Unlock_Display)
Unlock_Display();
if ((owner == None) || (owner == SDL_Window)) {
owner = DefaultRootWindow(SDL_Display);
selection = XA_CUT_BUFFER0;
}
else {
int selection_response = 0;
SDL_Event event;
owner = SDL_Window;
if (Lock_Display)
Lock_Display();
selection = XInternAtom(SDL_Display, "SDL_SELECTION",
False);
XConvertSelection(SDL_Display, XA_PRIMARY, format,
selection, owner, CurrentTime);
if (Unlock_Display)
Unlock_Display();
while (!selection_response) {
SDL_WaitEvent(&event);
if (event.type == SDL_SYSWMEVENT) {
XEvent xevent =
event.syswm.msg->event.xevent;
if ((xevent.type == SelectionNotify) &&
(xevent.xselection.requestor
== owner))
selection_response = 1;
}
}
}
if (Lock_Display)
Lock_Display();
if (XGetWindowProperty(SDL_Display, owner, selection,
0, INT_MAX/4, False, format, &seln_type,
&seln_format, &nbytes, &overflow,
(unsigned char **)&src) == Success) {
if (seln_type == format) {
*dstlen = convert_scrap(type, NULL,
src, nbytes);
*dst = (char *)realloc(*dst, *dstlen);
if (*dst == NULL)
*dstlen = 0;
else
convert_scrap(type, *dst, src, nbytes);
}
XFree(src);
}
}
if (Unlock_Display)
Unlock_Display();
#elif defined(WIN_SCRAP)
if (IsClipboardFormatAvailable(format) && OpenClipboard(SDL_Window)) {
HANDLE hMem;
char *src;
hMem = GetClipboardData(format);
if (hMem != NULL) {
src = (char *)GlobalLock(hMem);
*dstlen = convert_scrap(type, NULL, src, 0);
*dst = (char *)realloc(*dst, *dstlen);
if (*dst == NULL)
*dstlen = 0;
else
convert_scrap(type, *dst, src, 0);
GlobalUnlock(hMem);
}
CloseClipboard();
}
#elif defined(QNX_SCRAP)
#if (_NTO_VERSION < 620) /* before 6.2.0 releases */
{
void* clhandle;
PhClipHeader* clheader;
int* cldata;
clhandle = PhClipboardPasteStart(InputGroup);
if (clhandle != NULL) {
clheader = PhClipboardPasteType(clhandle,
Ph_CLIPBOARD_TYPE_TEXT);
if (clheader != NULL) {
cldata = clheader->data;
if ((clheader->length>4) && (*cldata == type)) {
*dstlen = convert_scrap(type, NULL,
(char*)clheader->data+4,
clheader->length-4);
*dst = (char *)realloc(*dst, *dstlen);
if (*dst == NULL)
*dstlen = 0;
else
convert_scrap(type, *dst,
(char*)clheader->data+4,
clheader->length-4);
}
}
PhClipboardPasteFinish(clhandle);
}
}
#else /* 6.2.0 and 6.2.1 and future releases */
{
void* clhandle;
PhClipboardHdr* clheader;
int* cldata;
clheader=PhClipboardRead(InputGroup, Ph_CLIPBOARD_TYPE_TEXT);
if (clheader!=NULL) {
cldata=clheader->data;
if ((clheader->length>4) && (*cldata==type)) {
*dstlen = convert_scrap(type, NULL,
(char*)clheader->data+4,
clheader->length-4);
*dst = (char *)realloc(*dst, *dstlen);
if (*dst == NULL)
*dstlen = 0;
else
convert_scrap(type, *dst,
(char*)clheader->data+4,
clheader->length-4);
}
}
}
#endif
#endif /* scrap type */
}
int clipboard_filter(const SDL_Event *event)
{
#if defined(X11_SCRAP)
/* Post all non-window manager specific events */
if (event->type != SDL_SYSWMEVENT)
return(1);
/* Handle window-manager specific clipboard events */
switch (event->syswm.msg->event.xevent.type) {
/* Copy the selection from XA_CUT_BUFFER0 to the requested property */
case SelectionRequest: {
XSelectionRequestEvent *req;
XEvent sevent;
int seln_format;
unsigned long nbytes;
unsigned long overflow;
unsigned char *seln_data;
req = &event->syswm.msg->event.xevent.xselectionrequest;
if (req->target == XA_TARGETS) {
Atom supported[] = {
XA_TEXT, XA_COMPOUND_TEXT, XA_UTF8_STRING,
XA_TARGETS, XA_STRING
};
XEvent response;
XChangeProperty(SDL_Display, req->requestor,
req->property, req->target, 32, PropModeReplace,
(unsigned char*)supported,
sizeof(supported) / sizeof(supported[0]));
response.xselection.property=None;
response.xselection.type= SelectionNotify;
response.xselection.display= req->display;
response.xselection.requestor= req->requestor;
response.xselection.selection=req->selection;
response.xselection.target= req->target;
response.xselection.time = req->time;
XSendEvent (SDL_Display, req->requestor,0,0,&response);
XFlush (SDL_Display);
return 1;
}
sevent.xselection.type = SelectionNotify;
sevent.xselection.display = req->display;
sevent.xselection.selection = req->selection;
sevent.xselection.target = None;
sevent.xselection.property = req->property;
sevent.xselection.requestor = req->requestor;
sevent.xselection.time = req->time;
if (XGetWindowProperty(SDL_Display,
DefaultRootWindow(SDL_Display), XA_CUT_BUFFER0,
0, INT_MAX/4, False, req->target,
&sevent.xselection.target, &seln_format,
&nbytes, &overflow, &seln_data) == Success) {
if (sevent.xselection.target == req->target) {
if (sevent.xselection.target == XA_STRING &&
nbytes > 0 &&
seln_data[nbytes-1] == '\0')
--nbytes;
XChangeProperty(SDL_Display, req->requestor,
req->property, sevent.xselection.target,
seln_format, PropModeReplace,
seln_data, nbytes);
sevent.xselection.property = req->property;
}
XFree(seln_data);
}
XSendEvent(SDL_Display,req->requestor,False,0,&sevent);
XSync(SDL_Display, False);
break;
}
}
/* Post the event for X11 clipboard reading above */
#endif /* X11_SCRAP */
return(1);
}

View File

@ -0,0 +1,18 @@
/* Handle clipboard text and data in arbitrary formats */
/* Miscellaneous defines */
#define T(A, B, C, D) (int)((A<<24)|(B<<16)|(C<<8)|(D<<0))
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
extern int init_scrap(void);
extern int lost_scrap(void);
extern void put_scrap(int type, int srclen, const char *src);
extern void get_scrap(int type, int *dstlen, char **dst);
extern int clipboard_filter(const SDL_Event *event);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -0,0 +1,435 @@
/*
* Simple movie writer for vnc; based on Libavformat API example from FFMPEG
*
* Copyright (c) 2003 Fabrice Bellard, 2004 Johannes E. Schindelin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <math.h>
#ifndef M_PI
#define M_PI 3.1415926535897931
#endif
#include "avformat.h"
#include <rfb/rfbclient.h>
#define STREAM_FRAME_RATE 25 /* 25 images/s */
/**************************************************************/
/* video output */
AVFrame *picture, *tmp_picture;
uint8_t *video_outbuf;
int frame_count, video_outbuf_size;
/* add a video output stream */
AVStream *add_video_stream(AVFormatContext *oc, int codec_id, int w, int h)
{
AVCodecContext *c;
AVStream *st;
st = av_new_stream(oc, 0);
if (!st) {
fprintf(stderr, "Could not alloc stream\n");
exit(1);
}
#if LIBAVFORMAT_BUILD<4629
c = &st->codec;
#else
c = st->codec;
#endif
c->codec_id = codec_id;
c->codec_type = CODEC_TYPE_VIDEO;
/* put sample parameters */
c->bit_rate = 800000;
/* resolution must be a multiple of two */
c->width = w;
c->height = h;
/* frames per second */
#if LIBAVCODEC_BUILD<4754
c->frame_rate = STREAM_FRAME_RATE;
c->frame_rate_base = 1;
#else
c->time_base.den = STREAM_FRAME_RATE;
c->time_base.num = 1;
c->pix_fmt = PIX_FMT_YUV420P;
#endif
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
if (c->codec_id == CODEC_ID_MPEG2VIDEO) {
/* just for testing, we also add B frames */
c->max_b_frames = 2;
}
if (c->codec_id == CODEC_ID_MPEG1VIDEO){
/* needed to avoid using macroblocks in which some coeffs overflow
this doesnt happen with normal video, it just happens here as the
motion of the chroma plane doesnt match the luma plane */
c->mb_decision=2;
}
/* some formats want stream headers to be seperate */
if(!strcmp(oc->oformat->name, "mp4") || !strcmp(oc->oformat->name, "mov") || !strcmp(oc->oformat->name, "3gp"))
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
return st;
}
AVFrame *alloc_picture(int pix_fmt, int width, int height)
{
AVFrame *picture;
uint8_t *picture_buf;
int size;
picture = avcodec_alloc_frame();
if (!picture)
return NULL;
size = avpicture_get_size(pix_fmt, width, height);
picture_buf = malloc(size);
if (!picture_buf) {
av_free(picture);
return NULL;
}
avpicture_fill((AVPicture *)picture, picture_buf,
pix_fmt, width, height);
return picture;
}
void open_video(AVFormatContext *oc, AVStream *st)
{
AVCodec *codec;
AVCodecContext *c;
#if LIBAVFORMAT_BUILD<4629
c = &st->codec;
#else
c = st->codec;
#endif
/* find the video encoder */
codec = avcodec_find_encoder(c->codec_id);
if (!codec) {
fprintf(stderr, "codec not found\n");
exit(1);
}
/* open the codec */
if (avcodec_open(c, codec) < 0) {
fprintf(stderr, "could not open codec\n");
exit(1);
}
video_outbuf = NULL;
if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) {
/* allocate output buffer */
/* XXX: API change will be done */
video_outbuf_size = 200000;
video_outbuf = malloc(video_outbuf_size);
}
/* allocate the encoded raw picture */
picture = alloc_picture(c->pix_fmt, c->width, c->height);
if (!picture) {
fprintf(stderr, "Could not allocate picture\n");
exit(1);
}
/* if the output format is not RGB565, then a temporary RGB565
picture is needed too. It is then converted to the required
output format */
tmp_picture = NULL;
if (c->pix_fmt != PIX_FMT_RGB565) {
tmp_picture = alloc_picture(PIX_FMT_RGB565, c->width, c->height);
if (!tmp_picture) {
fprintf(stderr, "Could not allocate temporary picture\n");
exit(1);
}
}
}
void write_video_frame(AVFormatContext *oc, AVStream *st)
{
int out_size, ret;
AVCodecContext *c;
AVFrame *picture_ptr;
#if LIBAVFORMAT_BUILD<4629
c = &st->codec;
#else
c = st->codec;
#endif
if (c->pix_fmt != PIX_FMT_RGB565) {
/* as we only generate a RGB565 picture, we must convert it
to the codec pixel format if needed */
img_convert((AVPicture *)picture, c->pix_fmt,
(AVPicture *)tmp_picture, PIX_FMT_RGB565,
c->width, c->height);
}
picture_ptr = picture;
if (oc->oformat->flags & AVFMT_RAWPICTURE) {
/* raw video case. The API will change slightly in the near
futur for that */
AVPacket pkt;
av_init_packet(&pkt);
pkt.flags |= PKT_FLAG_KEY;
pkt.stream_index= st->index;
pkt.data= (uint8_t *)picture_ptr;
pkt.size= sizeof(AVPicture);
ret = av_write_frame(oc, &pkt);
} else {
/* encode the image */
out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture_ptr);
/* if zero size, it means the image was buffered */
if (out_size != 0) {
AVPacket pkt;
av_init_packet(&pkt);
pkt.pts= c->coded_frame->pts;
if(c->coded_frame->key_frame)
pkt.flags |= PKT_FLAG_KEY;
pkt.stream_index= st->index;
pkt.data= video_outbuf;
pkt.size= out_size;
/* write the compressed frame in the media file */
ret = av_write_frame(oc, &pkt);
} else {
ret = 0;
}
}
if (ret != 0) {
fprintf(stderr, "Error while writing video frame\n");
exit(1);
}
frame_count++;
}
void close_video(AVFormatContext *oc, AVStream *st)
{
avcodec_close(st->codec);
av_free(picture->data[0]);
av_free(picture);
if (tmp_picture) {
av_free(tmp_picture->data[0]);
av_free(tmp_picture);
}
av_free(video_outbuf);
}
static const char *filename;
static AVOutputFormat *fmt;
static AVFormatContext *oc;
static AVStream *video_st;
static double video_pts;
static int movie_open(int w, int h) {
if (fmt->video_codec != CODEC_ID_NONE) {
video_st = add_video_stream(oc, fmt->video_codec, w, h);
} else
return 1;
/* set the output parameters (must be done even if no
parameters). */
if (av_set_parameters(oc, NULL) < 0) {
fprintf(stderr, "Invalid output format parameters\n");
return 2;
}
dump_format(oc, 0, filename, 1);
/* now that all the parameters are set, we can open the audio and
video codecs and allocate the necessary encode buffers */
if (video_st)
open_video(oc, video_st);
/* open the output file, if needed */
if (!(fmt->flags & AVFMT_NOFILE)) {
if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) {
fprintf(stderr, "Could not open '%s'\n", filename);
return 3;
}
}
/* write the stream header, if any */
av_write_header(oc);
return 0;
}
static int movie_close() {
int i;
/* close each codec */
close_video(oc, video_st);
/* write the trailer, if any */
av_write_trailer(oc);
/* free the streams */
for(i = 0; i < oc->nb_streams; i++) {
av_freep(&oc->streams[i]);
}
if (!(fmt->flags & AVFMT_NOFILE)) {
/* close the output file */
url_fclose(&oc->pb);
}
/* free the stream */
av_free(oc);
}
static rfbBool quit=FALSE;
static void signal_handler(int signal) {
fprintf(stderr,"Cleaning up.\n");
quit=TRUE;
}
/**************************************************************/
/* VNC callback functions */
static rfbBool resize(rfbClient* client) {
static rfbBool first=TRUE;
if(!first) {
movie_close();
perror("I don't know yet how to change resolutions!\n");
}
movie_open(client->width, client->height);
signal(SIGINT,signal_handler);
if(tmp_picture)
client->frameBuffer=tmp_picture->data[0];
else
client->frameBuffer=picture->data[0];
return TRUE;
}
static void update(rfbClient* client,int x,int y,int w,int h) {
}
/**************************************************************/
/* media file output */
int main(int argc, char **argv)
{
time_t stop=0;
rfbClient* client;
int i,j;
/* get a vnc client structure (don't connect yet). */
client = rfbGetClient(5,3,2);
client->format.redShift=11; client->format.redMax=31;
client->format.greenShift=5; client->format.greenMax=63;
client->format.blueShift=0; client->format.blueMax=31;
/* initialize libavcodec, and register all codecs and formats */
av_register_all();
if(!strncmp(argv[argc-1],":",1) ||
!strncmp(argv[argc-1],"127.0.0.1",9) ||
!strncmp(argv[argc-1],"localhost",9))
client->appData.encodingsString="raw";
filename=0;
for(i=1;i<argc;i++) {
j=i;
if(argc>i+1 && !strcmp("-o",argv[i])) {
filename=argv[2];
j+=2;
} else if(argc>i+1 && !strcmp("-t",argv[i])) {
stop=time(0)+atoi(argv[i+1]);
j+=2;
}
if(j>i) {
argc-=j-i;
memmove(argv+i,argv+j,(argc-i)*sizeof(char*));
i--;
}
}
/* auto detect the output format from the name. default is
mpeg. */
fmt = filename?guess_format(NULL, filename, NULL):0;
if (!fmt) {
printf("Could not deduce output format from file extension: using MPEG.\n");
fmt = guess_format("mpeg", NULL, NULL);
}
if (!fmt) {
fprintf(stderr, "Could not find suitable output format\n");
exit(1);
}
/* allocate the output media context */
oc = av_alloc_format_context();
if (!oc) {
fprintf(stderr, "Memory error\n");
exit(1);
}
oc->oformat = fmt;
snprintf(oc->filename, sizeof(oc->filename), "%s", filename);
/* add the audio and video streams using the default format codecs
and initialize the codecs */
video_st = NULL;
/* open VNC connection */
client->MallocFrameBuffer=resize;
client->GotFrameBufferUpdate=update;
if(!rfbInitClient(client,&argc,argv)) {
printf("usage: %s [-o output_file] [-t seconds] server:port\n"
"Shoot a movie from a VNC server.\n", argv[0]);
exit(1);
}
if(client->serverPort==-1)
client->vncRec->doNotSleep = TRUE; /* vncrec playback */
/* main loop */
while(!quit) {
int i=WaitForMessage(client,1000000/STREAM_FRAME_RATE);
if(i<0) {
movie_close();
return 0;
}
if(i)
if(!HandleRFBServerMessage(client))
quit=TRUE;
else {
/* compute current audio and video time */
video_pts = (double)video_st->pts.val * video_st->time_base.num / video_st->time_base.den;
/* write interleaved audio and video frames */
write_video_frame(oc, video_st);
}
if(stop!=0 && stop<time(0))
quit=TRUE;
}
movie_close();
return 0;
}

View File

@ -0,0 +1,894 @@
# Process this file with autoconf to produce a configure script.
AC_INIT(LibVNCServer, 0.9.7, http://sourceforge.net/projects/libvncserver)
AM_INIT_AUTOMAKE(LibVNCServer, 0.9.7)
AM_CONFIG_HEADER(rfbconfig.h)
AX_PREFIX_CONFIG_H([rfb/rfbconfig.h])
# Checks for programs.
AC_PROG_CC
AM_PROG_CC_C_O
if test -z "$CC"; then
CCLD="\$(CC)"
else
CCLD="$CC"
fi
test "x$GCC" = "xyes" && CFLAGS="$CFLAGS -Wall"
AC_PROG_MAKE_SET
AC_PROG_LIBTOOL
AC_PATH_PROG([AR], [ar], [/usr/bin/ar],
[$PATH:/usr/ccs/bin])
# Options
AH_TEMPLATE(WITH_TIGHTVNC_FILETRANSFER, [Disable TightVNCFileTransfer protocol])
AC_ARG_WITH(tightvnc-filetransfer,
[ --without-filetransfer disable TightVNC file transfer protocol],
, [ with_tightvnc_filetransfer=yes ])
# AC_DEFINE moved to after libpthread check.
# WebSockets support
AC_CHECK_LIB(resolv, __b64_ntop, HAVE_B64="true", HAVE_B64="false")
AH_TEMPLATE(WITH_WEBSOCKETS, [Disable WebSockets support])
AC_ARG_WITH(websockets,
[ --without-websockets disable WebSockets support],
, [ with_websockets=yes ])
# AC_DEFINE moved to after libresolve check.
AH_TEMPLATE(ALLOW24BPP, [Enable 24 bit per pixel in native framebuffer])
AC_ARG_WITH(24bpp,
[ --without-24bpp disable 24 bpp framebuffers],
, [ with_24bpp=yes ])
if test "x$with_24bpp" = "xyes"; then
AC_DEFINE(ALLOW24BPP)
fi
AH_TEMPLATE(FFMPEG, [Use ffmpeg (for vnc2mpg)])
AC_ARG_WITH(ffmpeg,
[ --with-ffmpeg=dir set ffmpeg home directory],,)
AC_SUBST(with_ffmpeg)
AM_CONDITIONAL(WITH_FFMPEG, test ! -z "$with_ffmpeg")
if test ! -z "$with_ffmpeg"; then
AC_CHECK_LIB(mp3lame, lame_init, HAVE_MP3LAME="true", HAVE_MP3LAME="false" )
fi
AM_CONDITIONAL(HAVE_MP3LAME, test "$HAVE_MP3LAME" = "true")
# Seem to need this dummy here to induce the 'checking for egrep... grep -E', etc.
# before it seemed to be inside the with_jpeg conditional.
AC_CHECK_HEADER(thenonexistentheader.h, HAVE_THENONEXISTENTHEADER_H="true")
# Checks for X libraries
HAVE_X11="false"
AC_PATH_XTRA
AH_TEMPLATE(HAVE_X11, [X11 build environment present])
# See if we are to build x11vnc:
AH_TEMPLATE(HAVE_SYSTEM_LIBVNCSERVER, [Use the system libvncserver build environment for x11vnc.])
AC_ARG_WITH(system-libvncserver,
[ --with-system-libvncserver use installed libvncserver for x11vnc]
[ --with-system-libvncserver=DIR use libvncserver installed in DIR for x11vnc],,)
AC_ARG_WITH(x11vnc,
[ --with-x11vnc configure for building the x11vnc subdir (if present)]
[ you will need to cd to x11vnc and run 'make' etc.],,)
if test ! -z "$with_x11vnc" -a "$with_x11vnc" = "yes"; then
build_x11vnc="yes"
elif test "$PACKAGE_NAME" = "x11vnc"; then
build_x11vnc="yes"
else
build_x11vnc="no"
fi
# x11vnc only:
if test "$build_x11vnc" = "yes"; then
AH_TEMPLATE(HAVE_XSHM, [MIT-SHM extension build environment present])
AH_TEMPLATE(HAVE_XTEST, [XTEST extension build environment present])
AH_TEMPLATE(HAVE_XTESTGRABCONTROL, [XTEST extension has XTestGrabControl])
AH_TEMPLATE(HAVE_XKEYBOARD, [XKEYBOARD extension build environment present])
AH_TEMPLATE(HAVE_LIBXINERAMA, [XINERAMA extension build environment present])
AH_TEMPLATE(HAVE_LIBXRANDR, [XRANDR extension build environment present])
AH_TEMPLATE(HAVE_LIBXFIXES, [XFIXES extension build environment present])
AH_TEMPLATE(HAVE_LIBXDAMAGE, [XDAMAGE extension build environment present])
AH_TEMPLATE(HAVE_LIBXTRAP, [DEC-XTRAP extension build environment present])
AH_TEMPLATE(HAVE_RECORD, [RECORD extension build environment present])
AH_TEMPLATE(HAVE_SOLARIS_XREADSCREEN, [Solaris XReadScreen available])
AH_TEMPLATE(HAVE_IRIX_XREADDISPLAY, [IRIX XReadDisplay available])
AH_TEMPLATE(HAVE_FBPM, [FBPM extension build environment present])
AH_TEMPLATE(HAVE_DPMS, [DPMS extension build environment present])
AH_TEMPLATE(HAVE_LINUX_VIDEODEV_H, [video4linux build environment present])
AH_TEMPLATE(HAVE_LINUX_FB_H, [linux fb device build environment present])
AH_TEMPLATE(HAVE_LINUX_INPUT_H, [linux/input.h present])
AH_TEMPLATE(HAVE_LINUX_UINPUT_H, [linux uinput device build environment present])
AH_TEMPLATE(HAVE_MACOSX_NATIVE_DISPLAY, [build MacOS X native display support])
AC_ARG_WITH(xkeyboard,
[ --without-xkeyboard disable xkeyboard extension support],,)
AC_ARG_WITH(xinerama,
[ --without-xinerama disable xinerama extension support],,)
AC_ARG_WITH(xrandr,
[ --without-xrandr disable xrandr extension support],,)
AC_ARG_WITH(xfixes,
[ --without-xfixes disable xfixes extension support],,)
AC_ARG_WITH(xdamage,
[ --without-xdamage disable xdamage extension support],,)
AC_ARG_WITH(xtrap,
[ --without-xtrap disable xtrap extension support],,)
AC_ARG_WITH(xrecord,
[ --without-xrecord disable xrecord extension support],,)
AC_ARG_WITH(fbpm,
[ --without-fbpm disable fbpm extension support],,)
AC_ARG_WITH(dpms,
[ --without-dpms disable dpms extension support],,)
AC_ARG_WITH(v4l,
[ --without-v4l disable video4linux support],,)
AC_ARG_WITH(fbdev,
[ --without-fbdev disable linux fb device support],,)
AC_ARG_WITH(uinput,
[ --without-uinput disable linux uinput device support],,)
AC_ARG_WITH(macosx-native,
[ --without-macosx-native disable MacOS X native display support],,)
fi
# end x11vnc only.
if test "x$with_x" = "xno"; then
HAVE_X11="false"
elif test "$X_CFLAGS" != "-DX_DISPLAY_MISSING"; then
AC_CHECK_LIB(X11, XGetImage, [AC_DEFINE(HAVE_X11) HAVE_X11="true"],
HAVE_X11="false",
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
# x11vnc only:
if test $HAVE_X11 = "true" -a "$build_x11vnc" = "yes"; then
X_PRELIBS="$X_PRELIBS -lXext"
AC_CHECK_LIB(Xext, XShmGetImage,
[AC_DEFINE(HAVE_XSHM)], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
AC_CHECK_LIB(Xext, XReadScreen,
[AC_DEFINE(HAVE_SOLARIS_XREADSCREEN)], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
AC_CHECK_HEADER(X11/extensions/readdisplay.h,
[AC_DEFINE(HAVE_IRIX_XREADDISPLAY)], ,
[#include <X11/Xlib.h>])
if test "x$with_fbpm" != "xno"; then
AC_CHECK_LIB(Xext, FBPMForceLevel,
[AC_DEFINE(HAVE_FBPM)], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
fi
if test "x$with_dpms" != "xno"; then
AC_CHECK_LIB(Xext, DPMSForceLevel,
[AC_DEFINE(HAVE_DPMS)], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
fi
AC_CHECK_LIB(Xtst, XTestGrabControl,
X_PRELIBS="-lXtst $X_PRELIBS"
[AC_DEFINE(HAVE_XTESTGRABCONTROL) HAVE_XTESTGRABCONTROL="true"], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
AC_CHECK_LIB(Xtst, XTestFakeKeyEvent,
X_PRELIBS="-lXtst $X_PRELIBS"
[AC_DEFINE(HAVE_XTEST) HAVE_XTEST="true"], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
if test "x$with_xrecord" != "xno"; then
AC_CHECK_LIB(Xtst, XRecordEnableContextAsync,
X_PRELIBS="-lXtst $X_PRELIBS"
[AC_DEFINE(HAVE_RECORD)], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
fi
# we use XTRAP on X11R5, or user can set X11VNC_USE_XTRAP
if test "x$with_xtrap" != "xno"; then
if test ! -z "$X11VNC_USE_XTRAP" -o -z "$HAVE_XTESTGRABCONTROL"; then
AC_CHECK_LIB(XTrap, XETrapSetGrabServer,
X_PRELIBS="$X_PRELIBS -lXTrap"
[AC_DEFINE(HAVE_LIBXTRAP)], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
# tru64 uses libXETrap.so
AC_CHECK_LIB(XETrap, XETrapSetGrabServer,
X_PRELIBS="$X_PRELIBS -lXETrap"
[AC_DEFINE(HAVE_LIBXTRAP)], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
fi
fi
if test "x$with_xkeyboard" != "xno"; then
saved_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
AC_CHECK_HEADER(X11/XKBlib.h, HAVE_XKBLIB_H="true",
HAVE_XKBLIB_H="false", [#include <X11/Xlib.h>])
CPPFLAGS="$saved_CPPFLAGS"
if test $HAVE_XKBLIB_H = "true"; then
AC_CHECK_LIB(X11, XkbSelectEvents,
[AC_DEFINE(HAVE_XKEYBOARD)], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
fi
fi
if test "x$with_xinerama" != "xno"; then
AC_CHECK_LIB(Xinerama, XineramaQueryScreens,
X_PRELIBS="$X_PRELIBS -lXinerama"
[AC_DEFINE(HAVE_LIBXINERAMA)], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
fi
if test "x$with_xrandr" != "xno"; then
AC_CHECK_LIB(Xrandr, XRRSelectInput,
X_PRELIBS="$X_PRELIBS -lXrandr"
[AC_DEFINE(HAVE_LIBXRANDR) HAVE_LIBXRANDR="true"], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
fi
if test "x$with_xfixes" != "xno"; then
AC_CHECK_LIB(Xfixes, XFixesGetCursorImage,
X_PRELIBS="$X_PRELIBS -lXfixes"
[AC_DEFINE(HAVE_LIBXFIXES) HAVE_LIBXFIXES="true"], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
fi
if test "x$with_xdamage" != "xno"; then
AC_CHECK_LIB(Xdamage, XDamageQueryExtension,
X_PRELIBS="$X_PRELIBS -lXdamage"
[AC_DEFINE(HAVE_LIBXDAMAGE) HAVE_LIBXDAMAGE="true"], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
fi
if test ! -z "$HAVE_LIBXFIXES" -o ! -z "$HAVE_LIBXDAMAGE"; then
# need /usr/sfw/lib in RPATH for Solaris 10 and later
case `(uname -sr) 2>/dev/null` in
"SunOS 5"*) X_EXTRA_LIBS="$X_EXTRA_LIBS -R/usr/sfw/lib" ;;
esac
fi
if test ! -z "$HAVE_LIBXRANDR"; then
# also need /usr/X11/include for Solaris 10 10/08 and later
case `(uname -sr) 2>/dev/null` in
"SunOS 5"*) CPPFLAGS="$CPPFLAGS -I/usr/X11/include" ;;
esac
fi
X_LIBS="$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS"
fi
# end x11vnc only.
fi
AC_SUBST(X_LIBS)
AM_CONDITIONAL(HAVE_X11, test $HAVE_X11 != "false")
# x11vnc only:
if test "$build_x11vnc" = "yes"; then
if test "x$HAVE_X11" = "xfalse" -a "x$with_x" != "xno"; then
AC_MSG_ERROR([
==========================================================================
*** A working X window system build environment is required to build ***
x11vnc. Make sure any required X development packages are installed.
If they are installed in non-standard locations, one can use the
--x-includes=DIR and --x-libraries=DIR configure options or set the
CPPFLAGS and LDFLAGS environment variables to indicate where the X
window system header files and libraries may be found. On 64+32 bit
machines you may need to point to lib64 or lib32 directories to pick up
the correct word size.
If you want to build x11vnc without X support (e.g. for -rawfb use only
or for native Mac OS X), specify the --without-x configure option.
==========================================================================
])
fi
if test "x$HAVE_X11" = "xtrue" -a "x$HAVE_XTEST" != "xtrue"; then
AC_MSG_WARN([
==========================================================================
*** A working build environment for the XTEST extension was not found ***
(libXtst). An x11vnc built this way will be *ONLY BARELY USABLE*.
You will be able to move the mouse but not click or type. There can
also be deadlocks if an application grabs the X server.
It is recommended that you install the necessary development packages
for XTEST (perhaps it is named something like libxtst-dev) and run
configure again.
==========================================================================
])
sleep 5
fi
# set some ld -R nonsense
#
uname_s=`(uname -s) 2>/dev/null`
ld_minus_R="yes"
if test "x$uname_s" = "xHP-UX"; then
ld_minus_R="no"
elif test "x$uname_s" = "xOSF1"; then
ld_minus_R="no"
elif test "x$uname_s" = "xDarwin"; then
ld_minus_R="no"
fi
if test "x$with_v4l" != "xno"; then
AC_CHECK_HEADER(linux/videodev.h,
[AC_DEFINE(HAVE_LINUX_VIDEODEV_H)],,)
fi
if test "x$with_fbdev" != "xno"; then
AC_CHECK_HEADER(linux/fb.h,
[AC_DEFINE(HAVE_LINUX_FB_H)],,)
fi
if test "x$with_uinput" != "xno"; then
AC_CHECK_HEADER(linux/input.h,
[AC_DEFINE(HAVE_LINUX_INPUT_H) HAVE_LINUX_INPUT_H="true"],,)
if test "x$HAVE_LINUX_INPUT_H" = "xtrue"; then
AC_CHECK_HEADER(linux/uinput.h,
[AC_DEFINE(HAVE_LINUX_UINPUT_H)],, [#include <linux/input.h>])
fi
fi
if test "x$with_macosx_native" != "xno"; then
AC_DEFINE(HAVE_MACOSX_NATIVE_DISPLAY)
fi
AH_TEMPLATE(HAVE_AVAHI, [Avahi/mDNS client build environment present])
AC_ARG_WITH(avahi,
[ --without-avahi disable support for Avahi/mDNS]
[ --with-avahi=DIR use avahi include/library files in DIR],,)
if test "x$with_avahi" != "xno"; then
printf "checking for avahi... "
if test ! -z "$with_avahi" -a "x$with_avahi" != "xyes"; then
AVAHI_CFLAGS="-I$with_avahi/include"
AVAHI_LIBS="-L$with_avahi/lib -lavahi-common -lavahi-client"
echo "using $with_avahi"
with_avahi=yes
elif pkg-config --atleast-version=0.6.4 avahi-client >/dev/null 2>&1; then
AVAHI_CFLAGS=`pkg-config --cflags avahi-client`
AVAHI_LIBS=`pkg-config --libs avahi-client`
with_avahi=yes
echo yes
else
with_avahi=no
echo no
fi
fi
if test "x$with_avahi" = "xyes"; then
AC_DEFINE(HAVE_AVAHI)
AC_SUBST(AVAHI_CFLAGS)
AC_SUBST(AVAHI_LIBS)
fi
fi
# end x11vnc only.
AH_TEMPLATE(HAVE_LIBCRYPT, [libcrypt library present])
AC_ARG_WITH(crypt,
[ --without-crypt disable support for libcrypt],,)
if test "x$with_crypt" != "xno"; then
AC_CHECK_FUNCS([crypt], HAVE_LIBC_CRYPT="true")
if test -z "$HAVE_LIBC_CRYPT"; then
AC_CHECK_LIB(crypt, crypt,
CRYPT_LIBS="-lcrypt"
[AC_DEFINE(HAVE_LIBCRYPT)], ,)
fi
fi
AC_SUBST(CRYPT_LIBS)
# some OS's need both -lssl and -lcrypto on link line:
AH_TEMPLATE(HAVE_LIBCRYPTO, [openssl libcrypto library present])
AC_ARG_WITH(crypto,
[ --without-crypto disable support for openssl libcrypto],,)
AH_TEMPLATE(HAVE_LIBSSL, [openssl libssl library present])
AC_ARG_WITH(ssl,
[ --without-ssl disable support for openssl libssl]
[ --with-ssl=DIR use openssl include/library files in DIR],,)
if test "x$with_crypto" != "xno" -a "x$with_ssl" != "xno"; then
if test ! -z "$with_ssl" -a "x$with_ssl" != "xyes"; then
saved_CPPFLAGS="$CPPFLAGS"
saved_LDFLAGS="$LDFLAGS"
CPPFLAGS="$CPPFLAGS -I$with_ssl/include"
LDFLAGS="$LDFLAGS -L$with_ssl/lib"
if test "x$ld_minus_R" = "xno"; then
:
elif test "x$GCC" = "xyes"; then
LDFLAGS="$LDFLAGS -Xlinker -R$with_ssl/lib"
else
LDFLAGS="$LDFLAGS -R$with_ssl/lib"
fi
fi
AC_CHECK_LIB(crypto, RAND_file_name,
[AC_DEFINE(HAVE_LIBCRYPTO) HAVE_LIBCRYPTO="true"], ,)
if test ! -z "$with_ssl" -a "x$with_ssl" != "xyes"; then
if test "x$HAVE_LIBCRYPTO" != "xtrue"; then
CPPFLAGS="$saved_CPPFLAGS"
LDFLAGS="$saved_LDFLAGS"
fi
fi
fi
AH_TEMPLATE(HAVE_X509_PRINT_EX_FP, [open ssl X509_print_ex_fp available])
if test "x$with_ssl" != "xno"; then
if test "x$HAVE_LIBCRYPTO" = "xtrue"; then
AC_CHECK_LIB(ssl, SSL_library_init,
SSL_LIBS="-lssl -lcrypto"
[AC_DEFINE(HAVE_LIBSSL) HAVE_LIBSSL="true"], ,
-lcrypto)
else
AC_CHECK_LIB(ssl, SSL_library_init,
SSL_LIBS="-lssl"
[AC_DEFINE(HAVE_LIBSSL) HAVE_LIBSSL="true"], ,)
fi
fi
AC_SUBST(SSL_LIBS)
if test "x$HAVE_LIBSSL" != "xtrue" -a "x$with_ssl" != "xno"; then
AC_MSG_WARN([
==========================================================================
*** The openssl encryption library libssl.so was not found. ***
An x11vnc built this way will not support SSL encryption. To enable
SSL install the necessary development packages (perhaps it is named
something like libssl-dev) and run configure again.
==========================================================================
])
sleep 5
elif test "x$with_ssl" != "xno"; then
AC_CHECK_LIB(ssl, X509_print_ex_fp,
[AC_DEFINE(HAVE_X509_PRINT_EX_FP) HAVE_X509_PRINT_EX_FP="true"], , $SSL_LIBS
)
fi
# Checks for libraries.
if test ! -z "$with_system_libvncserver" -a "x$with_system_libvncserver" != "xno"; then
printf "checking for system libvncserver... "
vneed="0.9.1"
if test "X$VNEED" != "X"; then
vneed=$VNEED
fi
if test "x$with_system_libvncserver" != "xyes"; then
rflag=""
if test "x$ld_minus_R" = "xno"; then
:
elif test "x$GCC" = "xyes"; then
rflag="-Xlinker -R$with_system_libvncserver/lib"
else
rflag="-R$with_system_libvncserver/lib"
fi
cmd="$with_system_libvncserver/bin/libvncserver-config"
if $cmd --version 1>/dev/null 2>&1; then
cvers=`$cmd --version 2>/dev/null`
cscore=`echo "$cvers" | tr '.' ' ' | awk '{print 10000 * $1 + 100 * $2 + $3}'`
nscore=`echo "$vneed" | tr '.' ' ' | awk '{print 10000 * $1 + 100 * $2 + $3}'`
if test $cscore -lt $nscore; then
echo "no"
with_system_libvncserver=no
AC_MSG_ERROR([
==========================================================================
*** Need libvncserver version $vneed, have version $cvers ***
You are building with a system installed libvncserver and it is not
new enough.
==========================================================================
])
else
SYSTEM_LIBVNCSERVER_CFLAGS="-I$with_system_libvncserver/include"
SYSTEM_LIBVNCSERVER_LIBS="-L$with_system_libvncserver/lib $rflag -lvncserver -lvncclient"
echo "using $with_system_libvncserver"
with_system_libvncserver=yes
fi
else
echo " *** cannot run $cmd *** " 1>&2
with_system_libvncserver=no
echo no
fi
elif libvncserver-config --version 1>/dev/null 2>&1; then
rflag=""
rprefix=`libvncserver-config --prefix`
if test "x$ld_minus_R" = "xno"; then
:
elif test "x$GCC" = "xyes"; then
rflag=" -Xlinker -R$rprefix/lib "
else
rflag=" -R$rprefix/lib "
fi
cvers=`libvncserver-config --version 2>/dev/null`
cscore=`echo "$cvers" | tr '.' ' ' | awk '{print 10000 * $1 + 100 * $2 + $3}'`
nscore=`echo "$vneed" | tr '.' ' ' | awk '{print 10000 * $1 + 100 * $2 + $3}'`
if test $cscore -lt $nscore; then
echo "no"
AC_MSG_ERROR([
==========================================================================
*** Need libvncserver version $vneed, have version $cvers ***
You are building with a system installed libvncserver and it is not
new enough.
==========================================================================
])
else
SYSTEM_LIBVNCSERVER_CFLAGS=`libvncserver-config --cflags`
SYSTEM_LIBVNCSERVER_LIBS="$rflag"`libvncserver-config --libs`
with_system_libvncserver=yes
echo yes
fi
else
with_system_libvncserver=no
echo no
fi
fi
if test "x$with_system_libvncserver" = "xyes"; then
AC_DEFINE(HAVE_SYSTEM_LIBVNCSERVER)
AC_SUBST(SYSTEM_LIBVNCSERVER_CFLAGS)
AC_SUBST(SYSTEM_LIBVNCSERVER_LIBS)
fi
AM_CONDITIONAL(HAVE_SYSTEM_LIBVNCSERVER, test "x$with_system_libvncserver" = "xyes")
AC_ARG_WITH(jpeg,
[ --without-jpeg disable support for jpeg]
[ --with-jpeg=DIR use jpeg include/library files in DIR],,)
# At this point:
# no jpeg on command line with_jpeg=""
# -with-jpeg with_jpeg="yes"
# -without-jpeg with_jpeg="no"
# -with-jpeg=/foo/dir with_jpeg="/foo/dir"
if test "x$with_jpeg" != "xno"; then
if test ! -z "$with_jpeg" -a "x$with_jpeg" != "xyes"; then
# add user supplied directory to flags:
saved_CPPFLAGS="$CPPFLAGS"
saved_LDFLAGS="$LDFLAGS"
CPPFLAGS="$CPPFLAGS -I$with_jpeg/include"
LDFLAGS="$LDFLAGS -L$with_jpeg/lib"
if test "x$ld_minus_R" = "xno"; then
:
elif test "x$GCC" = "xyes"; then
# this is not complete... in general a rat's nest.
LDFLAGS="$LDFLAGS -Xlinker -R$with_jpeg/lib"
else
LDFLAGS="$LDFLAGS -R$with_jpeg/lib"
fi
fi
AC_CHECK_HEADER(jpeglib.h, HAVE_JPEGLIB_H="true")
if test "x$HAVE_JPEGLIB_H" = "xtrue"; then
AC_CHECK_LIB(jpeg, jpeg_CreateCompress, , HAVE_JPEGLIB_H="")
fi
if test ! -z "$with_jpeg" -a "x$with_jpeg" != "xyes"; then
if test "x$HAVE_JPEGLIB_H" != "xtrue"; then
# restore old flags on failure:
CPPFLAGS="$saved_CPPFLAGS"
LDFLAGS="$saved_LDFLAGS"
fi
fi
if test "$build_x11vnc" = "yes"; then
if test "x$HAVE_JPEGLIB_H" != "xtrue"; then
AC_MSG_WARN([
==========================================================================
*** The libjpeg compression library was not found. ***
This may lead to reduced performance, especially over slow links.
If libjpeg is in a non-standard location use --with-jpeg=DIR to
indicate the header file is in DIR/include/jpeglib.h and the library
in DIR/lib/libjpeg.a. A copy of libjpeg may be obtained from:
ftp://ftp.uu.net/graphics/jpeg/
==========================================================================
])
sleep 5
fi
fi
fi
AC_ARG_WITH(png,
[ --without-png disable support for png]
[ --with-png=DIR use png include/library files in DIR],,)
# At this point:
# no png on command line with_png=""
# -with-png with_png="yes"
# -without-png with_png="no"
# -with-png=/foo/dir with_png="/foo/dir"
if test "x$with_png" != "xno"; then
if test ! -z "$with_png" -a "x$with_png" != "xyes"; then
# add user supplied directory to flags:
saved_CPPFLAGS="$CPPFLAGS"
saved_LDFLAGS="$LDFLAGS"
CPPFLAGS="$CPPFLAGS -I$with_png/include"
LDFLAGS="$LDFLAGS -L$with_png/lib"
if test "x$ld_minus_R" = "xno"; then
:
elif test "x$GCC" = "xyes"; then
# this is not complete... in general a rat's nest.
LDFLAGS="$LDFLAGS -Xlinker -R$with_png/lib"
else
LDFLAGS="$LDFLAGS -R$with_png/lib"
fi
fi
AC_CHECK_HEADER(png.h, HAVE_PNGLIB_H="true")
if test "x$HAVE_PNGLIB_H" = "xtrue"; then
AC_CHECK_LIB(png, png_create_write_struct, , HAVE_PNGLIB_H="")
fi
if test ! -z "$with_png" -a "x$with_png" != "xyes"; then
if test "x$HAVE_PNGLIB_H" != "xtrue"; then
# restore old flags on failure:
CPPFLAGS="$saved_CPPFLAGS"
LDFLAGS="$saved_LDFLAGS"
fi
fi
if test "$build_x11vnc" = "yes"; then
if test "x$HAVE_PNGLIB_H" != "xtrue"; then
AC_MSG_WARN([
==========================================================================
*** The libpng compression library was not found. ***
This may lead to reduced performance, especially over slow links.
If libpng is in a non-standard location use --with-png=DIR to
indicate the header file is in DIR/include/png.h and the library
in DIR/lib/libpng.a. A copy of libpng may be obtained from:
http://www.libpng.org/pub/png/libpng.html
==========================================================================
])
sleep 5
fi
fi
fi
AC_ARG_WITH(libz,
[ --without-libz disable support for deflate],,)
AC_ARG_WITH(zlib,
[ --without-zlib disable support for deflate]
[ --with-zlib=DIR use zlib include/library files in DIR],,)
if test "x$with_zlib" != "xno" -a "x$with_libz" != "xno"; then
if test ! -z "$with_zlib" -a "x$with_zlib" != "xyes"; then
saved_CPPFLAGS="$CPPFLAGS"
saved_LDFLAGS="$LDFLAGS"
CPPFLAGS="$CPPFLAGS -I$with_zlib/include"
LDFLAGS="$LDFLAGS -L$with_zlib/lib"
if test "x$ld_minus_R" = "xno"; then
:
elif test "x$GCC" = "xyes"; then
LDFLAGS="$LDFLAGS -Xlinker -R$with_zlib/lib"
else
LDFLAGS="$LDFLAGS -R$with_zlib/lib"
fi
fi
AC_CHECK_HEADER(zlib.h, HAVE_ZLIB_H="true")
if test "x$HAVE_ZLIB_H" = "xtrue"; then
AC_CHECK_LIB(z, deflate, , HAVE_ZLIB_H="")
fi
if test ! -z "$with_zlib" -a "x$with_zlib" != "xyes"; then
if test "x$HAVE_ZLIB_H" != "xtrue"; then
CPPFLAGS="$saved_CPPFLAGS"
LDFLAGS="$saved_LDFLAGS"
fi
fi
if test "$build_x11vnc" = "yes"; then
if test "x$HAVE_ZLIB_H" != "xtrue"; then
AC_MSG_WARN([
==========================================================================
*** The libz compression library was not found. ***
This may lead to reduced performance, especially over slow links.
If libz is in a non-standard location use --with-zlib=DIR to indicate the
header file is in DIR/include/zlib.h and the library in DIR/lib/libz.a.
A copy of libz may be obtained from: http://www.gzip.org/zlib/
==========================================================================
])
sleep 5
fi
fi
fi
AC_ARG_WITH(pthread,
[ --without-pthread disable support for libpthread],,)
if test "x$with_pthread" != "xno"; then
AC_CHECK_HEADER(pthread.h, HAVE_PTHREAD_H="true")
if test ! -z "$HAVE_PTHREAD_H"; then
AC_CHECK_LIB(pthread, pthread_mutex_lock)
AC_CHECK_LIB(pthread, pthread_mutex_lock, HAVE_LIBPTHREAD="true")
fi
fi
AM_CONDITIONAL(HAVE_LIBPTHREAD, test ! -z "$HAVE_LIBPTHREAD")
AC_MSG_CHECKING([for __thread])
AC_LINK_IFELSE([AC_LANG_PROGRAM(, [static __thread int p = 0])],
[AC_DEFINE(HAVE_TLS, 1,
Define to 1 if compiler supports __thread)
AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])])
# tightvnc-filetransfer implemented using threads:
if test -z "$HAVE_LIBPTHREAD"; then
with_tightvnc_filetransfer=""
fi
if test "x$with_tightvnc_filetransfer" = "xyes"; then
AC_DEFINE(WITH_TIGHTVNC_FILETRANSFER)
fi
AM_CONDITIONAL(WITH_TIGHTVNC_FILETRANSFER, test "$with_tightvnc_filetransfer" = "yes")
# websockets implemented using base64 from resolve
if test "x$HAVE_B64" != "xtrue"; then
with_websockets=""
fi
if test "x$with_websockets" = "xyes"; then
LIBS="$LIBS -lresolv"
AC_DEFINE(WITH_WEBSOCKETS)
fi
AM_CONDITIONAL(WITH_WEBSOCKETS, test "$with_websockets" = "yes")
AM_CONDITIONAL(HAVE_LIBZ, test ! -z "$HAVE_ZLIB_H")
AM_CONDITIONAL(HAVE_LIBJPEG, test ! -z "$HAVE_JPEGLIB_H")
AM_CONDITIONAL(HAVE_LIBPNG, test ! -z "$HAVE_PNGLIB_H")
SDLCONFIG="sdl-config"
AC_ARG_WITH(sdl-config,
[[ --with-sdl-config=FILE
Use the given path to sdl-config when determining
SDL configuration; defaults to "sdl-config"]],
[
if test "$withval" != "yes" -a "$withval" != ""; then
SDLCONFIG=$withval
fi
])
if test -z "$with_sdl"; then
if $SDLCONFIG --version >/dev/null 2>&1; then
with_sdl=yes
SDL_CFLAGS=`$SDLCONFIG --cflags`
SDL_LIBS=`$SDLCONFIG --libs`
else
with_sdl=no
fi
fi
AM_CONDITIONAL(HAVE_LIBSDL, test "x$with_sdl" = "xyes")
AC_SUBST(SDL_CFLAGS)
AC_SUBST(SDL_LIBS)
AC_CANONICAL_HOST
MINGW=`echo $host_os | grep mingw32 2>/dev/null`
AM_CONDITIONAL(MINGW, test ! -z "$MINGW" )
if test ! -z "$MINGW"; then
WSOCKLIB="-lws2_32"
fi
AC_SUBST(WSOCKLIB)
# Checks for GnuTLS
AH_TEMPLATE(WITH_CLIENT_TLS, [Enable support for gnutls in libvncclient])
AC_ARG_WITH(gnutls,
[ --without-gnutls disable support for gnutls],,)
AC_ARG_WITH(client-tls,
[ --without-client-tls disable support for gnutls in libvncclient],,)
if test "x$with_gnutls" != "xno"; then
PKG_CHECK_MODULES(GNUTLS, gnutls >= 2.4.0, , with_client_tls=no)
CFLAGS="$CFLAGS $GNUTLS_CFLAGS"
LIBS="$LIBS $GNUTLS_LIBS"
if test "x$with_client_tls" != "xno"; then
AC_DEFINE(WITH_CLIENT_TLS)
fi
fi
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h sys/time.h sys/timeb.h syslog.h unistd.h])
# x11vnc only:
if test "$build_x11vnc" = "yes"; then
AC_CHECK_HEADERS([pwd.h sys/wait.h utmpx.h termios.h sys/ioctl.h sys/stropts.h])
fi
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_INLINE
AC_C_BIGENDIAN
AC_TYPE_SIZE_T
AC_HEADER_TIME
AC_HEADER_SYS_WAIT
AC_TYPE_SOCKLEN_T
if test ! -d ./rfb; then
echo "creating subdir ./rfb for rfbint.h"
mkdir ./rfb
fi
AC_CREATE_STDINT_H(rfb/rfbint.h)
AC_CACHE_CHECK([for in_addr_t],
vnc_cv_inaddrt, [
AC_TRY_COMPILE([#include <sys/types.h>
#include <netinet/in.h>],
[in_addr_t foo; return 0;],
[inaddrt=yes],
[inaddrt=no]),
])
AH_TEMPLATE(NEED_INADDR_T, [Need a typedef for in_addr_t])
if test $inaddrt = no ; then
AC_DEFINE(NEED_INADDR_T)
fi
# Checks for library functions.
AC_FUNC_MEMCMP
AC_FUNC_STAT
AC_FUNC_STRFTIME
AC_FUNC_VPRINTF
AC_FUNC_FORK
AC_CHECK_LIB(nsl,gethostbyname)
AC_CHECK_LIB(socket,socket)
uname_s=`(uname -s) 2>/dev/null`
if test "x$uname_s" = "xHP-UX"; then
# need -lsec for getspnam()
LDFLAGS="$LDFLAGS -lsec"
fi
AC_CHECK_FUNCS([ftime gethostbyname gethostname gettimeofday inet_ntoa memmove memset mmap mkfifo select socket strchr strcspn strdup strerror strstr])
# x11vnc only:
if test "$build_x11vnc" = "yes"; then
AC_CHECK_FUNCS([setsid setpgrp getpwuid getpwnam getspnam getuid geteuid setuid setgid seteuid setegid initgroups waitpid setutxent grantpt shmat])
fi
# check, if shmget is in cygipc.a
AC_CHECK_LIB(cygipc,shmget)
AM_CONDITIONAL(CYGIPC, test "$HAVE_CYGIPC" = "true")
# Check if /dev/vcsa1 exists, if so, define LINUX
AM_CONDITIONAL(LINUX, test -c /dev/vcsa1)
# Check for OS X specific header
AC_CHECK_HEADER(ApplicationServices/ApplicationServices.h, HAVE_OSX="true")
AM_CONDITIONAL(OSX, test "$HAVE_OSX" = "true")
# On Solaris 2.7, write() returns ENOENT when it really means EAGAIN
AH_TEMPLATE(ENOENT_WORKAROUND, [work around when write() returns ENOENT but does not mean it])
case `(uname -sr) 2>/dev/null` in
"SunOS 5.7")
AC_DEFINE(ENOENT_WORKAROUND)
;;
esac
# Check for rpm SOURCES path
printf "checking for rpm sources path... "
RPMSOURCEDIR="NOT-FOUND"
for directory in packages OpenLinux redhat RedHat rpm RPM "" ; do
if test -d /usr/src/${directory}/SOURCES; then
RPMSOURCEDIR="/usr/src/${directory}/SOURCES/"
fi
done
echo "$RPMSOURCEDIR"
AM_CONDITIONAL(HAVE_RPM, test "$RPMSOURCEDIR" != "NOT-FOUND")
AM_CONDITIONAL(WITH_X11VNC, test "$build_x11vnc" = "yes")
AC_SUBST(RPMSOURCEDIR)
AC_CONFIG_FILES([Makefile
libvncserver/Makefile
contrib/Makefile
examples/Makefile
vncterm/Makefile
classes/Makefile
classes/ssl/Makefile
libvncclient/Makefile
client_examples/Makefile
test/Makefile
libvncserver-config
LibVNCServer.spec])
#
# x11vnc only:
#
if test "$build_x11vnc" = "yes"; then
#
# NOTE: if you are using the LibVNCServer-X.Y.Z.tar.gz source
# tarball and nevertheless want to run autoconf (i.e. aclocal,
# autoheader, automake, autoconf) AGAIN (perhaps you have a
# special target system, e.g. embedded) then you will need to
# comment out the following 'AC_CONFIG_FILES' line to avoid
# automake error messages like:
#
# configure.ac:690: required file `x11vnc/Makefile.in' not found
#
AC_CONFIG_FILES([x11vnc/Makefile x11vnc/misc/Makefile x11vnc/misc/turbovnc/Makefile])
fi
AC_CONFIG_COMMANDS([chmod-libvncserver-config],[chmod a+x libvncserver-config])
AC_OUTPUT
chmod a+x ./libvncserver-config

View File

@ -0,0 +1,38 @@
#!/usr/bin/perl
# convert a linux console font (8x16 format) to a font definition
# suitable for processing with LibVNCServer
#if($#ARGV == 0) { exit; }
foreach $i (@ARGV) {
$fontname = $i;
$fontname =~ s/\.fnt$//;
$fontname =~ s/^.*\///g;
$fontname =~ y/+/_/;
print STDERR "$i -> $fontname\n";
open IN, "<$i";
print STDERR read(IN,$x,4096);
close(IN);
open OUT, ">$fontname.h";
print OUT "unsigned char ".$fontname."FontData[4096+1]={";
for($i=0;$i<4096;$i++) {
if(($i%16)==0) {
print OUT "\n";
}
printf OUT "0x%02x,", ord(substr($x,$i));
}
print OUT "\n};\nint ".$fontname."FontMetaData[256*5+1]={\n";
for($i=0;$i<256;$i++) {
print OUT ($i*16).",8,16,0,0,";
}
print OUT "};\nrfbFontData ".$fontname."Font = { ".$fontname."FontData, "
.$fontname."FontMetaData };\n";
close OUT;
}

View File

@ -0,0 +1,6 @@
Makefile
Makefile.in
x11vnc
zippy
.deps

View File

@ -0,0 +1,7 @@
INCLUDES = -I$(top_srcdir)
LDADD = ../libvncserver/libvncserver.la @WSOCKLIB@
noinst_PROGRAMS=zippy
zippy_SOURCES=zippy.c

View File

@ -0,0 +1,179 @@
#include <stdio.h>
#include <stdlib.h>
#include <rfb/rfb.h>
#include <rfb/keysym.h>
#include <rfb/default8x16.h>
static int maxx=400, maxy=400, bpp=4;
/* odd maxx doesn't work (vncviewer bug) */
/* Here we create a structure so that every client has it's own pointer */
/* turns the framebuffer black */
void blank_framebuffer(char* frame_buffer, int x1, int y1, int x2, int y2);
/* displays a red bar, a green bar, and a blue bar */
void draw_primary_colors (char* frame_buffer, int x1, int y1, int x2, int y2);
void linecount (char* frame_buffer);
/* handles mouse events */
void on_mouse_event (int buttonMask,int x,int y,rfbClientPtr cl);
/* handles keyboard events */
void on_key_press (rfbBool down,rfbKeySym key,rfbClientPtr cl);
int main (int argc, char **argv)
{
rfbScreenInfoPtr server;
if(!rfbProcessSizeArguments(&maxx,&maxy,&bpp,&argc,argv))
return 1;
server = rfbGetScreen (&argc, argv, maxx, maxy, 8, 3, bpp);
server->desktopName = "Zippy das wundersquirrel\'s VNC server";
server->frameBuffer = (char*)malloc(maxx*maxy*bpp);
server->alwaysShared = TRUE;
server->kbdAddEvent = on_key_press;
server->ptrAddEvent = on_mouse_event;
rfbInitServer (server);
blank_framebuffer(server->frameBuffer, 0, 0, maxx, maxy);
rfbRunEventLoop (server, -1, FALSE);
free(server->frameBuffer);
rfbScreenCleanup (server);
return 0;
}
void blank_framebuffer(char* frame_buffer, int x1, int y1, int x2, int y2)
{
int i;
for (i=0; i < maxx * maxy * bpp; i++) frame_buffer[i]=(char) 0;
}
void draw_primary_colors (char* frame_buffer, int x1, int y1, int x2, int y2)
{
int i, j, current_pixel;
for (i=y1; i < y2; i++){
for (j=x1; j < x2; j++) {
current_pixel = (i*x2 + j) * bpp;
if (i < y2 ) {
frame_buffer[current_pixel+0] = (char) 128;
frame_buffer[current_pixel+1] = (char) 0;
frame_buffer[current_pixel+2] = (char) 0;
}
if (i < y2/3*2) {
frame_buffer[current_pixel+0] = (char) 0;
frame_buffer[current_pixel+1] = (char) 128;
frame_buffer[current_pixel+2] = (char) 0;
}
if (i < y2/3) {
frame_buffer[current_pixel+0] = (char) 0;
frame_buffer[current_pixel+1] = (char) 0;
frame_buffer[current_pixel+2] = (char) 128;
}
}
}
}
/* Dscho's versions (slower, but works for bpp != 3 or 4) */
static void draw_primary_colours_generic(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2)
{
rfbPixelFormat f=s->serverFormat;
int i,j;
for(j=y1;j<y2;j++)
for(i=x1;i<x2;i++)
if(j<y1*2/3+y2/3)
rfbDrawPixel(s,i,j,f.redMax<<f.redShift);
else if(j<y1/3+y2*2/3)
rfbDrawPixel(s,i,j,f.greenMax<<f.greenShift);
else
rfbDrawPixel(s,i,j,f.blueMax<<f.blueShift);
}
static void draw_primary_colours_generic_fast(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2)
{
rfbPixelFormat f=s->serverFormat;
int i,j,y3=(y1*2+y2)/3,y4=(y1+y2*2)/3;
/* draw first pixel */
rfbDrawPixel(s,x1,y1,f.redMax<<f.redShift);
rfbDrawPixel(s,x1,y3,f.greenMax<<f.greenShift);
rfbDrawPixel(s,x1,y4,f.blueMax<<f.blueShift);
/* then copy stripes */
for(j=0;j<y2-y4;j++)
for(i=x1;i<x2;i++) {
#define ADDR(x,y) s->frameBuffer+(x)*bpp+(y)*s->paddedWidthInBytes
memcpy(ADDR(i,j+y1),ADDR(x1,y1),bpp);
memcpy(ADDR(i,j+y3),ADDR(x1,y3),bpp);
memcpy(ADDR(i,j+y4),ADDR(x1,y4),bpp);
}
}
static void draw_primary_colours_generic_ultrafast(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2)
{
rfbPixelFormat f=s->serverFormat;
int y3=(y1*2+y2)/3,y4=(y1+y2*2)/3;
/* fill rectangles */
rfbFillRect(s,x1,y1,x2,y3,f.redMax<<f.redShift);
rfbFillRect(s,x1,y3,x2,y4,f.greenMax<<f.greenShift);
rfbFillRect(s,x1,y4,x2,y2,f.blueMax<<f.blueShift);
}
void linecount (char* frame_buffer)
{
int i,j,k, current_pixel;
for (i=maxy-4; i>maxy-20; i-=4)
for (j=0; j<4; j++) for (k=0; k < maxx; k++) {
current_pixel = (i*j*maxx + k) * bpp;
if (i%2 == 0) {
frame_buffer[current_pixel+0] = (char) 0;
frame_buffer[current_pixel+1] = (char) 0;
frame_buffer[current_pixel+2] = (char) 128;
}
if (i%2 == 1) {
frame_buffer[current_pixel+0] = (char) 128;
frame_buffer[current_pixel+1] = (char) 0;
frame_buffer[current_pixel+2] = (char) 0;
}
}
}
void on_key_press (rfbBool down,rfbKeySym key,rfbClientPtr cl)
{
if (down) /* or else the action occurs on both the press and depress */
switch (key) {
case XK_b:
case XK_B:
blank_framebuffer(cl->screen->frameBuffer, 0, 0, maxx, maxy);
rfbDrawString(cl->screen,&default8x16Font,20,maxy-20,"Hello, World!",0xffffff);
rfbMarkRectAsModified(cl->screen,0, 0,maxx,maxy);
rfbLog("Framebuffer blanked\n");
break;
case XK_p:
case XK_P:
/* draw_primary_colors (cl->screen->frameBuffer, 0, 0, maxx, maxy); */
draw_primary_colours_generic_ultrafast (cl->screen, 0, 0, maxx, maxy);
rfbMarkRectAsModified(cl->screen,0, 0,maxx,maxy);
rfbLog("Primary colors displayed\n");
break;
case XK_Q:
case XK_q:
rfbLog("Exiting now\n");
exit(0);
case XK_C:
case XK_c:
rfbDrawString(cl->screen,&default8x16Font,20,100,"Hello, World!",0xffffff);
rfbMarkRectAsModified(cl->screen,0, 0,maxx,maxy);
break;
default:
rfbLog("The %c key was pressed\n", (char) key);
}
}
void on_mouse_event (int buttonMask,int x,int y,rfbClientPtr cl)
{
printf("buttonMask: %i\n"
"x: %i\n" "y: %i\n", buttonMask, x, y);
}

View File

@ -0,0 +1,13 @@
#!/bin/bash
case "$1" in
#cvs --help-commands 2>&1 | sed "s/[ ][ ]*/ /g" | cut -d " " -f 2
add|admin|annotate|checkout|commit|diff|edit|editors|export|history|import|\
init|log|login|logout|pserver|rdiff|release|remove|rtag|server|status|\
tag|unedit|update|watch|watchers)
cmd="$1"; shift;;
*) cmd=update;;
esac
cvs -z3 -d :pserver:anonymous@cvs.libvncserver.sf.net:/cvsroot/libvncserver $cmd "$@"

View File

@ -0,0 +1,18 @@
Makefile
*test
example
fontsel
pnmshow
pnmshow24
storepasswd
vncev
Makefile.in
.deps
simple
simple15
colourmaptest
regiontest
mac
filetransfer
backchannel
rotate

View File

@ -0,0 +1,141 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
typedef struct {
char* filename; /* this file is the pipe (set by user) */
char is_server; /* this is set by open_control_file */
int fd; /* this is set by open_control_file */
} single_instance_struct;
/* returns fd, is_server is set to -1 if server, 0 if client */
int open_control_file(single_instance_struct* str)
{
struct stat buf;
if(stat(str->filename,&buf)) {
mkfifo(str->filename,128|256);
str->is_server=-1;
str->fd=open(str->filename,O_NONBLOCK|O_RDONLY);
} else {
str->fd=open(str->filename,O_NONBLOCK|O_WRONLY);
if(errno==ENXIO) {
str->is_server=-1;
str->fd=open(str->filename,O_NONBLOCK|O_RDONLY);
} else
str->is_server=0;
}
return(str->fd);
}
void delete_control_file(single_instance_struct* str)
{
remove(str->filename);
}
void close_control_file(single_instance_struct* str)
{
close(str->fd);
}
typedef void (*event_dispatcher)(char* message);
int get_next_message(char* buffer,int len,single_instance_struct* str,int usecs)
{
struct timeval tv;
fd_set fdset;
int num_fds;
FD_ZERO(&fdset);
FD_SET(str->fd,&fdset);
tv.tv_sec=0;
tv.tv_usec=usecs;
num_fds=select(str->fd+1,&fdset,NULL,NULL,&tv);
if(num_fds) {
int reallen;
reallen=read(str->fd,buffer,len);
if(reallen==0) {
close(str->fd);
str->fd=open(str->filename,O_NONBLOCK|O_RDONLY);
num_fds--;
}
buffer[reallen]=0;
#ifdef DEBUG_1INSTANCE
if(reallen!=0) rfbLog("message received: %s.\n",buffer);
#endif
}
return(num_fds);
}
int dispatch_event(single_instance_struct* str,event_dispatcher dispatcher,int usecs)
{
char buffer[1024];
int num_fds;
if((num_fds=get_next_message(buffer,1024,str,usecs)) && buffer[0])
dispatcher(buffer);
return(num_fds);
}
int loop_if_server(single_instance_struct* str,event_dispatcher dispatcher)
{
open_control_file(str);
if(str->is_server) {
while(1)
dispatch_event(str,dispatcher,50);
}
return(str->fd);
}
void send_message(single_instance_struct* str,char* message)
{
#ifdef DEBUG_1INSTANCE
int i=
#endif
write(str->fd,message,strlen(message));
#ifdef DEBUG_1INSTANCE
rfbLog("send: %s => %d(%d)\n",message,i,strlen(message));
#endif
}
#ifdef DEBUG_MAIN
#include <stdio.h>
#include <stdlib.h>
single_instance_struct str1 = { "/tmp/1instance" };
void my_dispatcher(char* message)
{
#ifdef DEBUG_1INSTANCE
rfbLog("Message arrived: %s.\n",message);
#endif
if(!strcmp(message,"quit")) {
delete_control_file(str1);
exit(0);
}
}
int main(int argc,char** argv)
{
int i;
loop_if_server(str1,my_dispatcher);
for(i=1;i<argc;i++)
send_event(str1,argv[i]);
return(0);
}
#endif

View File

@ -0,0 +1,22 @@
INCLUDES = -I$(top_srcdir)
LDADD = ../libvncserver/libvncserver.la @WSOCKLIB@
if OSX
MAC=mac
mac_LDFLAGS=-framework ApplicationServices -framework Carbon -framework IOKit
endif
if WITH_TIGHTVNC_FILETRANSFER
FILETRANSFER=filetransfer
endif
if HAVE_LIBPTHREAD
BLOOPTEST=blooptest
endif
noinst_HEADERS=radon.h rotatetemplate.c
noinst_PROGRAMS=example pnmshow regiontest pnmshow24 fontsel \
vncev storepasswd colourmaptest simple simple15 $(MAC) \
$(FILETRANSFER) backchannel $(BLOOPTEST) camera rotate

View File

@ -0,0 +1,113 @@
#include <rfb/rfb.h>
/*
* This is a simple example demonstrating a protocol extension.
*
* The "back channel" permits sending commands between client and server.
* It works by sending plain text messages.
*
* As suggested in the RFB protocol, the back channel is enabled by asking
* for a "pseudo encoding", and enabling the back channel on the client side
* as soon as it gets a back channel message from the server.
*
* This implements the server part.
*
* Note: If you design your own extension and want it to be useful for others,
* too, you should make sure that
*
* - your server as well as your client can speak to other clients and
* servers respectively (i.e. they are nice if they are talking to a
* program which does not know about your extension).
*
* - if the machine is little endian, all 16-bit and 32-bit integers are
* swapped before they are sent and after they are received.
*
*/
#define rfbBackChannel 155
typedef struct backChannelMsg {
uint8_t type;
uint8_t pad1;
uint16_t pad2;
uint32_t size;
} backChannelMsg;
rfbBool enableBackChannel(rfbClientPtr cl, void** data, int encoding)
{
if(encoding == rfbBackChannel) {
backChannelMsg msg;
const char* text="Server acknowledges back channel encoding\n";
uint32_t length = strlen(text)+1;
int n;
rfbLog("Enabling the back channel\n");
msg.type = rfbBackChannel;
msg.size = Swap32IfLE(length);
if((n = rfbWriteExact(cl, (char*)&msg, sizeof(msg))) <= 0 ||
(n = rfbWriteExact(cl, text, length)) <= 0) {
rfbLogPerror("enableBackChannel: write");
}
return TRUE;
}
return FALSE;
}
static rfbBool handleBackChannelMessage(rfbClientPtr cl, void* data,
const rfbClientToServerMsg* message)
{
if(message->type == rfbBackChannel) {
backChannelMsg msg;
char* text;
int n;
if((n = rfbReadExact(cl, ((char*)&msg)+1, sizeof(backChannelMsg)-1)) <= 0) {
if(n != 0)
rfbLogPerror("handleBackChannelMessage: read");
rfbCloseClient(cl);
return TRUE;
}
msg.size = Swap32IfLE(msg.size);
if((text = malloc(msg.size)) == NULL) {
rfbErr("Could not allocate %d bytes\n", msg.size);
return TRUE;
}
if((n = rfbReadExact(cl, text, msg.size)) <= 0) {
if(n != 0)
rfbLogPerror("handleBackChannelMessage: read");
rfbCloseClient(cl);
return TRUE;
}
rfbLog("got message:\n%s\n", text);
free(text);
return TRUE;
}
return FALSE;
}
static int backChannelEncodings[] = {rfbBackChannel, 0};
static rfbProtocolExtension backChannelExtension = {
NULL, /* newClient */
NULL, /* init */
backChannelEncodings, /* pseudoEncodings */
enableBackChannel, /* enablePseudoEncoding */
handleBackChannelMessage, /* handleMessage */
NULL, /* close */
NULL, /* usage */
NULL, /* processArgument */
NULL /* next extension */
};
int main(int argc,char** argv)
{
rfbScreenInfoPtr server;
rfbRegisterProtocolExtension(&backChannelExtension);
server=rfbGetScreen(&argc,argv,400,300,8,3,4);
server->frameBuffer=(char*)malloc(400*300*4);
rfbInitServer(server);
rfbRunEventLoop(server,-1,FALSE);
return(0);
}

View File

@ -0,0 +1,2 @@
#define BACKGROUND_LOOP_TEST
#include "example.c"

View File

@ -0,0 +1,152 @@
/*
* Question: I need to display a live camera image via VNC. Until now I just
* grab an image, set the rect to modified and do a 0.1 s sleep to give the
* system time to transfer the data.
* This is obviously a solution which doesn't scale very well to different
* connection speeds/cpu horsepowers, so I wonder if there is a way for the
* server application to determine if the updates have been sent. This would
* cause the live image update rate to always be the maximum the connection
* supports while avoiding excessive loads.
*
* Thanks in advance,
*
*
* Christian Daschill
*
*
* Answer: Originally, I thought about using seperate threads and using a
* mutex to determine when the frame buffer was being accessed by any client
* so we could determine a safe time to take a picture. The probem is, we
* are lock-stepping everything with framebuffer access. Why not be a
* single-thread application and in-between rfbProcessEvents perform a
* camera snapshot. And this is what I do here. It guarantees that the
* clients have been serviced before taking another picture.
*
* The downside to this approach is that the more clients you have, there is
* less time available for you to service the camera equating to reduced
* frame rate. (or, your clients are on really slow links). Increasing your
* systems ethernet transmit queues may help improve the overall performance
* as the libvncserver should not stall on transmitting to any single
* client.
*
* Another solution would be to provide a seperate framebuffer for each
* client and use mutexes to determine if any particular client is ready for
* a snapshot. This way, your not updating a framebuffer for a slow client
* while it is being transferred.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rfb/rfb.h>
#define WIDTH 640
#define HEIGHT 480
#define BPP 4
/* 15 frames per second (if we can) */
#define PICTURE_TIMEOUT (1.0/15.0)
/*
* throttle camera updates
*/
int TimeToTakePicture() {
static struct timeval now={0,0}, then={0,0};
double elapsed, dnow, dthen;
gettimeofday(&now,NULL);
dnow = now.tv_sec + (now.tv_usec /1000000.0);
dthen = then.tv_sec + (then.tv_usec/1000000.0);
elapsed = dnow - dthen;
if (elapsed > PICTURE_TIMEOUT)
memcpy((char *)&then, (char *)&now, sizeof(struct timeval));
return elapsed > PICTURE_TIMEOUT;
}
/*
* simulate grabbing a picture from some device
*/
int TakePicture(unsigned char *buffer)
{
static int last_line=0, fps=0, fcount=0;
int line=0;
int i,j;
struct timeval now;
/*
* simulate grabbing data from a device by updating the entire framebuffer
*/
for(j=0;j<HEIGHT;++j) {
for(i=0;i<WIDTH;++i) {
buffer[(j*WIDTH+i)*BPP+0]=(i+j)*128/(WIDTH+HEIGHT); /* red */
buffer[(j*WIDTH+i)*BPP+1]=i*128/WIDTH; /* green */
buffer[(j*WIDTH+i)*BPP+2]=j*256/HEIGHT; /* blue */
}
buffer[j*WIDTH*BPP+0]=0xff;
buffer[j*WIDTH*BPP+1]=0xff;
buffer[j*WIDTH*BPP+2]=0xff;
}
/*
* simulate the passage of time
*
* draw a simple black line that moves down the screen. The faster the
* client, the more updates it will get, the smoother it will look!
*/
gettimeofday(&now,NULL);
line = now.tv_usec / (1000000/HEIGHT);
if (line>HEIGHT) line=HEIGHT-1;
memset(&buffer[(WIDTH * BPP) * line], 0, (WIDTH * BPP));
/* frames per second (informational only) */
fcount++;
if (last_line > line) {
fps = fcount;
fcount = 0;
}
last_line = line;
fprintf(stderr,"%03d/%03d Picture (%03d fps)\r", line, HEIGHT, fps);
/* success! We have a new picture! */
return (1==1);
}
/*
* Single-threaded application that interleaves client servicing with taking
* pictures from the camera. This way, we do not update the framebuffer
* while an encoding is working on it too (banding, and image artifacts).
*/
int main(int argc,char** argv)
{
long usec;
rfbScreenInfoPtr server=rfbGetScreen(&argc,argv,WIDTH,HEIGHT,8,3,BPP);
server->desktopName = "Live Video Feed Example";
server->frameBuffer=(char*)malloc(WIDTH*HEIGHT*BPP);
server->alwaysShared=(1==1);
/* Initialize the server */
rfbInitServer(server);
/* Loop, processing clients and taking pictures */
while (rfbIsActive(server)) {
if (TimeToTakePicture())
if (TakePicture((unsigned char *)server->frameBuffer))
rfbMarkRectAsModified(server,0,0,WIDTH,HEIGHT);
usec = server->deferUpdateTime*1000;
rfbProcessEvents(server,usec);
}
return(0);
}

View File

@ -0,0 +1,32 @@
#include <rfb/rfb.h>
int main(int argc,char** argv)
{
int i;
uint8_t bytes[256*3];
rfbScreenInfoPtr server=rfbGetScreen(&argc,argv,256,256,8,1,1);
server->serverFormat.trueColour=FALSE;
server->colourMap.count=256;
server->colourMap.is16=FALSE;
for(i=0;i<256;i++) {
bytes[i*3+0]=255-i; /* red */
bytes[i*3+1]=0; /* green */
bytes[i*3+2]=i; /* blue */
}
bytes[128*3+0]=0xff;
bytes[128*3+1]=0;
bytes[128*3+2]=0;
server->colourMap.data.bytes=bytes;
server->frameBuffer=(char*)malloc(256*256);
for(i=0;i<256*256;i++)
server->frameBuffer[i]=(i/256);
rfbInitServer(server);
rfbRunEventLoop(server,-1,FALSE);
return(0);
}

View File

@ -0,0 +1,336 @@
/*
*
* This is an example of how to use libvncserver.
*
* libvncserver example
* Copyright (C) 2001 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#ifdef WIN32
#define sleep Sleep
#else
#include <unistd.h>
#endif
#ifdef __IRIX__
#include <netdb.h>
#endif
#include <rfb/rfb.h>
#include <rfb/keysym.h>
static const int bpp=4;
static int maxx=800, maxy=600;
/* TODO: odd maxx doesn't work (vncviewer bug) */
/* This initializes a nice (?) background */
static void initBuffer(unsigned char* buffer)
{
int i,j;
for(j=0;j<maxy;++j) {
for(i=0;i<maxx;++i) {
buffer[(j*maxx+i)*bpp+0]=(i+j)*128/(maxx+maxy); /* red */
buffer[(j*maxx+i)*bpp+1]=i*128/maxx; /* green */
buffer[(j*maxx+i)*bpp+2]=j*256/maxy; /* blue */
}
buffer[j*maxx*bpp+0]=0xff;
buffer[j*maxx*bpp+1]=0xff;
buffer[j*maxx*bpp+2]=0xff;
buffer[j*maxx*bpp+3]=0xff;
}
}
/* Here we create a structure so that every client has it's own pointer */
typedef struct ClientData {
rfbBool oldButton;
int oldx,oldy;
} ClientData;
static void clientgone(rfbClientPtr cl)
{
free(cl->clientData);
}
static enum rfbNewClientAction newclient(rfbClientPtr cl)
{
cl->clientData = (void*)calloc(sizeof(ClientData),1);
cl->clientGoneHook = clientgone;
return RFB_CLIENT_ACCEPT;
}
/* switch to new framebuffer contents */
static void newframebuffer(rfbScreenInfoPtr screen, int width, int height)
{
unsigned char *oldfb, *newfb;
maxx = width;
maxy = height;
oldfb = (unsigned char*)screen->frameBuffer;
newfb = (unsigned char*)malloc(maxx * maxy * bpp);
initBuffer(newfb);
rfbNewFramebuffer(screen, (char*)newfb, maxx, maxy, 8, 3, bpp);
free(oldfb);
/*** FIXME: Re-install cursor. ***/
}
/* aux function to draw a line */
static void drawline(unsigned char* buffer,int rowstride,int bpp,int x1,int y1,int x2,int y2)
{
int i,j;
i=x1-x2; j=y1-y2;
if(i==0 && j==0) {
for(i=0;i<bpp;i++)
buffer[y1*rowstride+x1*bpp+i]=0xff;
return;
}
if(i<0) i=-i;
if(j<0) j=-j;
if(i<j) {
if(y1>y2) { i=y2; y2=y1; y1=i; i=x2; x2=x1; x1=i; }
for(j=y1;j<=y2;j++)
for(i=0;i<bpp;i++)
buffer[j*rowstride+(x1+(j-y1)*(x2-x1)/(y2-y1))*bpp+i]=0xff;
} else {
if(x1>x2) { i=y2; y2=y1; y1=i; i=x2; x2=x1; x1=i; }
for(i=x1;i<=x2;i++)
for(j=0;j<bpp;j++)
buffer[(y1+(i-x1)*(y2-y1)/(x2-x1))*rowstride+i*bpp+j]=0xff;
}
}
/* Here the pointer events are handled */
static void doptr(int buttonMask,int x,int y,rfbClientPtr cl)
{
ClientData* cd=cl->clientData;
if(x>=0 && y>=0 && x<maxx && y<maxy) {
if(buttonMask) {
int i,j,x1,x2,y1,y2;
if(cd->oldButton==buttonMask) { /* draw a line */
drawline((unsigned char*)cl->screen->frameBuffer,cl->screen->paddedWidthInBytes,bpp,
x,y,cd->oldx,cd->oldy);
x1=x; y1=y;
if(x1>cd->oldx) x1++; else cd->oldx++;
if(y1>cd->oldy) y1++; else cd->oldy++;
rfbMarkRectAsModified(cl->screen,x,y,cd->oldx,cd->oldy);
} else { /* draw a point (diameter depends on button) */
int w=cl->screen->paddedWidthInBytes;
x1=x-buttonMask; if(x1<0) x1=0;
x2=x+buttonMask; if(x2>maxx) x2=maxx;
y1=y-buttonMask; if(y1<0) y1=0;
y2=y+buttonMask; if(y2>maxy) y2=maxy;
for(i=x1*bpp;i<x2*bpp;i++)
for(j=y1;j<y2;j++)
cl->screen->frameBuffer[j*w+i]=(char)0xff;
rfbMarkRectAsModified(cl->screen,x1,y1,x2,y2);
}
/* we could get a selection like that:
rfbGotXCutText(cl->screen,"Hallo",5);
*/
} else
cd->oldButton=0;
cd->oldx=x; cd->oldy=y; cd->oldButton=buttonMask;
}
rfbDefaultPtrAddEvent(buttonMask,x,y,cl);
}
/* aux function to draw a character to x, y */
#include "radon.h"
/* Here the key events are handled */
static void dokey(rfbBool down,rfbKeySym key,rfbClientPtr cl)
{
if(down) {
if(key==XK_Escape)
rfbCloseClient(cl);
else if(key==XK_F12)
/* close down server, disconnecting clients */
rfbShutdownServer(cl->screen,TRUE);
else if(key==XK_F11)
/* close down server, but wait for all clients to disconnect */
rfbShutdownServer(cl->screen,FALSE);
else if(key==XK_Page_Up) {
initBuffer((unsigned char*)cl->screen->frameBuffer);
rfbMarkRectAsModified(cl->screen,0,0,maxx,maxy);
} else if (key == XK_Up) {
if (maxx < 1024) {
if (maxx < 800) {
newframebuffer(cl->screen, 800, 600);
} else {
newframebuffer(cl->screen, 1024, 768);
}
}
} else if(key==XK_Down) {
if (maxx > 640) {
if (maxx > 800) {
newframebuffer(cl->screen, 800, 600);
} else {
newframebuffer(cl->screen, 640, 480);
}
}
} else if(key>=' ' && key<0x100) {
ClientData* cd=cl->clientData;
int x1=cd->oldx,y1=cd->oldy,x2,y2;
cd->oldx+=rfbDrawCharWithClip(cl->screen,&radonFont,cd->oldx,cd->oldy,(char)key,0,0,cl->screen->width,cl->screen->height,0x00ffffff,0x00ffffff);
rfbFontBBox(&radonFont,(char)key,&x1,&y1,&x2,&y2);
rfbMarkRectAsModified(cl->screen,x1,y1,x2-1,y2-1);
}
}
}
/* Example for an XCursor (foreground/background only) */
#ifdef JUST_AN_EXAMPLE
static int exampleXCursorWidth=9,exampleXCursorHeight=7;
static char exampleXCursor[]=
" "
" xx xx "
" xx xx "
" xxx "
" xx xx "
" xx xx "
" ";
#endif
/* Example for a rich cursor (full-colour) */
static void MakeRichCursor(rfbScreenInfoPtr rfbScreen)
{
int i,j,w=32,h=32;
rfbCursorPtr c = rfbScreen->cursor;
char bitmap[]=
" "
" xxxxxx "
" xxxxxxxxxxxxxxxxx "
" xxxxxxxxxxxxxxxxxxxxxx "
" xxxxx xxxxxxxx xxxxxxxx "
" xxxxxxxxxxxxxxxxxxxxxxxxxxx "
" xxxxxxxxxxxxxxxxxxxxxxxxxxxxx "
" xxxxx xxxxxxxxxxx xxxxxxx "
" xxxx xxxxxxxxx xxxxxx "
" xxxxx xxxxxxxxxxx xxxxxxx "
" xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx "
" xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx "
" xxxxxxxxxxxx xxxxxxxxxxxxxxx "
" xxxxxxxxxxxxxxxxxxxxxxxxxxxx "
" xxxxxxxxxxxxxxxxxxxxxxxxxxxx "
" xxxxxxxxxxx xxxxxxxxxxxxxx "
" xxxxxxxxxx xxxxxxxxxxxx "
" xxxxxxxxx xxxxxxxxx "
" xxxxxxxxxx xxxxxxxxx "
" xxxxxxxxxxxxxxxxxxx "
" xxxxxxxxxxxxxxxxxxx "
" xxxxxxxxxxxxxxxxxxx "
" xxxxxxxxxxxxxxxxx "
" xxxxxxxxxxxxxxx "
" xxxx xxxxxxxxxxxxx "
" xx x xxxxxxxxxxx "
" xxx xxxxxxxxxxx "
" xxxx xxxxxxxxxxx "
" xxxxxx xxxxxxxxxxxx "
" xxxxxxxxxxxxxxxxxxxxxx "
" xxxxxxxxxxxxxxxx "
" ";
c=rfbScreen->cursor = rfbMakeXCursor(w,h,bitmap,bitmap);
c->xhot = 16; c->yhot = 24;
c->richSource = (unsigned char*)malloc(w*h*bpp);
c->cleanupRichSource = TRUE;
for(j=0;j<h;j++) {
for(i=0;i<w;i++) {
c->richSource[j*w*bpp+i*bpp+0]=i*0xff/w;
c->richSource[j*w*bpp+i*bpp+1]=(i+j)*0xff/(w+h);
c->richSource[j*w*bpp+i*bpp+2]=j*0xff/h;
c->richSource[j*w*bpp+i*bpp+3]=0;
}
}
}
/* Initialization */
int main(int argc,char** argv)
{
rfbScreenInfoPtr rfbScreen =
rfbGetScreen(&argc,argv,maxx,maxy,8,3,bpp);
rfbScreen->desktopName = "LibVNCServer Example";
rfbScreen->frameBuffer = (char*)malloc(maxx*maxy*bpp);
rfbScreen->alwaysShared = TRUE;
rfbScreen->ptrAddEvent = doptr;
rfbScreen->kbdAddEvent = dokey;
rfbScreen->newClientHook = newclient;
rfbScreen->httpDir = "../classes";
rfbScreen->httpEnableProxyConnect = TRUE;
initBuffer((unsigned char*)rfbScreen->frameBuffer);
rfbDrawString(rfbScreen,&radonFont,20,100,"Hello, World!",0xffffff);
/* This call creates a mask and then a cursor: */
/* rfbScreen->defaultCursor =
rfbMakeXCursor(exampleCursorWidth,exampleCursorHeight,exampleCursor,0);
*/
MakeRichCursor(rfbScreen);
/* initialize the server */
rfbInitServer(rfbScreen);
#ifndef BACKGROUND_LOOP_TEST
#ifdef USE_OWN_LOOP
{
int i;
for(i=0;rfbIsActive(rfbScreen);i++) {
fprintf(stderr,"%d\r",i);
rfbProcessEvents(rfbScreen,100000);
}
}
#else
/* this is the blocking event loop, i.e. it never returns */
/* 40000 are the microseconds to wait on select(), i.e. 0.04 seconds */
rfbRunEventLoop(rfbScreen,40000,FALSE);
#endif /* OWN LOOP */
#else
#if !defined(LIBVNCSERVER_HAVE_LIBPTHREAD)
#error "I need pthreads for that."
#endif
/* this is the non-blocking event loop; a background thread is started */
rfbRunEventLoop(rfbScreen,-1,TRUE);
fprintf(stderr, "Running background loop...\n");
/* now we could do some cool things like rendering in idle time */
while(1) sleep(5); /* render(); */
#endif /* BACKGROUND_LOOP */
free(rfbScreen->frameBuffer);
rfbScreenCleanup(rfbScreen);
return(0);
}

View File

@ -0,0 +1,93 @@
# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** NICHT BEARBEITEN **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=example - Win32 Debug
!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
!MESSAGE
!MESSAGE NMAKE /f "example.mak".
!MESSAGE
!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
!MESSAGE
!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Debug"
!MESSAGE
!MESSAGE Für die Konfiguration stehen zur Auswahl:
!MESSAGE
!MESSAGE "example - Win32 Release" (basierend auf "Win32 (x86) Console Application")
!MESSAGE "example - Win32 Debug" (basierend auf "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "example - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "zlib" /I "libjpeg" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x407 /d "NDEBUG"
# ADD RSC /l 0x407 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib zlib.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"msvcrt.lib"
!ELSEIF "$(CFG)" == "example - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "zlib" /I "libjpeg" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib zlib.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /pdbtype:sept
!ENDIF
# Begin Target
# Name "example - Win32 Release"
# Name "example - Win32 Debug"
# Begin Group "Sources"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\example.c
# End Source File
# End Group
# End Target
# End Project

View File

@ -0,0 +1,11 @@
#include <rfb/rfb.h>
int main(int argc,char** argv)
{
rfbScreenInfoPtr server=rfbGetScreen(&argc,argv,400,300,8,3,4);
server->frameBuffer=(char*)malloc(400*300*4);
rfbRegisterTightVNCFileTransferExtension();
rfbInitServer(server);
rfbRunEventLoop(server,-1,FALSE);
return(0);
}

View File

@ -0,0 +1,73 @@
#include <rfb/rfb.h>
#define FONTDIR "/usr/lib/kbd/consolefonts/"
#define DEFAULTFONT FONTDIR "default8x16"
static char *fontlist[50]={
"8x16alt", "b.fnt", "c.fnt", "default8x16", "m.fnt", "ml.fnt", "mod_d.fnt",
"mod_s.fnt", "mr.fnt", "mu.fnt", "r.fnt", "rl.fnt", "ro.fnt", "s.fnt",
"sc.fnt", "scrawl_s.fnt", "scrawl_w.fnt", "sd.fnt", "t.fnt",
NULL
};
static rfbScreenInfoPtr rfbScreen = NULL;
static rfbFontDataPtr curFont = NULL;
static void showFont(int index)
{
char buffer[1024];
if(!rfbScreen) return;
if(curFont)
rfbFreeFont(curFont);
strcpy(buffer,FONTDIR);
strcat(buffer,fontlist[index]);
curFont = rfbLoadConsoleFont(buffer);
rfbFillRect(rfbScreen,210,30-20,210+10*16,30-20+256*20/16,0xb77797);
if(curFont) {
int i,j;
for(j=0;j<256;j+=16)
for(i=0;i<16;i++)
rfbDrawCharWithClip(rfbScreen,curFont,210+10*i,30+j*20/16,j+i,
0,0,640,480,0xffffff,0x000000);
}
}
int main(int argc,char** argv)
{
rfbFontDataPtr font;
rfbScreenInfoPtr s=rfbGetScreen(&argc,argv,640,480,8,3,3);
int i,j;
s->frameBuffer=(char*)malloc(640*480*3);
rfbInitServer(s);
for(j=0;j<480;j++)
for(i=0;i<640;i++) {
s->frameBuffer[(j*640+i)*3+0]=j*256/480;
s->frameBuffer[(j*640+i)*3+1]=i*256/640;
s->frameBuffer[(j*640+i)*3+2]=(i+j)*256/(480+640);
}
rfbScreen = s;
font=rfbLoadConsoleFont(DEFAULTFONT);
if(!font) {
rfbErr("Couldn't find %s\n",DEFAULTFONT);
exit(1);
}
for(j=0;j<0 && rfbIsActive(s);j++)
rfbProcessEvents(s,900000);
i = rfbSelectBox(s,font,fontlist,10,20,200,300,0xffdfdf,0x602040,2,showFont);
rfbLog("Selection: %d: %s\n",i,(i>=0)?fontlist[i]:"cancelled");
rfbFreeFont(font);
free(s->frameBuffer);
rfbScreenCleanup(s);
return(0);
}

View File

@ -0,0 +1,551 @@
/*
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
* All Rights Reserved.
*
* Cut in two parts by Johannes Schindelin (2001): libvncserver and OSXvnc.
*
*
* This file implements every system specific function for Mac OS X.
*
* It includes the keyboard functions:
*
void KbdAddEvent(down, keySym, cl)
rfbBool down;
rfbKeySym keySym;
rfbClientPtr cl;
void KbdReleaseAllKeys()
*
* the mouse functions:
*
void PtrAddEvent(buttonMask, x, y, cl)
int buttonMask;
int x;
int y;
rfbClientPtr cl;
*
*/
#include <unistd.h>
#include <ApplicationServices/ApplicationServices.h>
#include <Carbon/Carbon.h>
/* zlib doesn't like Byte already defined */
#undef Byte
#undef TRUE
#undef rfbBool
#include <rfb/rfb.h>
#include <rfb/keysym.h>
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <IOKit/pwr_mgt/IOPM.h>
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
rfbBool rfbNoDimming = FALSE;
rfbBool 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 rfbBool initialized = FALSE;
static rfbBool dim_time_saved = FALSE;
static rfbBool 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;
rfbBool disconnectAfterFirstClient = TRUE;
/* Where do I get the "official" list of Mac key codes?
Ripped these out of a Mac II emulator called Basilisk II
that I found on the net. */
static int keyTable[] = {
/* The alphabet */
XK_A, 0, /* A */
XK_B, 11, /* B */
XK_C, 8, /* C */
XK_D, 2, /* D */
XK_E, 14, /* E */
XK_F, 3, /* F */
XK_G, 5, /* G */
XK_H, 4, /* H */
XK_I, 34, /* I */
XK_J, 38, /* J */
XK_K, 40, /* K */
XK_L, 37, /* L */
XK_M, 46, /* M */
XK_N, 45, /* N */
XK_O, 31, /* O */
XK_P, 35, /* P */
XK_Q, 12, /* Q */
XK_R, 15, /* R */
XK_S, 1, /* S */
XK_T, 17, /* T */
XK_U, 32, /* U */
XK_V, 9, /* V */
XK_W, 13, /* W */
XK_X, 7, /* X */
XK_Y, 16, /* Y */
XK_Z, 6, /* Z */
XK_a, 0, /* a */
XK_b, 11, /* b */
XK_c, 8, /* c */
XK_d, 2, /* d */
XK_e, 14, /* e */
XK_f, 3, /* f */
XK_g, 5, /* g */
XK_h, 4, /* h */
XK_i, 34, /* i */
XK_j, 38, /* j */
XK_k, 40, /* k */
XK_l, 37, /* l */
XK_m, 46, /* m */
XK_n, 45, /* n */
XK_o, 31, /* o */
XK_p, 35, /* p */
XK_q, 12, /* q */
XK_r, 15, /* r */
XK_s, 1, /* s */
XK_t, 17, /* t */
XK_u, 32, /* u */
XK_v, 9, /* v */
XK_w, 13, /* w */
XK_x, 7, /* x */
XK_y, 16, /* y */
XK_z, 6, /* z */
/* Numbers */
XK_0, 29, /* 0 */
XK_1, 18, /* 1 */
XK_2, 19, /* 2 */
XK_3, 20, /* 3 */
XK_4, 21, /* 4 */
XK_5, 23, /* 5 */
XK_6, 22, /* 6 */
XK_7, 26, /* 7 */
XK_8, 28, /* 8 */
XK_9, 25, /* 9 */
/* Symbols */
XK_exclam, 18, /* ! */
XK_at, 19, /* @ */
XK_numbersign, 20, /* # */
XK_dollar, 21, /* $ */
XK_percent, 23, /* % */
XK_asciicircum, 22, /* ^ */
XK_ampersand, 26, /* & */
XK_asterisk, 28, /* * */
XK_parenleft, 25, /* ( */
XK_parenright, 29, /* ) */
XK_minus, 27, /* - */
XK_underscore, 27, /* _ */
XK_equal, 24, /* = */
XK_plus, 24, /* + */
XK_grave, 10, /* ` */ /* XXX ? */
XK_asciitilde, 10, /* ~ */
XK_bracketleft, 33, /* [ */
XK_braceleft, 33, /* { */
XK_bracketright, 30, /* ] */
XK_braceright, 30, /* } */
XK_semicolon, 41, /* ; */
XK_colon, 41, /* : */
XK_apostrophe, 39, /* ' */
XK_quotedbl, 39, /* " */
XK_comma, 43, /* , */
XK_less, 43, /* < */
XK_period, 47, /* . */
XK_greater, 47, /* > */
XK_slash, 44, /* / */
XK_question, 44, /* ? */
XK_backslash, 42, /* \ */
XK_bar, 42, /* | */
/* "Special" keys */
XK_space, 49, /* Space */
XK_Return, 36, /* Return */
XK_Delete, 117, /* Delete */
XK_Tab, 48, /* Tab */
XK_Escape, 53, /* Esc */
XK_Caps_Lock, 57, /* Caps Lock */
XK_Num_Lock, 71, /* Num Lock */
XK_Scroll_Lock, 107, /* Scroll Lock */
XK_Pause, 113, /* Pause */
XK_BackSpace, 51, /* Backspace */
XK_Insert, 114, /* Insert */
/* Cursor movement */
XK_Up, 126, /* Cursor Up */
XK_Down, 125, /* Cursor Down */
XK_Left, 123, /* Cursor Left */
XK_Right, 124, /* Cursor Right */
XK_Page_Up, 116, /* Page Up */
XK_Page_Down, 121, /* Page Down */
XK_Home, 115, /* Home */
XK_End, 119, /* End */
/* Numeric keypad */
XK_KP_0, 82, /* KP 0 */
XK_KP_1, 83, /* KP 1 */
XK_KP_2, 84, /* KP 2 */
XK_KP_3, 85, /* KP 3 */
XK_KP_4, 86, /* KP 4 */
XK_KP_5, 87, /* KP 5 */
XK_KP_6, 88, /* KP 6 */
XK_KP_7, 89, /* KP 7 */
XK_KP_8, 91, /* KP 8 */
XK_KP_9, 92, /* KP 9 */
XK_KP_Enter, 76, /* KP Enter */
XK_KP_Decimal, 65, /* KP . */
XK_KP_Add, 69, /* KP + */
XK_KP_Subtract, 78, /* KP - */
XK_KP_Multiply, 67, /* KP * */
XK_KP_Divide, 75, /* KP / */
/* Function keys */
XK_F1, 122, /* F1 */
XK_F2, 120, /* F2 */
XK_F3, 99, /* F3 */
XK_F4, 118, /* F4 */
XK_F5, 96, /* F5 */
XK_F6, 97, /* F6 */
XK_F7, 98, /* F7 */
XK_F8, 100, /* F8 */
XK_F9, 101, /* F9 */
XK_F10, 109, /* F10 */
XK_F11, 103, /* F11 */
XK_F12, 111, /* F12 */
/* Modifier keys */
XK_Shift_L, 56, /* Shift Left */
XK_Shift_R, 56, /* Shift Right */
XK_Control_L, 59, /* Ctrl Left */
XK_Control_R, 59, /* Ctrl Right */
XK_Meta_L, 58, /* Logo Left (-> Option) */
XK_Meta_R, 58, /* Logo Right (-> Option) */
XK_Alt_L, 55, /* Alt Left (-> Command) */
XK_Alt_R, 55, /* Alt Right (-> Command) */
/* Weirdness I can't figure out */
#if 0
XK_3270_PrintScreen, 105, /* PrintScrn */
??? 94, 50, /* International */
XK_Menu, 50, /* Menu (-> International) */
#endif
};
void
KbdAddEvent(rfbBool down, rfbKeySym keySym, struct _rfbClientRec* cl)
{
int i;
CGKeyCode keyCode = -1;
int found = 0;
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];
found = 1;
break;
}
}
if (!found) {
rfbErr("warning: couldn't figure out keycode for X keysym %d (0x%x)\n",
(int)keySym, (int)keySym);
} else {
/* Hopefully I can get away with not specifying a CGCharCode.
(Why would you need both?) */
CGPostKeyboardEvent((CGCharCode)0, keyCode, down);
}
}
void
PtrAddEvent(buttonMask, x, y, cl)
int buttonMask;
int x;
int y;
rfbClientPtr cl;
{
CGPoint position;
if(((int)cl->clientData)==-1) return; /* viewOnly */
rfbUndim();
position.x = x;
position.y = y;
CGPostMouseEvent(position, TRUE, 8,
(buttonMask & (1 << 0)) ? TRUE : FALSE,
(buttonMask & (1 << 1)) ? TRUE : FALSE,
(buttonMask & (1 << 2)) ? TRUE : FALSE,
(buttonMask & (1 << 3)) ? TRUE : FALSE,
(buttonMask & (1 << 4)) ? TRUE : FALSE,
(buttonMask & (1 << 5)) ? TRUE : FALSE,
(buttonMask & (1 << 6)) ? TRUE : FALSE,
(buttonMask & (1 << 7)) ? TRUE : FALSE);
}
rfbBool viewOnly = FALSE, sharedMode = FALSE;
void
ScreenInit(int argc, char**argv)
{
int bitsPerSample=CGDisplayBitsPerSample(kCGDirectMainDisplay);
rfbScreen = rfbGetScreen(&argc,argv,
CGDisplayPixelsWide(kCGDirectMainDisplay),
CGDisplayPixelsHigh(kCGDirectMainDisplay),
bitsPerSample,
CGDisplaySamplesPerPixel(kCGDirectMainDisplay),4);
rfbScreen->serverFormat.redShift = bitsPerSample*2;
rfbScreen->serverFormat.greenShift = bitsPerSample*1;
rfbScreen->serverFormat.blueShift = 0;
gethostname(rfbScreen->thisHost, 255);
rfbScreen->paddedWidthInBytes = CGDisplayBytesPerRow(kCGDirectMainDisplay);
rfbScreen->frameBuffer =
(char *)CGDisplayBaseAddress(kCGDirectMainDisplay);
/* we cannot write to the frame buffer */
rfbScreen->cursor = NULL;
rfbScreen->ptrAddEvent = PtrAddEvent;
rfbScreen->kbdAddEvent = KbdAddEvent;
if(sharedMode) {
rfbScreen->alwaysShared = TRUE;
}
rfbInitServer(rfbScreen);
}
static void
refreshCallback(CGRectCount count, const CGRect *rectArray, void *ignore)
{
int i;
if(startTime>0 && time(0)>startTime+maxSecsToConnect)
rfbShutdown(0);
for (i = 0; i < count; i++)
rfbMarkRectAsModified(rfbScreen,
rectArray[i].origin.x,rectArray[i].origin.y,
rectArray[i].origin.x + rectArray[i].size.width,
rectArray[i].origin.y + rectArray[i].size.height);
}
void clientGone(rfbClientPtr cl)
{
rfbShutdown(cl);
}
enum rfbNewClientAction newClient(rfbClientPtr cl)
{
if(startTime>0 && time(0)>startTime+maxSecsToConnect)
rfbShutdown(cl);
if(disconnectAfterFirstClient)
cl->clientGoneHook = clientGone;
cl->clientData=(void*)((viewOnly)?-1:0);
return(RFB_CLIENT_ACCEPT);
}
int main(int argc,char *argv[])
{
int i;
for(i=argc-1;i>0;i--)
if(i<argc-1 && strcmp(argv[i],"-wait4client")==0) {
maxSecsToConnect = atoi(argv[i+1])/1000;
startTime = time(0);
} else if(strcmp(argv[i],"-runforever")==0) {
disconnectAfterFirstClient = FALSE;
} else if(strcmp(argv[i],"-viewonly")==0) {
viewOnly=TRUE;
} else if(strcmp(argv[i],"-shared")==0) {
sharedMode=TRUE;
}
rfbDimmingInit();
ScreenInit(argc,argv);
rfbScreen->newClientHook = newClient;
/* enter background event loop */
rfbRunEventLoop(rfbScreen,40,TRUE);
/* enter OS X loop */
CGRegisterScreenRefreshCallback(refreshCallback, NULL);
RunApplicationEventLoop();
rfbDimmingShutdown();
return(0); /* never ... */
}
void rfbShutdown(rfbClientPtr cl)
{
rfbScreenCleanup(rfbScreen);
rfbDimmingShutdown();
exit(0);
}

View File

@ -0,0 +1,121 @@
#include <stdio.h>
#include <rfb/rfb.h>
#include <rfb/keysym.h>
#ifndef HAVE_HANDLEKEY
static void HandleKey(rfbBool down,rfbKeySym key,rfbClientPtr cl)
{
if(down && (key==XK_Escape || key=='q' || key=='Q'))
rfbCloseClient(cl);
}
#endif
int main(int argc,char** argv)
{
FILE* in=stdin;
int i,j,k,l,width,height,paddedWidth;
char buffer[1024];
rfbScreenInfoPtr rfbScreen;
enum { BW, GRAY, TRUECOLOUR } picType=TRUECOLOUR;
int bytesPerPixel,bitsPerPixelInFile;
if(argc>1) {
in=fopen(argv[1],"rb");
if(!in) {
printf("Couldn't find file %s.\n",argv[1]);
exit(1);
}
}
fgets(buffer,1024,in);
if(!strncmp(buffer,"P6",2)) {
picType=TRUECOLOUR;
bytesPerPixel=4; bitsPerPixelInFile=3*8;
} else if(!strncmp(buffer,"P5",2)) {
picType=GRAY;
bytesPerPixel=1; bitsPerPixelInFile=1*8;
} else if(!strncmp(buffer,"P4",2)) {
picType=BW;
bytesPerPixel=1; bitsPerPixelInFile=1;
} else {
printf("Not a ppm.\n");
exit(2);
}
/* skip comments */
do {
fgets(buffer,1024,in);
} while(buffer[0]=='#');
/* get width & height */
sscanf(buffer,"%d %d",&width,&height);
rfbLog("Got width %d and height %d.\n",width,height);
if(picType!=BW)
fgets(buffer,1024,in);
else
width=1+((width-1)|7);
/* vncviewers have problems with widths which are no multiple of 4. */
paddedWidth = width;
if(width&3)
paddedWidth+=4-(width&3);
/* initialize data for vnc server */
rfbScreen = rfbGetScreen(&argc,argv,paddedWidth,height,8,(bitsPerPixelInFile+7)/8,bytesPerPixel);
if(argc>1)
rfbScreen->desktopName = argv[1];
else
rfbScreen->desktopName = "Picture";
rfbScreen->alwaysShared = TRUE;
rfbScreen->kbdAddEvent = HandleKey;
/* enable http */
rfbScreen->httpDir = "../classes";
/* allocate picture and read it */
rfbScreen->frameBuffer = (char*)malloc(paddedWidth*bytesPerPixel*height);
fread(rfbScreen->frameBuffer,width*bitsPerPixelInFile/8,height,in);
fclose(in);
if(picType!=TRUECOLOUR) {
rfbScreen->serverFormat.trueColour=FALSE;
rfbScreen->colourMap.count=256;
rfbScreen->colourMap.is16=FALSE;
rfbScreen->colourMap.data.bytes=malloc(256*3);
for(i=0;i<256;i++)
memset(rfbScreen->colourMap.data.bytes+3*i,i,3);
}
switch(picType) {
case TRUECOLOUR:
/* correct the format to 4 bytes instead of 3 (and pad to paddedWidth) */
for(j=height-1;j>=0;j--) {
for(i=width-1;i>=0;i--)
for(k=2;k>=0;k--)
rfbScreen->frameBuffer[(j*paddedWidth+i)*4+k]=
rfbScreen->frameBuffer[(j*width+i)*3+k];
for(i=width*4;i<paddedWidth*4;i++)
rfbScreen->frameBuffer[j*paddedWidth*4+i]=0;
}
break;
case GRAY:
break;
case BW:
/* correct the format from 1 bit to 8 bits */
for(j=height-1;j>=0;j--)
for(i=width-1;i>=0;i-=8) {
l=(unsigned char)rfbScreen->frameBuffer[(j*width+i)/8];
for(k=7;k>=0;k--)
rfbScreen->frameBuffer[j*paddedWidth+i+7-k]=(l&(1<<k))?0:255;
}
break;
}
/* initialize server */
rfbInitServer(rfbScreen);
/* run event loop */
rfbRunEventLoop(rfbScreen,40000,FALSE);
return(0);
}

View File

@ -0,0 +1,94 @@
#include <stdio.h>
#include <rfb/rfb.h>
#include <rfb/keysym.h>
#ifndef LIBVNCSERVER_ALLOW24BPP
int main() {
printf("I need the ALLOW24BPP LibVNCServer flag to work\n");
exit(1);
}
#else
static void HandleKey(rfbBool down,rfbKeySym key,rfbClientPtr cl)
{
if(down && (key==XK_Escape || key=='q' || key=='Q'))
rfbCloseClient(cl);
}
int main(int argc,char** argv)
{
FILE* in=stdin;
int j,width,height,paddedWidth;
char buffer[1024];
rfbScreenInfoPtr rfbScreen;
if(argc>1) {
in=fopen(argv[1],"rb");
if(!in) {
printf("Couldn't find file %s.\n",argv[1]);
exit(1);
}
}
fgets(buffer,1024,in);
if(strncmp(buffer,"P6",2)) {
printf("Not a ppm.\n");
exit(2);
}
/* skip comments */
do {
fgets(buffer,1024,in);
} while(buffer[0]=='#');
/* get width & height */
sscanf(buffer,"%d %d",&width,&height);
rfbLog("Got width %d and height %d.\n",width,height);
fgets(buffer,1024,in);
/* vncviewers have problems with widths which are no multiple of 4. */
paddedWidth = width;
/* if your vncviewer doesn't have problems with a width
which is not a multiple of 4, you can comment this. */
if(width&3)
paddedWidth+=4-(width&3);
/* initialize data for vnc server */
rfbScreen = rfbGetScreen(&argc,argv,paddedWidth,height,8,3,3);
if(argc>1)
rfbScreen->desktopName = argv[1];
else
rfbScreen->desktopName = "Picture";
rfbScreen->alwaysShared = TRUE;
rfbScreen->kbdAddEvent = HandleKey;
/* enable http */
rfbScreen->httpDir = "../classes";
/* allocate picture and read it */
rfbScreen->frameBuffer = (char*)malloc(paddedWidth*3*height);
fread(rfbScreen->frameBuffer,width*3,height,in);
fclose(in);
/* pad to paddedWidth */
if(width != paddedWidth) {
int padCount = 3*(paddedWidth - width);
for(j=height-1;j>=0;j--) {
memmove(rfbScreen->frameBuffer+3*paddedWidth*j,
rfbScreen->frameBuffer+3*width*j,
3*width);
memset(rfbScreen->frameBuffer+3*paddedWidth*(j+1)-padCount,
0,padCount);
}
}
/* initialize server */
rfbInitServer(rfbScreen);
/* run event loop */
rfbRunEventLoop(rfbScreen,40000,FALSE);
return(0);
}
#endif

View File

@ -0,0 +1,195 @@
static unsigned char radonFontData[2280]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 32 */
0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x10,0x10,0x00,0x00, /* 33 */
0x00,0x28,0x28,0x28,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 34 */
0x00,0x44,0x44,0xba,0x44,0x44,0x44,0xba,0x44,0x44,0x00,0x00, /* 35 */
0x10,0x7e,0x80,0x90,0x80,0x7c,0x02,0x12,0x02,0xfc,0x10,0x00, /* 36 */
0x00,0x62,0x92,0x94,0x68,0x10,0x2c,0x52,0x92,0x8c,0x00,0x00, /* 37 */
0x00,0x60,0x90,0x90,0x40,0x20,0x90,0x8a,0x84,0x7a,0x00,0x00, /* 38 */
0x00,0x10,0x10,0x10,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 39 */
0x00,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x00,0x00, /* 40 */
0x00,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x00,0x00, /* 41 */
0x00,0x10,0x92,0x54,0x10,0x10,0x54,0x92,0x10,0x00,0x00,0x00, /* 42 */
0x00,0x00,0x10,0x10,0x10,0xd6,0x10,0x10,0x10,0x00,0x00,0x00, /* 43 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x30,0x00, /* 44 */
0x00,0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00, /* 45 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00, /* 46 */
0x00,0x02,0x02,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x00,0x00, /* 47 */
0x00,0x7c,0x82,0x82,0x82,0xba,0x82,0x82,0x82,0x7c,0x00,0x00, /* 48 */
0x00,0x08,0x28,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00, /* 49 */
0x00,0xfc,0x02,0x02,0x02,0x7c,0x80,0x80,0x00,0xfe,0x00,0x00, /* 50 */
0x00,0xfc,0x02,0x02,0x02,0x3c,0x02,0x02,0x02,0xfc,0x00,0x00, /* 51 */
0x00,0x82,0x82,0x82,0x82,0x7a,0x02,0x02,0x02,0x02,0x00,0x00, /* 52 */
0x00,0xfe,0x00,0x80,0x80,0x7c,0x02,0x02,0x02,0xfc,0x00,0x00, /* 53 */
0x00,0x7c,0x80,0x80,0xbc,0x82,0x82,0x82,0x82,0x7c,0x00,0x00, /* 54 */
0x00,0xfc,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x00, /* 55 */
0x00,0x7c,0x82,0x82,0x82,0x7c,0x82,0x82,0x82,0x7c,0x00,0x00, /* 56 */
0x00,0x7c,0x82,0x82,0x82,0x82,0x7a,0x02,0x02,0xfc,0x00,0x00, /* 57 */
0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00, /* 58 */
0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x10,0x10,0x60,0x00,0x00, /* 59 */
0x00,0x08,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x08,0x00,0x00, /* 60 */
0x00,0x00,0x00,0x00,0xfe,0x00,0xfe,0x00,0x00,0x00,0x00,0x00, /* 61 */
0x00,0x10,0x10,0x08,0x04,0x02,0x04,0x08,0x10,0x10,0x00,0x00, /* 62 */
0x00,0xfc,0x02,0x02,0x02,0x1c,0x20,0x20,0x00,0x20,0x00,0x00, /* 63 */
0x00,0x7c,0x82,0x8a,0x92,0x92,0x92,0x8c,0x80,0x7c,0x00,0x00, /* 64 */
0x00,0x7c,0x82,0x82,0x82,0x82,0xba,0x82,0x82,0x82,0x00,0x00, /* 65 */
0x00,0xbc,0x82,0x82,0x82,0xbc,0x82,0x82,0x82,0xbc,0x00,0x00, /* 66 */
0x00,0x7c,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7c,0x00,0x00, /* 67 */
0x00,0xbc,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xbc,0x00,0x00, /* 68 */
0x00,0x7c,0x80,0x80,0x80,0xb8,0x80,0x80,0x80,0x7c,0x00,0x00, /* 69 */
0x00,0x7c,0x80,0x80,0x80,0xb8,0x80,0x80,0x80,0x80,0x00,0x00, /* 70 */
0x00,0x7c,0x80,0x80,0x80,0x80,0x9a,0x82,0x82,0x7c,0x00,0x00, /* 71 */
0x00,0x82,0x82,0x82,0x82,0xba,0x82,0x82,0x82,0x82,0x00,0x00, /* 72 */
0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, /* 73 */
0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x84,0x78,0x00,0x00, /* 74 */
0x00,0x82,0x82,0x82,0x82,0xbc,0x82,0x82,0x82,0x82,0x00,0x00, /* 75 */
0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7e,0x00,0x00, /* 76 */
0x00,0x7c,0x82,0x92,0x92,0x92,0x92,0x82,0x82,0x82,0x00,0x00, /* 77 */
0x00,0x7c,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x00,0x00, /* 78 */
0x00,0x7c,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x7c,0x00,0x00, /* 79 */
0x00,0xbc,0x82,0x82,0x82,0xbc,0x80,0x80,0x80,0x80,0x00,0x00, /* 80 */
0x00,0x7c,0x82,0x82,0x82,0x82,0x8a,0x8a,0x82,0x7c,0x00,0x00, /* 81 */
0x00,0xbc,0x82,0x82,0x82,0xbc,0x82,0x82,0x82,0x82,0x00,0x00, /* 82 */
0x00,0x7e,0x80,0x80,0x80,0x7c,0x02,0x02,0x02,0xfc,0x00,0x00, /* 83 */
0x00,0xfe,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, /* 84 */
0x00,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x7c,0x00,0x00, /* 85 */
0x00,0x82,0x82,0x82,0x82,0x82,0x84,0x88,0x90,0xa0,0x00,0x00, /* 86 */
0x00,0x82,0x82,0x82,0x82,0x92,0x92,0x92,0x82,0x7c,0x00,0x00, /* 87 */
0x00,0x82,0x82,0x82,0x82,0x7c,0x82,0x82,0x82,0x82,0x00,0x00, /* 88 */
0x00,0x82,0x82,0x82,0x82,0x7c,0x00,0x10,0x10,0x10,0x00,0x00, /* 89 */
0x00,0xfc,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x7e,0x00,0x00, /* 90 */
0x00,0x1c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x1c,0x00,0x00, /* 91 */
0x00,0x80,0x80,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x00,0x00, /* 92 */
0x00,0x38,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x38,0x00,0x00, /* 93 */
0x00,0x38,0x44,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 94 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00, /* 95 */
0x00,0x08,0x08,0x08,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 96 */
0x00,0x00,0x00,0x00,0x3c,0x02,0x3a,0x42,0x42,0x3c,0x00,0x00, /* 97 */
0x00,0x00,0x40,0x40,0x5c,0x42,0x42,0x42,0x42,0x3c,0x00,0x00, /* 98 */
0x00,0x00,0x00,0x00,0x3c,0x40,0x40,0x40,0x40,0x3c,0x00,0x00, /* 99 */
0x00,0x00,0x02,0x02,0x3a,0x42,0x42,0x42,0x42,0x3c,0x00,0x00, /* 100 */
0x00,0x00,0x00,0x00,0x3c,0x42,0x42,0x5c,0x40,0x3c,0x00,0x00, /* 101 */
0x00,0x00,0x0c,0x10,0x10,0x10,0x54,0x10,0x10,0x10,0x00,0x00, /* 102 */
0x00,0x00,0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x3a,0x02,0x3c, /* 103 */
0x00,0x00,0x40,0x40,0x5c,0x42,0x42,0x42,0x42,0x42,0x00,0x00, /* 104 */
0x00,0x00,0x08,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00, /* 105 */
0x00,0x00,0x08,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x30, /* 106 */
0x00,0x00,0x40,0x40,0x42,0x42,0x5c,0x42,0x42,0x42,0x00,0x00, /* 107 */
0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00, /* 108 */
0x00,0x00,0x00,0x00,0x7c,0x82,0x92,0x92,0x92,0x92,0x00,0x00, /* 109 */
0x00,0x00,0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x42,0x00,0x00, /* 110 */
0x00,0x00,0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x3c,0x00,0x00, /* 111 */
0x00,0x00,0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x5c,0x40,0x40, /* 112 */
0x00,0x00,0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x3a,0x02,0x02, /* 113 */
0x00,0x00,0x00,0x00,0x0c,0x10,0x10,0x10,0x10,0x10,0x00,0x00, /* 114 */
0x00,0x00,0x00,0x00,0x3e,0x40,0x3c,0x02,0x02,0x7c,0x00,0x00, /* 115 */
0x00,0x00,0x10,0x10,0x10,0x54,0x10,0x10,0x10,0x0c,0x00,0x00, /* 116 */
0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x3c,0x00,0x00, /* 117 */
0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x44,0x48,0x50,0x00,0x00, /* 118 */
0x00,0x00,0x00,0x00,0x92,0x92,0x92,0x92,0x82,0x7c,0x00,0x00, /* 119 */
0x00,0x00,0x00,0x00,0x42,0x42,0x3c,0x42,0x42,0x42,0x00,0x00, /* 120 */
0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x3a,0x02,0x3c, /* 121 */
0x00,0x00,0x00,0x00,0x7c,0x02,0x0c,0x30,0x40,0x3e,0x00,0x00, /* 122 */
0x00,0x1c,0x20,0x20,0x20,0x40,0x20,0x20,0x20,0x1c,0x00,0x00, /* 123 */
0x00,0x10,0x10,0x10,0x10,0x00,0x10,0x10,0x10,0x10,0x00,0x00, /* 124 */
0x00,0x38,0x04,0x04,0x04,0x02,0x04,0x04,0x04,0x38,0x00,0x00, /* 125 */
0x00,0x04,0x38,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 126 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160 */
0x00,0x10,0x10,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, /* 161 */
0x00,0x00,0x08,0x3e,0x40,0x48,0x48,0x40,0x3e,0x08,0x00,0x00, /* 162 */
0x00,0x1c,0x20,0x20,0x20,0xa8,0x20,0x20,0x42,0xbc,0x00,0x00, /* 163 */
0x00,0x00,0x82,0x38,0x44,0x44,0x44,0x38,0x82,0x00,0x00,0x00, /* 164 */
0x00,0x82,0x82,0x82,0x7c,0x00,0x54,0x10,0x54,0x10,0x00,0x00, /* 165 */
0x00,0x10,0x10,0x10,0x00,0x00,0x00,0x10,0x10,0x10,0x00,0x00, /* 166 */
0x00,0x38,0x40,0x38,0x44,0x44,0x44,0x44,0x38,0x04,0x38,0x00, /* 167 */
0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168 */
0x00,0x7c,0x82,0x9a,0xa2,0xa2,0xa2,0x9a,0x82,0x7c,0x00,0x00, /* 169 */
0x38,0x04,0x34,0x44,0x38,0x00,0x7c,0x00,0x00,0x00,0x00,0x00, /* 170 */
0x00,0x00,0x00,0x24,0x48,0x00,0x48,0x24,0x00,0x00,0x00,0x00, /* 171 */
0x00,0x00,0x00,0x00,0x00,0xfc,0x02,0x02,0x02,0x00,0x00,0x00, /* 172 */
0x00,0x00,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00, /* 173 */
0x00,0x7c,0x82,0x92,0xaa,0xb2,0xaa,0xaa,0x82,0x7c,0x00,0x00, /* 174 */
0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 175 */
0x38,0x44,0x44,0x44,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176 */
0x00,0x10,0x10,0xd6,0x10,0x10,0x00,0xfe,0x00,0x00,0x00,0x00, /* 177 */
0x38,0x04,0x18,0x20,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 178 */
0x38,0x04,0x38,0x04,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 179 */
0x18,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 180 */
0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x58,0x40,0x40, /* 181 */
0x00,0x79,0xfa,0xfa,0xfa,0x7a,0x02,0x0a,0x0a,0x0a,0x0a,0x00, /* 182 */
0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00, /* 183 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00, /* 184 */
0x08,0x18,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 185 */
0x38,0x44,0x44,0x38,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00, /* 186 */
0x00,0x00,0x00,0x48,0x24,0x00,0x24,0x48,0x00,0x00,0x00,0x00, /* 187 */
0x20,0xa2,0x22,0x22,0x24,0x08,0x10,0x29,0x49,0x85,0x01,0x01, /* 188 */
0x20,0xa2,0x22,0x22,0x24,0x08,0x10,0x2e,0x41,0x86,0x08,0x0f, /* 189 */
0xe0,0x12,0xe2,0x12,0xe4,0x08,0x10,0x29,0x49,0x85,0x01,0x01, /* 190 */
0x00,0x08,0x00,0x08,0x08,0x70,0x80,0x80,0x80,0x7e,0x00,0x00, /* 191 */
0x20,0x18,0x00,0x7c,0x82,0x82,0x82,0xba,0x82,0x82,0x00,0x00, /* 192 */
0x08,0x30,0x00,0x7c,0x82,0x82,0x82,0xba,0x82,0x82,0x00,0x00, /* 193 */
0x38,0x44,0x00,0x7c,0x82,0x82,0x82,0xba,0x82,0x82,0x00,0x00, /* 194 */
0x32,0x4c,0x00,0x7c,0x82,0x82,0x82,0xba,0x82,0x82,0x00,0x00, /* 195 */
0x6c,0x00,0x00,0x7c,0x82,0x82,0x82,0xba,0x82,0x82,0x00,0x00, /* 196 */
0x38,0x44,0x38,0x7c,0x82,0x82,0x82,0xba,0x82,0x82,0x00,0x00, /* 197 */
0x00,0x77,0x88,0x88,0x88,0x8b,0xa8,0x88,0x88,0x8b,0x00,0x00, /* 198 */
0x00,0x7c,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x6c,0x10,0x20, /* 199 */
0x20,0x18,0x00,0x7c,0x80,0x80,0xb8,0x80,0x80,0x7c,0x00,0x00, /* 200 */
0x08,0x30,0x00,0x7c,0x80,0x80,0xb8,0x80,0x80,0x7c,0x00,0x00, /* 201 */
0x38,0x44,0x00,0x7c,0x80,0x80,0xb8,0x80,0x80,0x7c,0x00,0x00, /* 202 */
0x6c,0x00,0x00,0x7c,0x80,0x80,0xb8,0x80,0x80,0x7c,0x00,0x00, /* 203 */
0x20,0x18,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, /* 204 */
0x08,0x30,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, /* 205 */
0x38,0x44,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, /* 206 */
0x6c,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, /* 207 */
0x00,0xbc,0x82,0x82,0x82,0xb2,0x82,0x82,0x82,0xbc,0x00,0x00, /* 208 */
0x32,0x4c,0x00,0x7c,0x82,0x82,0x82,0x82,0x82,0x82,0x00,0x00, /* 209 */
0x20,0x18,0x00,0x7c,0x82,0x82,0x82,0x82,0x82,0x7c,0x00,0x00, /* 210 */
0x08,0x30,0x00,0x7c,0x82,0x82,0x82,0x82,0x82,0x7c,0x00,0x00, /* 211 */
0x38,0x44,0x00,0x7c,0x82,0x82,0x82,0x82,0x82,0x7c,0x00,0x00, /* 212 */
0x32,0x4c,0x00,0x7c,0x82,0x82,0x82,0x82,0x82,0x7c,0x00,0x00, /* 213 */
0x6c,0x00,0x00,0x7c,0x82,0x82,0x82,0x82,0x82,0x7c,0x00,0x00, /* 214 */
0x00,0x00,0x00,0x00,0x44,0x28,0x00,0x28,0x44,0x00,0x00,0x00, /* 215 */
0x00,0x7a,0x84,0x82,0x8a,0x92,0xa2,0x82,0x42,0xbc,0x00,0x00, /* 216 */
0x20,0x18,0x00,0x82,0x82,0x82,0x82,0x82,0x82,0x7c,0x00,0x00, /* 217 */
0x08,0x30,0x00,0x82,0x82,0x82,0x82,0x82,0x82,0x7c,0x00,0x00, /* 218 */
0x38,0x44,0x00,0x82,0x82,0x82,0x82,0x82,0x82,0x7c,0x00,0x00, /* 219 */
0x6c,0x00,0x00,0x82,0x82,0x82,0x82,0x82,0x82,0x7c,0x00,0x00, /* 220 */
0x08,0xb2,0x82,0x82,0x82,0x7c,0x00,0x10,0x10,0x10,0x00,0x00, /* 221 */
0x00,0x80,0x80,0xbc,0x82,0x82,0x82,0xbc,0x80,0x80,0x00,0x00, /* 222 */
0x00,0x3c,0x42,0x42,0x42,0x5c,0x42,0x42,0x42,0x9c,0x00,0x00, /* 223 */
0x20,0x18,0x00,0x00,0x3c,0x02,0x3a,0x42,0x42,0x3c,0x00,0x00, /* 224 */
0x08,0x30,0x00,0x00,0x3c,0x02,0x3a,0x42,0x42,0x3c,0x00,0x00, /* 225 */
0x38,0x44,0x00,0x00,0x3c,0x02,0x3a,0x42,0x42,0x3c,0x00,0x00, /* 226 */
0x32,0x4c,0x00,0x00,0x3c,0x02,0x3a,0x42,0x42,0x3c,0x00,0x00, /* 227 */
0x6c,0x00,0x00,0x00,0x3c,0x02,0x3a,0x42,0x42,0x3c,0x00,0x00, /* 228 */
0x18,0x24,0x18,0x00,0x3c,0x02,0x3a,0x42,0x42,0x3c,0x00,0x00, /* 229 */
0x00,0x00,0x00,0x00,0x6c,0x12,0x52,0x94,0x90,0x6e,0x00,0x00, /* 230 */
0x00,0x00,0x00,0x00,0x3c,0x40,0x40,0x40,0x40,0x34,0x08,0x10, /* 231 */
0x20,0x18,0x00,0x00,0x3c,0x42,0x42,0x5c,0x40,0x3c,0x00,0x00, /* 232 */
0x08,0x30,0x00,0x00,0x3c,0x42,0x42,0x5c,0x40,0x3c,0x00,0x00, /* 233 */
0x38,0x44,0x00,0x00,0x3c,0x42,0x42,0x5c,0x40,0x3c,0x00,0x00, /* 234 */
0x6c,0x00,0x00,0x00,0x3c,0x42,0x42,0x5c,0x40,0x3c,0x00,0x00, /* 235 */
0x20,0x18,0x00,0x10,0x00,0x10,0x10,0x10,0x10,0x10,0x00,0x00, /* 236 */
0x08,0x30,0x00,0x10,0x00,0x10,0x10,0x10,0x10,0x10,0x00,0x00, /* 237 */
0x38,0x44,0x00,0x10,0x00,0x10,0x10,0x10,0x10,0x10,0x00,0x00, /* 238 */
0x6c,0x00,0x00,0x10,0x00,0x10,0x10,0x10,0x10,0x10,0x00,0x00, /* 239 */
0x00,0x14,0x08,0x14,0x02,0x3a,0x42,0x42,0x42,0x3c,0x00,0x00, /* 240 */
0x00,0x32,0x4c,0x00,0x3c,0x42,0x42,0x42,0x42,0x42,0x00,0x00, /* 241 */
0x20,0x18,0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x3c,0x00,0x00, /* 242 */
0x08,0x30,0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x3c,0x00,0x00, /* 243 */
0x38,0x44,0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x3c,0x00,0x00, /* 244 */
0x32,0x4c,0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x3c,0x00,0x00, /* 245 */
0x6c,0x00,0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x3c,0x00,0x00, /* 246 */
0x00,0x00,0x00,0x00,0x38,0x00,0xfe,0x00,0x38,0x00,0x00,0x00, /* 247 */
0x00,0x00,0x00,0x00,0x3a,0x44,0x4a,0x52,0x22,0x5c,0x00,0x00, /* 248 */
0x20,0x18,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x3c,0x00,0x00, /* 249 */
0x08,0x30,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x3c,0x00,0x00, /* 250 */
0x38,0x44,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x3c,0x00,0x00, /* 251 */
0x6c,0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x3c,0x00,0x00, /* 252 */
0x04,0x18,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x3a,0x02,0x3c, /* 253 */
0x00,0x80,0x80,0x9c,0xa2,0x82,0xa2,0x9c,0x80,0x80,0x00,0x00, /* 254 */
};
static int radonFontMetaData[256*5]={
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,12,0,-2,12,8,12,0,-2,24,8,12,0,-2,36,8,12,0,-2,48,8,12,0,-2,60,8,12,0,-2,72,8,12,0,-2,84,8,12,0,-2,96,8,12,0,-2,108,8,12,0,-2,120,8,12,0,-2,132,8,12,0,-2,144,8,12,0,-2,156,8,12,0,-2,168,8,12,0,-2,180,8,12,0,-2,192,8,12,0,-2,204,8,12,0,-2,216,8,12,0,-2,228,8,12,0,-2,240,8,12,0,-2,252,8,12,0,-2,264,8,12,0,-2,276,8,12,0,-2,288,8,12,0,-2,300,8,12,0,-2,312,8,12,0,-2,324,8,12,0,-2,336,8,12,0,-2,348,8,12,0,-2,360,8,12,0,-2,372,8,12,0,-2,384,8,12,0,-2,396,8,12,0,-2,408,8,12,0,-2,420,8,12,0,-2,432,8,12,0,-2,444,8,12,0,-2,456,8,12,0,-2,468,8,12,0,-2,480,8,12,0,-2,492,8,12,0,-2,504,8,12,0,-2,516,8,12,0,-2,528,8,12,0,-2,540,8,12,0,-2,552,8,12,0,-2,564,8,12,0,-2,576,8,12,0,-2,588,8,12,0,-2,600,8,12,0,-2,612,8,12,0,-2,624,8,12,0,-2,636,8,12,0,-2,648,8,12,0,-2,660,8,12,0,-2,672,8,12,0,-2,684,8,12,0,-2,696,8,12,0,-2,708,8,12,0,-2,720,8,12,0,-2,732,8,12,0,-2,744,8,12,0,-2,756,8,12,0,-2,768,8,12,0,-2,780,8,12,0,-2,792,8,12,0,-2,804,8,12,0,-2,816,8,12,0,-2,828,8,12,0,-2,840,8,12,0,-2,852,8,12,0,-2,864,8,12,0,-2,876,8,12,0,-2,888,8,12,0,-2,900,8,12,0,-2,912,8,12,0,-2,924,8,12,0,-2,936,8,12,0,-2,948,8,12,0,-2,960,8,12,0,-2,972,8,12,0,-2,984,8,12,0,-2,996,8,12,0,-2,1008,8,12,0,-2,1020,8,12,0,-2,1032,8,12,0,-2,1044,8,12,0,-2,1056,8,12,0,-2,1068,8,12,0,-2,1080,8,12,0,-2,1092,8,12,0,-2,1104,8,12,0,-2,1116,8,12,0,-2,1128,8,12,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1140,8,12,0,-2,1152,8,12,0,-2,1164,8,12,0,-2,1176,8,12,0,-2,1188,8,12,0,-2,1200,8,12,0,-2,1212,8,12,0,-2,1224,8,12,0,-2,1236,8,12,0,-2,1248,8,12,0,-2,1260,8,12,0,-2,1272,8,12,0,-2,1284,8,12,0,-2,1296,8,12,0,-2,1308,8,12,0,-2,1320,8,12,0,-2,1332,8,12,0,-2,1344,8,12,0,-2,1356,8,12,0,-2,1368,8,12,0,-2,1380,8,12,0,-2,1392,8,12,0,-2,1404,8,12,0,-2,1416,8,12,0,-2,1428,8,12,0,-2,1440,8,12,0,-2,1452,8,12,0,-2,1464,8,12,0,-2,1476,8,12,0,-2,1488,8,12,0,-2,1500,8,12,0,-2,1512,8,12,0,-2,1524,8,12,0,-2,1536,8,12,0,-2,1548,8,12,0,-2,1560,8,12,0,-2,1572,8,12,0,-2,1584,8,12,0,-2,1596,8,12,0,-2,1608,8,12,0,-2,1620,8,12,0,-2,1632,8,12,0,-2,1644,8,12,0,-2,1656,8,12,0,-2,1668,8,12,0,-2,1680,8,12,0,-2,1692,8,12,0,-2,1704,8,12,0,-2,1716,8,12,0,-2,1728,8,12,0,-2,1740,8,12,0,-2,1752,8,12,0,-2,1764,8,12,0,-2,1776,8,12,0,-2,1788,8,12,0,-2,1800,8,12,0,-2,1812,8,12,0,-2,1824,8,12,0,-2,1836,8,12,0,-2,1848,8,12,0,-2,1860,8,12,0,-2,1872,8,12,0,-2,1884,8,12,0,-2,1896,8,12,0,-2,1908,8,12,0,-2,1920,8,12,0,-2,1932,8,12,0,-2,1944,8,12,0,-2,1956,8,12,0,-2,1968,8,12,0,-2,1980,8,12,0,-2,1992,8,12,0,-2,2004,8,12,0,-2,2016,8,12,0,-2,2028,8,12,0,-2,2040,8,12,0,-2,2052,8,12,0,-2,2064,8,12,0,-2,2076,8,12,0,-2,2088,8,12,0,-2,2100,8,12,0,-2,2112,8,12,0,-2,2124,8,12,0,-2,2136,8,12,0,-2,2148,8,12,0,-2,2160,8,12,0,-2,2172,8,12,0,-2,2184,8,12,0,-2,2196,8,12,0,-2,2208,8,12,0,-2,2220,8,12,0,-2,2232,8,12,0,-2,2244,8,12,0,-2,2256,8,12,0,-2,2268,8,12,0,-2,0,0,0,0,0,};
static rfbFontData radonFont={radonFontData, radonFontMetaData};

Some files were not shown because too many files have changed in this diff Show More