Why and how to use AsxV AsxV is an adapter class which enables the program xv by John Bradley to act as a frontend client for displaying images. Using AsxV is faster than forking xv and avoids the high frequency of XMapWindow() calls which make annoying a memory leak of the combination fvwm2 and X on SuSE 7.2. (SuSE 6.4 was healthier in that aspect.) The client feature is triggered by a new option of xv : -asxv subscription hostname portnumber username where subscription may be "current_file" or "double_files". "current_file" will try to display images at the upper left corner of the screen while "double_files" will position to the upper right corner. Within simv, the portnumber of the -tcp_service can be read from variable $@. If username is empty or "-" then the connection is unencrypted. Any other user name causes encryption according to sagent helptext : "Appendix agent C : Authentication and Encryption". So the start of a AsxV viewer from within simv might look like : simv \ ... other options ... \ -tcp_service: \ -internal:current_file:off \ -shell:'xv.simv -geometry +0+0 -asxv current_file localhost $@ thomas' -internal:double_files:off \ -shell:'xv.simv -geometry -0+0 -asxv double_files localhost $@ thomas' When connected, xv does not end on hitting key 'q' in one of its windows. It rather tries to become most invisible and waits for new image notifications. On the other hand a connected xv ends automatically when the connection ends. The 'Quit' button in the dialog window of xv does end the program even if it is connected. I also added key 'Q' which has the same effect as 'q'. (Just a "boss key" :) The default behavior of the connected viewer tries to be very like the behavior of forked xv childs. This may be modified by another new option : -asxv_opt command_list The command list consist of one or more statements which are separated by comma. Valid statements are : lazy_refresh=on do only display a new image if no further notifications of the server are pending. Also interrupt loading an image when a new message is detected. (This is the default) lazy_refresh=off display any incomming image notification. That may cause the viewer to flip around like it does if it gets interactive commands faster than they can be processed. hide_on_empty=on make the image window most invisible (but do no XUnmapWindow()) when the image is canceled by the server. (This is the default) hide_on_empty=off keep the last image until it is replaced by a new one. This saves computing power and makes a calmer screen but also gives less information over the state of the server. raise_window=on raise the image window whenever a new image is displayed. (This is the default) raise_window=off do not raise the image window automatically. lower_window=on lower the window when when the image is canceled by the server. This option has no effect if hide_on_empty=on . lower_window=off do not lower the image window automatically. (This is the default.) This option has no effect if hide_on_empty=on . auto_jpgb=on if xv is not able to display an image file, issue a -jpgb command to the server in order to try a conversion to readable JPEG. (This is the default) auto_jpgb=off handle an undisplayable image as if it was canceled. standalone=on pop up windows for error messages and warnings like the original xv. Not very suited for being frontend of simv. standalone=off print error messages and warnings to stderr. (This is the default) Example of usage: -asxv_opt hide_on_empty=off,raise_window=off How to make the modified xv Within the stic_build directory compile the adapter class AsxV : make asxv.o Due to the licensing policy of xv, i cannot provide a modified package but only information about the modifications i made. I don't like that license but i'm thankful to John Bradley for his work and therefore i do respect it strictly. With an existing, configured and already successfully compiled source installation of xv-3.10a (from http://www.trilon.com/xv), i had to make the the changes described below, afterwards executed the command : make and copied the resulting binary xv at its appropriate place. (on my box it is called : /usr/local/bin/xv.simv ) Changes i made in xv-3.10a (this also contains changes equivalent to the ones described in doc/xv_changes. See above: standalone=on/off ) When changing the Makefile the address "/u/thomas/stic_dir/src/stic_build" needs to be replaced by the stic_build directory of your stic installation. The changes are also documented in file src/misc/xv.diff which needs the same replacement and then may be used for a run of program "patch". new ================================================= Makefile 17c17,18 < CCOPTS = -O --- > # CCOPTS = -O > CCOPTS = -g 192a194,196 > # IMPORTANT: EXCHANGE THIS BY THE ADDRESS OF YOUR STIC_BUILD DIRECTORY > s=/u/thomas/stic_dir/src/stic_build > 199c203,206 < xvxwd.o xvfits.o --- > xvxwd.o xvfits.o \ > $s/asxv.o $s/asfrontend.o $s/asvmsg.o \ > $s/sregex.o $s/sfile.o $s/stcp.o $s/stunnel.o \ > $s/sblowfish.o $s/sconn.o $s/saccess.o $s/smem.o ================================================= xv.h 1681a1682,1690 > > /* global AsxV */ > #ifdef MAIN > struct AsxV *asxv= NULL; > #else > extern struct AsxV *asxv; > #endif > #define AsXv_LINES_PER_CHECK 100 > ================================================= xv.c 98d97 < static int openPic PARM((int)); 112d110 < static void deleteFromList PARM((int)); 115a114,117 > /* AsxV : formerly static */ > void deleteFromList PARM((int)); > int openPic PARM((int)); > 298a301,303 > /* AsxV initialization */ > Asxv_new(&asxv,0); > 825a831,833 > > Asxv_destroy(&asxv,0); > 1186a1195,1202 > else if (strcmp(argv[i],"-asxv")==0 && i+4 Asxv_define_service(asxv,argv+i+1,0); > i+= 4; > } else if (strcmp(argv[i],"-asxv_opt")==0 && i+1 Asxv_modify_settings(asxv,argv[i+1],0); > i+= 1; > } > 1333,1334d1348 < < 1337a1352,1353 > if(!not_in_first_half) continue; /* an option was already recognized */ > 1706c1722 < static int openPic(filenum) --- > int openPic(filenum) 2053d2068 < 2057a2073,2075 > if(Asxv_has_data(asxv,1)) /* new message ahead , old pic is invalid now */ > goto FAILED; > 2131a2150,2151 > if(Asxv_has_data(asxv,1)) /* new message ahead , old pic is invalid now */ > goto FAILED; 3128a3149,3152 > if(!Asxv_is_connected(asxv,0)) > if(Asxv_connect(asxv,0)<=0) > Quit(0); > 3657c3681 < static void deleteFromList(delnum) --- > void deleteFromList(delnum) ================================================= xvevent.c 76d75 < 110a110,111 > if(Asxv_act(asxv,&waiting,0)<0) > return(QUIT); 114c115,116 < if ((waitsec==-1 && !polling && !HaveSelection()) || XPending(theDisp)>0) { --- > if ((waitsec==-1 && !polling && !HaveSelection() && > !Asxv_is_connected(asxv,0)) || XPending(theDisp)>0) { 1611c1613,1618 < case 'q': FakeButtonPress(&but[BQUIT]); break; --- > case 'q': case 'Q' : > if(Asxv_is_connected(asxv,0)) > Asxv_hide(asxv,0); > else > FakeButtonPress(&but[BQUIT]); > break; ================================================= xvimage.c 1931a1932,1935 > if((i % AsXv_LINES_PER_CHECK) == 0) > if(Asxv_has_data(asxv,0)) /* new message ahead, old pic invalid */ > return(xim); > ================================================= xvinfo.c 14a15,16 > #include > 24d25 < 267,269c268,291 < OpenAlert(istrs[stnum]); < sleep(3); < CloseAlert(); --- > > if(Asxv_is_standalone(asxv,0)) { > > OpenAlert(istrs[stnum]); > sleep(3); > CloseAlert(); > > } else { > struct stat stbuf; > char *home,adr[4096]; > > home= getenv("HOME"); > if(home!=NULL) { > sprintf(adr,"%s/%s",home,".xv.gefummelt.beep"); > if(stat(adr,&stbuf)!=-1) > fprintf(stderr, "\007"); > } > fprintf(stderr, > "\n************************************************************\n"); > fprintf(stderr,"xv notice : %s\n",istrs[stnum]); > fprintf(stderr, > "************************************************************\n\n"); > } > ================================================= xvjpeg.c 424c424,425 < SetISTR(ISTR_WARNING, "%s: %s", fbasename, buffer); /* send it to XV */ --- > if(strcmp(buffer,"Application transferred too few scanlines")!=0) > SetISTR(ISTR_WARNING, "%s: %s", fbasename, buffer); /* send it to XV */ 600a602 > AsXvFailed:; 611a614,620 > > if((cinfo.output_scanline % AsXv_LINES_PER_CHECK) == 0) > if(Asxv_has_data(asxv,0)){/* new message ahead, old pic is invalid now */ > jpeg_finish_decompress(&cinfo); > goto AsXvFailed; > } > ================================================= xvmisc.c 475,477c475,488 < OpenAlert(st); < sleep(3); < CloseAlert(); --- > > if(Asxv_is_standalone(asxv,0)) { > > OpenAlert(st); > sleep(3); > CloseAlert(); > > } else { > fprintf(stderr, > "\n************************************************************\n"); > fprintf(stderr,"xv notice : %s\n",st); > fprintf(stderr, > "************************************************************\n\n"); > } ================================================= xvpopup.c 320c320,329 < PopUp(txt, &label, 1); --- > if(Asxv_is_standalone(asxv,0)) { > PopUp(txt, &label, 1); > } else { > fprintf(stderr, > "\n************************************************************\n"); > fprintf(stderr,"xv error :\n%s\n",txt); > fprintf(stderr,"button text : %s\n",label); > fprintf(stderr, > "************************************************************\n\n"); > } ================================================= xvtext.c 299a300,302 > if(tv->vis==2) > XRaiseWindow(theDisp, tv->win); > else 1564a1568,1571 > int AsXv_LowerTextWindows(flag) > int flag; > { > int i; 1566c1573,1580 < --- > for (i=0; i if (tinfo[i].vis) { > XLowerWindow(theDisp, tinfo[i].win); > tinfo[i].vis= 2; > } > } > } >