summaryrefslogtreecommitdiffstats
path: root/VisualNaCro/nacro.c
diff options
context:
space:
mode:
authorChristian Beier <dontmind@freeshell.org>2014-09-09 11:06:22 +0200
committerChristian Beier <dontmind@freeshell.org>2014-09-09 11:06:22 +0200
commit7960c6871dd21036d7fe7d9b9ccb6774177d658c (patch)
treeb66b654a62632d6838c34ef4323a0e1e80aba95b /VisualNaCro/nacro.c
parent9bf5fe016017d2028fae3625b4615c4798e81efb (diff)
downloadlibvncserver-7960c6871dd21036d7fe7d9b9ccb6774177d658c.zip
libvncserver-7960c6871dd21036d7fe7d9b9ccb6774177d658c.tar.gz
Move VisualNaCro to https://github.com/LibVNC/VisualNaCro.
Diffstat (limited to 'VisualNaCro/nacro.c')
-rw-r--r--VisualNaCro/nacro.c801
1 files changed, 0 insertions, 801 deletions
diff --git a/VisualNaCro/nacro.c b/VisualNaCro/nacro.c
deleted file mode 100644
index 9c492b0..0000000
--- a/VisualNaCro/nacro.c
+++ /dev/null
@@ -1,801 +0,0 @@
-#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);
- if(!res->server)
- return FALSE;
- 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;
-}
-
OpenPOWER on IntegriCloud