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@ ...@@ -10,7 +10,7 @@ nacro_CFLAGS= @LIBVNCSERVERCFLAGS@
SWIGOPT= 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) all: $(LIBPREFIX)$(TARGET)$(SO)
...@@ -39,11 +39,11 @@ PERL5_CCFLAGS = @PERL5CCFLAGS@ ...@@ -39,11 +39,11 @@ PERL5_CCFLAGS = @PERL5CCFLAGS@
$(ISRCS): $(INTERFACE) $(ISRCS): $(INTERFACE)
$(SWIG) -perl5 $(SWIGOPT) $(INTERFACE) $(SWIG) -perl5 $(SWIGOPT) $(INTERFACE)
$(OBJS): $(SRCS) $(OBJS): $(SRCS) $(INTERFACE)
$(CC) -c -Dbool=char $(CCSHARED) $(CFLAGS) -o $@ $^ $(LIBVNCSERVERCFLAGS) $(INCLUDES) -I$(PERL5_INCLUDE) $(CC) -c -Dbool=char $(CCSHARED) $(CFLAGS) -o $@ $< $(LIBVNCSERVERCFLAGS) $(INCLUDES) -I$(PERL5_INCLUDE)
$(IOBJS): $(ISRCS) $(IOBJS): $(ISRCS) $(INTERFACE)
$(CC) -c -Dbool=char $(CCSHARED) $(CFLAGS) -o $@ $^ $(INCLUDES) $(PERL5_CCFLAGS) -I$(PERL5_INCLUDE) $(CC) -c -Dbool=char $(CCSHARED) $(CFLAGS) -o $@ $< $(INCLUDES) $(PERL5_CCFLAGS) -I$(PERL5_INCLUDE)
$(LIBPREFIX)$(TARGET)$(SO): $(OBJS) $(IOBJS) $(LIBPREFIX)$(TARGET)$(SO): $(OBJS) $(IOBJS)
$(LDSHARED) $(OBJS) $(IOBJS) $(PERL5_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO) $(LDSHARED) $(OBJS) $(IOBJS) $(PERL5_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
......
This diff is collapsed.
...@@ -110,16 +110,50 @@ rfbBool malloc_frame_buffer(rfbClient* cl) ...@@ -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) void got_frame_buffer(rfbClient* cl,int x,int y,int w,int h)
{ {
private_resource_t* res=(private_resource_t*)cl->clientData; private_resource_t* res=(private_resource_t*)cl->clientData;
assert(res->server); assert(res->server);
if(res->grep_image) { if(res->grep_image && do_visual_grep(res,x,y,w,h)) {
/* TODO: find image and set x_origin,y_origin if found */ res->result|=RESULT_FOUNDIMAGE;
} else {
res->state=RESULT_SCREEN;
} }
if(res->server) { if(res->server) {
rfbMarkRectAsModified(res->server,x,y,x+w,y+h); 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 ...@@ -180,7 +214,8 @@ bool_t savepnm(resource_t resource,const char* filename,int x1,int y1,int x2,int
uint32_t* buffer; uint32_t* buffer;
FILE* f; FILE* f;
assert(res->client); if(res==0 || res->client==0)
return 0;
assert(res->client->format.depth==24); assert(res->client->format.depth==24);
w=res->client->width; w=res->client->width;
...@@ -228,7 +263,7 @@ image_t* loadpnm(const char* filename) ...@@ -228,7 +263,7 @@ image_t* loadpnm(const char* filename)
} }
} while(buffer[0]=='#'); } 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)) { || !fgets(buffer,1024,f) || strcmp("255\n",buffer)) {
fclose(f); fclose(f);
return 0; return 0;
...@@ -246,7 +281,8 @@ image_t* loadpnm(const char* filename) ...@@ -246,7 +281,8 @@ image_t* loadpnm(const char* filename)
for(j=0;j<h;j++) for(j=0;j<h;j++)
for(i=0;i<w;i++) 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); fclose(f);
free(image->buffer); free(image->buffer);
free(image); free(image);
...@@ -291,9 +327,9 @@ result_t private_process(resource_t resource,timeout_t timeout_in_seconds,result ...@@ -291,9 +327,9 @@ result_t private_process(resource_t resource,timeout_t timeout_in_seconds,result
rfbBool loop; rfbBool loop;
do { do {
loop=rfbProcessEvents(res->server,res->server->deferUpdateTime); 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; return res->result;
memcpy((char*)&fds,(const char*)&(res->server->allFds),sizeof(fd_set)); 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 ...@@ -321,14 +357,16 @@ result_t private_process(resource_t resource,timeout_t timeout_in_seconds,result
if(count>0) { if(count>0) {
if(FD_ISSET(res->client->sock,&fds)) { if(FD_ISSET(res->client->sock,&fds)) {
if(!HandleRFBServerMessage(res->client)) if(!HandleRFBServerMessage(res->client)) {
closevnc(resource);
return 0; return 0;
if(res->result&return_mask!=0) }
if((res->result&return_mask)!=0)
return res->result; return res->result;
} }
} else { } else {
res->result|=RESULT_TIMEOUT; res->result|=RESULT_TIMEOUT;
return RESULT_TIMEOUT; return res->result;
} }
} while(1); } while(1);
...@@ -355,10 +393,81 @@ result_t waitforupdate(resource_t res,timeout_t timeout) ...@@ -355,10 +393,81 @@ result_t waitforupdate(resource_t res,timeout_t timeout)
return private_process(res,timeout,RESULT_SCREEN|RESULT_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)
{ {
/* TODO: load filename and set res->grep_image to this image */ private_resource_t* res=get_resource(resource);
return private_process(res,timeout,RESULT_FOUNDIMAGE|RESULT_TIMEOUT); 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)
{
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 */ /* 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) ...@@ -368,7 +477,7 @@ result_t alert(resource_t resource,const char* message,timeout_t timeout)
private_resource_t* res=get_resource(resource); private_resource_t* res=get_resource(resource);
char* fake_frame_buffer; char* fake_frame_buffer;
char* backup; char* backup;
int w,h; int x,y,w,h;
result_t result; result_t result;
if(res->server==0) if(res->server==0)
...@@ -381,15 +490,17 @@ result_t alert(resource_t resource,const char* message,timeout_t timeout) ...@@ -381,15 +490,17 @@ result_t alert(resource_t resource,const char* message,timeout_t timeout)
if(!fake_frame_buffer) if(!fake_frame_buffer)
return -1; return -1;
memcpy(fake_frame_buffer,res->server->frameBuffer,w*4*h); memcpy(fake_frame_buffer,res->server->frameBuffer,w*4*h);
/* TODO: draw message */
backup=res->server->frameBuffer; backup=res->server->frameBuffer;
res->server->frameBuffer=fake_frame_buffer; res->server->frameBuffer=fake_frame_buffer;
center_text(res->server,message,&x,&y,&w,&h);
fprintf(stderr,"%s\n",message);
result=waitforinput(resource,timeout);
result=private_process(resource,timeout,-1);
res->server->frameBuffer=backup; res->server->frameBuffer=backup;
/* TODO: rfbMarkRectAsModified() */ free(fake_frame_buffer);
rfbMarkRectAsModified(res->server,x,y,x+w,y+h);
return result; return result;
} }
...@@ -430,24 +541,28 @@ buttons_t getbuttons(resource_t res) ...@@ -430,24 +541,28 @@ buttons_t getbuttons(resource_t res)
bool_t sendkey(resource_t res,keysym_t keysym,bool_t keydown) bool_t sendkey(resource_t res,keysym_t keysym,bool_t keydown)
{ {
private_resource_t* r=get_resource(res); private_resource_t* r=get_resource(res);
if(r==0)
return 0;
return SendKeyEvent(r->client,keysym,keydown); return SendKeyEvent(r->client,keysym,keydown);
} }
bool_t sendmouse(resource_t res,coordinate_t x,coordinate_t y,buttons_t buttons) bool_t sendmouse(resource_t res,coordinate_t x,coordinate_t y,buttons_t buttons)
{ {
private_resource_t* r=get_resource(res); private_resource_t* r=get_resource(res);
if(r==0)
return 0;
return SendPointerEvent(r->client,x,y,buttons); return SendPointerEvent(r->client,x,y,buttons);
} }
/* for visual grepping */ /* for visual grepping */
coordinate_t getoriginx(resource_t res) coordinate_t getxorigin(resource_t res)
{ {
private_resource_t* r=get_resource(res); private_resource_t* r=get_resource(res);
return r->x_origin; return r->x_origin;
} }
coordinate_t getoriginy(resource_t res) coordinate_t getyorigin(resource_t res)
{ {
private_resource_t* r=get_resource(res); private_resource_t* r=get_resource(res);
return r->y_origin; return r->y_origin;
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
typedef int bool_t; typedef int bool_t;
/* a keysym: identical with ASCII for values between 0-127 */ /* 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 */ /* this can be negative, because of a new origin set via visual grep */
typedef int coordinate_t; typedef int coordinate_t;
...@@ -27,31 +27,31 @@ typedef int resource_t; ...@@ -27,31 +27,31 @@ typedef int resource_t;
typedef double timeout_t; typedef double timeout_t;
/* the return values of process() and friends */ /* the return values of process() and friends */
typedef enum { typedef int result_t;
RESULT_TIMEOUT=1, /*
RESULT_KEY=2, * %constant int RESULT_TIMEOUT=1;
RESULT_MOUSE=4, %constant int RESULT_KEY=2;
RESULT_SCREEN=8, %constant int RESULT_MOUSE=4;
RESULT_FOUNDIMAGE=16 %constant int RESULT_SCREEN=8;
} result_t; %constant int RESULT_FOUNDIMAGE=16;
*/
%} %}
#endif // SWIG #endif // SWIG
typedef int bool_t; typedef int bool_t;
typedef unsigned char keysym_t; typedef int keysym_t;
typedef int coordinate_t; typedef int coordinate_t;
typedef unsigned char buttons_t; typedef unsigned char buttons_t;
typedef int resource_t; typedef int resource_t;
typedef double timeout_t; typedef double timeout_t;
typedef enum { typedef int result_t;
RESULT_TIMEOUT=1, #define RESULT_TIMEOUT 1
RESULT_KEY=2, #define RESULT_KEY 2
RESULT_MOUSE=4, #define RESULT_MOUSE 4
RESULT_SCREEN=8, #define RESULT_SCREEN 8
RESULT_FOUNDIMAGE=16 #define RESULT_FOUNDIMAGE 16
} result_t;
/* init/shutdown */ /* init/shutdown */
...@@ -89,8 +89,8 @@ bool_t sendmouse(resource_t res,coordinate_t x,coordinate_t y,buttons_t buttons) ...@@ -89,8 +89,8 @@ bool_t sendmouse(resource_t res,coordinate_t x,coordinate_t y,buttons_t buttons)
/* for visual grepping */ /* for visual grepping */
coordinate_t getoriginx(resource_t res); coordinate_t getxorigin(resource_t res);
coordinate_t getoriginy(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); 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 @@ ...@@ -2,26 +2,124 @@
use nacro; 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); $mode="passthru";
print nacro::sendkey($vnc,ord('a'),0); $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); if($mode eq "passthru") {
if($result&$nacro::RESULT_KEY) {
nacro::process($vnc,3); $keysym=nacro::getkeysym($vnc);
$keydown=nacro::getkeydown($vnc);
print"\n"; 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