Commit 336d7dad authored by dscho's avatar dscho

fix most TODOs; recorder.pl now actually records something; add nacro.pm to package

parent 2d03c071
......@@ -10,7 +10,7 @@ nacro_CFLAGS= @LIBVNCSERVERCFLAGS@
SWIGOPT=
EXTRA_DIST=autogen.sh $(INTERFACE) $(SRCS) $(ISRCS) recorder.pl
EXTRA_DIST=autogen.sh $(INTERFACE) $(SRCS) $(ISRCS) nacro.pm recorder.pl
all: $(LIBPREFIX)$(TARGET)$(SO)
......@@ -39,11 +39,11 @@ PERL5_CCFLAGS = @PERL5CCFLAGS@
$(ISRCS): $(INTERFACE)
$(SWIG) -perl5 $(SWIGOPT) $(INTERFACE)
$(OBJS): $(SRCS)
$(CC) -c -Dbool=char $(CCSHARED) $(CFLAGS) -o $@ $^ $(LIBVNCSERVERCFLAGS) $(INCLUDES) -I$(PERL5_INCLUDE)
$(OBJS): $(SRCS) $(INTERFACE)
$(CC) -c -Dbool=char $(CCSHARED) $(CFLAGS) -o $@ $< $(LIBVNCSERVERCFLAGS) $(INCLUDES) -I$(PERL5_INCLUDE)
$(IOBJS): $(ISRCS)
$(CC) -c -Dbool=char $(CCSHARED) $(CFLAGS) -o $@ $^ $(INCLUDES) $(PERL5_CCFLAGS) -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)
......
This diff is collapsed.
......@@ -110,16 +110,50 @@ rfbBool malloc_frame_buffer(rfbClient* cl)
}
}
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;
}
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) {
/* TODO: find image and set x_origin,y_origin if found */
} else {
res->state=RESULT_SCREEN;
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);
......@@ -180,7 +214,8 @@ bool_t savepnm(resource_t resource,const char* filename,int x1,int y1,int x2,int
uint32_t* buffer;
FILE* f;
assert(res->client);
if(res==0 || res->client==0)
return 0;
assert(res->client->format.depth==24);
w=res->client->width;
......@@ -228,7 +263,7 @@ image_t* loadpnm(const char* filename)
}
} while(buffer[0]=='#');
if(!fgets(buffer,1024,f) || sscanf(buffer,"%d %d",&w,&h)!=2
if( sscanf(buffer,"%d %d",&w,&h)!=2
|| !fgets(buffer,1024,f) || strcmp("255\n",buffer)) {
fclose(f);
return 0;
......@@ -246,7 +281,8 @@ image_t* loadpnm(const char* filename)
for(j=0;j<h;j++)
for(i=0;i<w;i++)
if(fread(image->buffer+4*(i+w*j),3,1,f)!=3) {
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);
......@@ -291,9 +327,9 @@ result_t private_process(resource_t resource,timeout_t timeout_in_seconds,result
rfbBool loop;
do {
loop=rfbProcessEvents(res->server,res->server->deferUpdateTime);
} while(loop && res->result&return_mask==0);
} while(loop && (res->result&return_mask)==0);
if(res->result&return_mask!=0)
if((res->result&return_mask)!=0)
return res->result;
memcpy((char*)&fds,(const char*)&(res->server->allFds),sizeof(fd_set));
......@@ -321,14 +357,16 @@ result_t private_process(resource_t resource,timeout_t timeout_in_seconds,result
if(count>0) {
if(FD_ISSET(res->client->sock,&fds)) {
if(!HandleRFBServerMessage(res->client))
if(!HandleRFBServerMessage(res->client)) {
closevnc(resource);
return 0;
if(res->result&return_mask!=0)
}
if((res->result&return_mask)!=0)
return res->result;
}
} else {
res->result|=RESULT_TIMEOUT;
return RESULT_TIMEOUT;
return res->result;
}
} while(1);
......@@ -355,10 +393,81 @@ result_t waitforupdate(resource_t res,timeout_t timeout)
return private_process(res,timeout,RESULT_SCREEN|RESULT_TIMEOUT);
}
result_t visualgrep(resource_t res,const char* filename,timeout_t 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=0;
}
return result;
}
/* auxiliary function for alert */
#include "default8x16.h"
void center_text(rfbScreenInfo* screen,const char* message,int* x,int* y,int* w,int* h)
{
/* TODO: load filename and set res->grep_image to this image */
return private_process(res,timeout,RESULT_FOUNDIMAGE|RESULT_TIMEOUT);
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 */
......@@ -368,7 +477,7 @@ 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 w,h;
int x,y,w,h;
result_t result;
if(res->server==0)
......@@ -381,15 +490,17 @@ result_t alert(resource_t resource,const char* message,timeout_t timeout)
if(!fake_frame_buffer)
return -1;
memcpy(fake_frame_buffer,res->server->frameBuffer,w*4*h);
/* TODO: draw message */
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=private_process(resource,timeout,-1);
result=waitforinput(resource,timeout);
res->server->frameBuffer=backup;
/* TODO: rfbMarkRectAsModified() */
free(fake_frame_buffer);
rfbMarkRectAsModified(res->server,x,y,x+w,y+h);
return result;
}
......@@ -430,24 +541,28 @@ buttons_t getbuttons(resource_t res)
bool_t sendkey(resource_t res,keysym_t keysym,bool_t keydown)
{
private_resource_t* r=get_resource(res);
if(r==0)
return 0;
return SendKeyEvent(r->client,keysym,keydown);
}
bool_t sendmouse(resource_t res,coordinate_t x,coordinate_t y,buttons_t buttons)
{
private_resource_t* r=get_resource(res);
if(r==0)
return 0;
return SendPointerEvent(r->client,x,y,buttons);
}
/* for visual grepping */
coordinate_t getoriginx(resource_t res)
coordinate_t getxorigin(resource_t res)
{
private_resource_t* r=get_resource(res);
return r->x_origin;
}
coordinate_t getoriginy(resource_t res)
coordinate_t getyorigin(resource_t res)
{
private_resource_t* r=get_resource(res);
return r->y_origin;
......
......@@ -12,7 +12,7 @@
typedef int bool_t;
/* a keysym: identical with ASCII for values between 0-127 */
typedef unsigned char keysym_t;
typedef int keysym_t;
/* this can be negative, because of a new origin set via visual grep */
typedef int coordinate_t;
......@@ -27,31 +27,31 @@ typedef int resource_t;
typedef double timeout_t;
/* the return values of process() and friends */
typedef enum {
RESULT_TIMEOUT=1,
RESULT_KEY=2,
RESULT_MOUSE=4,
RESULT_SCREEN=8,
RESULT_FOUNDIMAGE=16
} result_t;
typedef int result_t;
/*
* %constant int RESULT_TIMEOUT=1;
%constant int RESULT_KEY=2;
%constant int RESULT_MOUSE=4;
%constant int RESULT_SCREEN=8;
%constant int RESULT_FOUNDIMAGE=16;
*/
%}
#endif // SWIG
typedef int bool_t;
typedef unsigned char keysym_t;
typedef int keysym_t;
typedef int coordinate_t;
typedef unsigned char buttons_t;
typedef int resource_t;
typedef double timeout_t;
typedef enum {
RESULT_TIMEOUT=1,
RESULT_KEY=2,
RESULT_MOUSE=4,
RESULT_SCREEN=8,
RESULT_FOUNDIMAGE=16
} result_t;
typedef int result_t;
#define RESULT_TIMEOUT 1
#define RESULT_KEY 2
#define RESULT_MOUSE 4
#define RESULT_SCREEN 8
#define RESULT_FOUNDIMAGE 16
/* init/shutdown */
......@@ -89,8 +89,8 @@ bool_t sendmouse(resource_t res,coordinate_t x,coordinate_t y,buttons_t buttons)
/* for visual grepping */
coordinate_t getoriginx(resource_t res);
coordinate_t getoriginy(resource_t res);
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);
......
......@@ -2,26 +2,124 @@
use nacro;
$vnc=nacro::initvnc("localhost",5900,5923);
# TODO: take options
print $vnc;
$output="my_script";
$server="localhost";
$port=5900;
$listen_port=5923;
# give it a chance to get a first screen update
# start connection
$vnc=nacro::initvnc($server,$port,$listen_port);
print nacro::waitforupdate($vnc,.4);
if($vnc<0) {
print STDERR "Could not initialize $server:$port\n";
exit 1;
}
print STDERR "Now\n";
# TODO: timing
print nacro::sendmouse($vnc,90,250,0);
open OUT, ">$output.pl";
print OUT "#!/usr/bin/perl\n";
print OUT "\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";
print nacro::sendkey($vnc,ord('a'),-1);
print nacro::sendkey($vnc,ord('a'),0);
$mode="passthru";
$image_counter=1;
$magickey=0;
$x_origin=0; $y_origin=0;
print nacro::sendmouse($vnc,100,10,0);
while(1) {
$result=nacro::waitforinput($vnc,999999);
if($result==0) {
# server went away
close OUT;
exit 0;
}
print nacro::savepnm($vnc,"hallo.pnm",50,50,300,200);
nacro::process($vnc,3);
print"\n";
if($mode eq "passthru") {
if($result&$nacro::RESULT_KEY) {
$keysym=nacro::getkeysym($vnc);
$keydown=nacro::getkeydown($vnc);
if(nacro::sendkey($vnc,$keysym,$keydown)) {
print OUT "nacro::sendkey(\$vnc,$keysym,$keydown);\n";
}
if($keysym==0xffe3 || $keysym==0xffe4) {
# Control pressed
$magickey++;
if($magickey>3 && !$keydown) {
$magickey=0;
$mode="menu";
$dragging=0;
nacro::alert($vnc,"VisualNaCro: press 'q' to quit\nor mark reference rectangle by dragging",10);
}
} else {
$magickey=0;
}
}
if($result&$nacro::RESULT_MOUSE) {
$x=nacro::getx($vnc);
$y=nacro::gety($vnc);
$buttons=nacro::getbuttons($vnc);
if(nacro::sendmouse($vnc,$x,$y,$buttons)) {
$x-=$x_origin; $y-=$y_origin;
print OUT "nacro::sendmouse(\$vnc,\$x_origin"
. ($x>=0?"+":"")."$x,\$y_origin"
. ($y>=0?"+":"")."$y,$buttons);\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;
}
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(!$dragging && (($buttons&1)==1)) {
print STDERR "start draggin: $x $y\n";
$start_x=$x;
$start_y=$y;
$dragging=1;
} elsif($dragging && (($buttons&1)==0)) {
print STDERR "stop draggin: $x $y\n";
if($start_x==$x && $start_y==$y) {
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";
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment