bradley@halibut.cis.upenn.edu (John Bradley) (11/28/90)
Submitted-by: bradley@halibut.cis.upenn.edu (John Bradley) Posting-number: Volume 10, Issue 88 Archive-name: xv/part10 #!/bin/sh # to extract, remove the header and type "sh filename" if `test ! -s ./README` then echo "writting ./README" cat > ./README << '\BARFOO\' Installation ------------ If you don't plan to use Imake, copy 'Makefile.std' (a regular old-style minimalist makefile, not one created by Imake) to 'Makefile'. Check the Makefile for the configuration option(s). There are unfortunately quite a few these days, to support a number of different machines. The program builds just fine on Suns running SunOS 4.0, VAXes running Ultrix, and DECstations running UWS, without any options whatsoever. If you're on a SYSV-based machine, you'll probably need '-DSYSV' and '-DDIRENT'. Read the file for more specific info. Otherwise, check the Imakefile, and make the program however you normally would. Be sure to 'make depend' before building the program. Caveats ------- XV has been developed on a Sun4/280 running SunOS 4.0, using both the normal 'cc' and gcc-1.37 compilers. There shouldn't be anything grotesque enough in the code to break any other compilers. The viewing environment has mainly been an IBM RT with an 8-bit color display. The window managers of choice have been TWM (recently) and UWM (in the past). It has been compiled and tested on the following systems: Sun 4 running SunOS 4.0, VAXstation 3500 running Ultrix 3.0, MicroVax II running Ultrix 2.0, DecStation 3100 running UWS 2.0, IBM RISC System/6000 running AIX 3.0. It has displayed on the following systems: IBM RT (8-bit color), Sun 3 (1-bit B/W), Sun 3 (8-bit grayscale), Sun 4 (1-bit B/W), MicroVax II (8-bit color), MicroVax II (4-bit grayscale), a variety of HPs (4-bit color, 6-bit color, 8-bit color, and 24-bit color), and Visual, NCD, Tektronix, and HDS X terminals (1-bit B/W abd 8-bit color). Provided you don't have some odd-ball 5-bit StaticColor display, it should work for you. 'vsprintf.c' has been included for the benefit of those on machines that don't have it. (IBM RT AOS 4.3 and BSD 4.3 on VAX) Bizarrities ----------- There are problems with using XV under 'dxwm', DEC's window manager. You'll have to specify '-dxwm' to enable a couple of kludges, and even then XV is unable to MOVE its window AT ALL. (This was with dxwm controlling my X11R4 IBM RT display. Your mileage (dxwm controlling a DEC server, ferinstance) may vary. XV would appear to exercise a pair of bugs in TWM, the version from the X11R4 tape. Perhaps they've been fixed by now. Colormap Installation: under twm, if you have multiple XVs running, and each has their own colormap, sometimes the colormap doesn't get properly installed if you move the mouse directly from one XV to the other, quickly, so that it doesn't see the mouse go into the root window, or any other window. If you move the mouse outside the window and move it back in, it SHOULD install the colormap correctly. Colormap Installation: Note, if an alternate colormap is installed, it will ONLY be installed when the mouse is inside the IMAGE window. It will not be installed when the mouse is in any other XV windows. This is because I can't guarantee that the other windows will still have contrasting foreground/background colors when the alternate colormap is installed. It is assumed that if you put the mouse in a window, you will want to use that window, so you'd better be able to READ that window... There's a bug in my version of TWM that creeps up if you have titlebars turned off. Essentially, XV tells the window manager to make the window a certain size. TWM (wrongly) adds enough room at the top to put its title bar there, but doesn't draw it, since titlebars are turned off. XV gets back a ConfigureNotify event on the window with the new size, which is large by 20-odd pixels in height. There's no way to detect this behavior that I know of. Workaround: wait for a fixed version of TWM, until then, run (at least XV) with titlebars on. Modifying XV ------------ ADDING A NEW FILE FORMAT TO XV This category is split up into two sections, reading a new file format, and writing a new file format, because it's perfectly conceivable that you'd want to do one but not the other. In some cases, it's even possible that you could only (realistically, read "easily") do one or the other. (Example: you want to be able to write an Encapsulated PostScript image, but you'd never be able to read PostScript files without writing a complete postscript interpreter, something that's thankfully outside the context of this program.) Alternately, you might also want to be able to directly display the output of some Mutant Ray Tracer (or whatever) without going through a conversion program, yet you'd NEVER want to create more Mutant-Ray-Tracer-format pictures with xv... Whatever. The following instructions are being written as I add PBM/PGM/PPM capability to the program, so A) it's likely to be fairly accurate, and B) for example purposes, I'll be talking about the PBM/PGM/PPM code specifically. READING A NEW FILE FORMAT ------- NOTE: Despite the wide variety of displays and file formats XV deals with, internally it only manipulates 8-bit colormapped images. If you're loading an 8-bit colormapped image, such as a GIF image, no prob. If you're loading an 8-or-less-bits format that doesn't have a colormap (such as an 8-bit greyscale image, or a 1-bit B/W bitmap) your Load() routine will have to generate an appropriate colormap. And if you're loading up a 24 bit RGB file, you'll have to compress it down to 8 bits by calling Conf24to8()... ------- Make a copy of xvpm.c, calling it something appropriate. I'm adding PBM capabilities, so I think xvpbm.c is a fine file name. Edit the Makefile so that your new module will be compiled. Add 'xvpbm.o' (or whatever) Edit the new module. You'll need to #include "xv.h", of course. The module should have one externally callable function that does the work of loading up the file. The function is called with two arguments, a filename and the number of colors available on this display, like so: /*******************************************/ int LoadPBM(fname,nc) char *fname; int nc; /*******************************************/ The file name will be the complete file name (absolute, not relative to any directory). Note: if xv is reading from <stdin>, don't worry about it. stdin is automatically copied to a /tmp/xv****** file to make life considerably simpler (and some times possible at all) The number of colors argument is going to be (2 << # of bit planes) (or 'ncols' if specified on the command line). Either way, this only comes into play if you have to do a 24-to-8 bit conversion. More on that later. The function returns '0' on success, non-zero on failure. The function is expected to load up the following global variables: byte *pic; this is a wide*high array of bytes, one byte per pixel, starting at the top-left corner, and proceeding in scan-line order. There is no padding of any sort at the end of a scan line. The code is expected to malloc() the memory for this image. int pWIDE, pHIGH; these variables specify the size of the image that has been loaded, in pixels. byte r[256], g[256], b[256]; the desired colormap. As specified above, 'pic' is an 8-bits per pixel image. A given pixel value in pic maps to an RGB color through these arrays. In each array, a value of 0 means 'off', and a value of 255 means 'fully on'. Note: the arrays do not have to be completely set. Only RGB entries for pixels that actually exist in the 'pic' need to be set. For example, if the pic is known to be a B/W bitmap with pixel values of 0 and 1, you'd only have to set {r,g,b}[0] and {r,g,b}[1]. The function should also call 'SetISTR(ISTR_FORMAT, fmt, args)' to set the "Format:" string in the Info box. It should call the function as soon as possible (ie, once it knows the format of the picture, but before it's tried to load/parse all of the image data...) Diagnostics: Non-fatal errors in your Load() routine should be handled by calling SetISTR(ISTR_WARNING, fmt, args...). This will print the string in the info box and in the ctrl box. Non-fatal errors would be things like 'can't open file'... Fatal errors should be handled by calling 'FatalError(error_string)'. This function prints the string to stderr, and exits the program with an error code. The classic fatal error is 'unable to malloc...'. Handling 24-bit RGB pictures: If (as in the case of PPM files) you're file format has 24 bits of information per pixel, you'll have to get it down to 8 bits and a colormap for XV to make any use of it. A function 'Conv25to8(pic24, w, h, nc)' is provided, so don't worry about it. To use it, you'll have to load your picture into a WIDE*HIGH*3 array of bytes. (You'll be expected to malloc() this array.) This array begins at the top left corner, and proceeds in scan-line order. The first byte of the array is the red component of pixel0, followed by the green component of pixel0, followed by the blue component of pixel0, followed by the red component of pixel1, etc... There is no padding of any kind. Once you've got this image built, call 'Conv24to8()' with a pointer to the 24bit image, the width and height of the image, and the number of colors to 'shoot for' in the resulting 8-bit picture. This is the same parameter that was passed to your Load() routine, so just pass it along. If successful, Conv24to8() will return '0'. It will have generated 'pic', and filled in values in all the global variables that your Load() routine is expected to set. You should now free() the memory associated with the 24-bit version of your image and leave your Load() function. Read the source in xvpbm.c for further info on writing the Load() routine. ---------- Once you have a working Load() routine, you'll want to do some other crap... Edit xv.h and add two function prototypes for any global functions you've written (presumably just LoadPBM() (in this case)). You'll need to add a full function prototype (with parameter types) in the #ifdef __STDC__ section (near the bottom), and a function reference (just the return type) in the #else /* non-ANSI */ section at the bottom. Edit xv.c: *** Add a filetype #define near the top. Find the section: > /* file types that can be read */ > #define UNKNOWN 0 > #define GIF 1 > #define PM 2 And add one more to the list, in this case: "#define PBM 3" Note: I only added one filetype to this list, despite the fact that I'm really adding three (or six, really) different file formats to the program. This is because all of these file formats are related, and are handled by the same Load...() function. *** now tell the openPic() routine about your Load...() routine find the following (in openPic()): > filetype = UNKNOWN; > if (strncmp(magicno,"GIF87",5)==0) filetype = GIF; > else if (strncmp(magicno,"VIEW",4)==0 || > strncmp(magicno,"WEIV",4)==0) filetype = PM; Add another 'else' case that will set filetype if it's your format: > else if (magicno[0] == 'P' && magicno[1]>='1' && > magicno[1]<='6') filetype = PBM; And add another case to the switch statement (a few lines further down) > switch (filetype) { > case GIF: i = LoadGIF(filename); break; > case PM: i = LoadPM(filename,ncols); break; > } add: > case PBM: i = LoadPBM(filename,ncols); break; That should do it. Consult the file xvpm.c or xvpbm.c for further information. Remember: do as I mean, not as I say. ----------------------------------------------------------------------------- WRITING A NEW FILE FORMAT ------- NOTE: Despite the wide variety of displays and file formats XV deals with, internally it only manipulates 8-bit colormapped images. As a result, writing out 24bit RGB images is a horrible waste, and is to be avoided if your file format can handle colortable images... ------- If you haven't already done so (if/when you created the Load...() function): Make a copy of xvpm.c, calling it something appropriate. I'm adding PBM capabilities, so I think xvpbm.c is a fine file name. Edit the Makefile so that your new module will be compiled. Add 'xvpbm.o' (or whatever) Edit the new module. You'll need to #include "xv.h", of course. The module should have one externally callable function that does the work of writing the file. The function is called with a vitual plethora of arguments. At a minimum, you'll be given a FILE * to an already open-for-writing stream, a pointer to an 8-bits per pixel image, the width and height of that image, pointers to 256-entry red, green, and blue colormaps, the number of colors actually used in the colormaps, and the 'color style' from the 'Save' dialog box. You may pass more parameters, since you're going to be adding the call to this function later on. For example, in my PBM code, I pass one more parameter, 'raw' (whether to save the file as RAW or ASCII) to handle two very similar formats. (Rather than haveing WritePBMRaw() and WritePBMAscii()...) Your function definition should look something like this: /*******************************************/ int WritePBM(fp,pic,w,h,rmap,gmap,bmap,numcols,colorstyle,raw) FILE *fp; byte *pic; int w,h; byte *rmap, *gmap, *bmap; int numcols, colorstyle, raw; /*******************************************/ Write the function as you deem appropriate. Some Notes: * your function should return '0' if successful, non-zero if not * don't close 'fp' * pic is a w*h byte array, starting at top-left, and proceeding in normal scan-line order * colorstyle can (currently) take on three values: 0=FULL COLOR. This could mean either 24-bit RGB, or an 8-bit colormap or any other color format. r[pix],g[pix],b[pix] specifies the color of pixel 'pix'. 1=GREYSCALE, preferably 8 bits. Two caveats: you MUST use the colormap to determine what grey value to write. For all you know, pixel value '0' in pic could map to white, '1' could map to black, and '2' could map to a half-intensity grey. The other note: unless the original picture was a greyscale, (which SHOULDN'T be tested for), the colormap is going to have actual colors in it. You'll want to map RGB colors into greyscale values using 'the standard formula' (roughly .33R + .5G +.17B). The following code shows how to quickly write a raw greyscale image: if (colorstyle == 1) { /* GreyScale: 8 bits per pixel */ byte rgb[256]; for (i=0; i<numcols; i++) rgb[i] = MONO(rmap[i],gmap[i],bmap[i]); for (i=0, p=pic; i<w*h; i++, p++) putc(rgb[*p],fp); } 2=B/W STIPPLE: The stippling algorithm will have already been preformed by the time your function is called. 'pic' will be an image consisting of the pixel values '1' and '0'. (pic will STILL be organized the same way (ie, one byte per pixel)) 1 = WHITE, 0 = BLACK * for FULL COLOR or GREYSCALE images, you will be guaranteed that all pixel values in pic are in the range [0 - numcols-1] (inclusive). That done, edit 'xv.h' and add a pair of function declarations for your new function. (one full ANSI-style prototype, and one that just declares the return type). (Copy the declarations for 'WritePM()'.) Edit 'xvdir.c'. This is the module that controls the 'Save' dialog box. Add another 'format' type to the 'formatRB' button list: In the function 'CreateDirW()', find the block that (starts like): > formatRB = RBCreate(NULL, dirW, 26, y, "GIF", infofg, infobg); > RBCreate(formatRB, dirW, 26, y+18, "PM", infofg, infobg); copy the last 'RBCreate' call in the list, add '18' to the 'y+**' argument, and stick in an appropriate format type name. In this case, I'm adding two formats (PBM raw and PBM ascii) so I'll add these two lines: > RBCreate(formatRB, dirW, 26, y+36, "PBM/PGM/PPM raw", infofg, infobg); > RBCreate(formatRB, dirW, 26, y+54, "PBM/PGM/PPM ascii", infofg, infobg); Depending how many formats you've added, you may have to move the 'Normal Size' & 'At Current Expansion' buttons down. Right above the RBCreate calls that have that string in them is a 'y = y + **' assignment. Add 18 to the constant for each 'format' line that you added above. In the function DoSave(), find the following block: > i = RBWhich(formatRB); > switch (i) { > case 0: rv = WriteGIF(fp,thepic,w, h, r, g, b,numcols,RBWhich(colorRB)); > break; > case 1: rv = WritePM (fp,thepic,w, h, r, g, b,numcols,RBWhich(colorRB)); > break; > } and add cases for your function(s), like so: > case 2: rv = WritePBM(fp,thepic,w, h, r, g, b,numcols,RBWhich(colorRB),1); > break; > case 3: rv = WritePBM(fp,thepic,w, h, r, g, b,numcols,RBWhich(colorRB),0); > break; \BARFOO\ else echo "will not over write ./README" fi if `test ! -s ./PATCHLEVEL` then echo "writting ./PATCHLEVEL" cat > ./PATCHLEVEL << '\BARFOO\' Current patchlevel: 2 Rev: 10/9/90 (patchlevel 0 - initial release) Rev: 10/17/90 (patchlevel 1) ------------------------------ Imakefile added (David Elliot (dce@smsc.sony.com)) System V release 4 mods (David Elliot (dce@smsc.sony.com)) Bug in 'quick check' fixed (Arthur Olson (ado@elsie.nci.nih.gov)) Mods for Convex machines (Anthony Datri (datri@convex.com)) 'vprintf' module added (Jonathan Kamens (jik@pit-manager.mit.edu)) window creation bug fixed added icon fixed 'Input Focus' probs added '-w' flag to bggen various cleanups to shut up 'noisy' compilers Rev: 11/26/90 (patchlevel 2) ----------------------------- added workaround for 'X Protocol Errors' on broken servers (XFreeColors()) (see the '-bfc' option) fixed core dump when cropping on certain displays misc. #ifdefs for HPs fixed problem with fish cursor remaining around too long more SVR4 #ifdefs (David Elliott, dce@smsc.sony.com) fixed bug in tracking pixel values (Bob Finch, bob@gli.com) misc #ifdefs for ISC 386/ix 2.0.2 (Mark Snitily mark@zok.uucp) misc #ifdefs for AT&T machines (Eric Raymond eric@snark.thyrsus.com) misc #ifdefs for Silicon Graphics (Paul Close pdc@lunch.wpd.sgi.com) Added POSIX signal handling (Mike Patnode (mikep@sco.com)) Port to SCO UNIX/ODT (Mike Patnode (mikep@sco.com)) fixed problem with using '-max' and '-fixed' at same time (Greg Spencer greg@longs.lance.colostate.edu) modification to work with Virtual Root Windows (ala swm and tvtwm) (Bill Kucharski kucharsk@solbourne.com) the 'save-as' filename is now set to the 'current' filename Also, if you double click on 'plain' files in the directory box, it will set the 'save-as' filename accordingly. Added ability to view images centered on the root window, without any tiling. Added associated options ('-center', '-rfg', '-rbg', and '-rpat') Workaround for twm 'No title bars' bug (Steve Swales steve@bat.lle.rochester.edu) Bidirectional Rotate commands added Maxpect command added: (Maximum size, but preserve aspect ratio) AutoCrop command added: (Crops out solid borders.) Potential support for 32-bit displays. (Hasn't been tested. Don't have one.) \BARFOO\ else echo "will not over write ./PATCHLEVEL" fi if `test ! -s ./Makefile` then echo "writting ./Makefile" cat > ./Makefile << '\BARFOO\' # Makefile for xv # # your C compiler of choice CC = cc ################ CONFIGURATION OPTIONS ################# # if you are running on a SysV-based machine, such as HP, Silicon Graphics, # etc, uncomment the following line to get you most of the way there. # #UNIX = -DSVR4 # If you are running on a POSIX-compatible machine, such as an # IBM RS6000, you MAY need to uncomment the 'NEED_DIRENT' line. # To determine if such is the case, do a 'man readdir' on your machine. If # readdir() returns a pointer to 'struct direct', you will not have # to change anything. If, however, readdir() returns a pointer to # 'struct dirent', you will have to add the '-DDIRENT' to CFLAGS # #NEED_DIRENT = -DDIRENT # If, when 'Applying' colors, or when loading new pictures, you get an # X Protocol Error on the XFreeColors() call, your X Server is Wrong. # Several workarounds: You can specify '-bfc' on the command line, or # set the 'xv.brokeFreeCols' resource to 'true'. Alternately, you can # uncomment the BROKECOLS line below to compile in the workarounds # permanently. If you do this, '-bfc' will toggle OFF the workarounds. # Noteworthy Offenders: AIX 3.1 on IBM 6000, and OLW on Suns # #BROKECOLS = -DBROKEFREECOLS # IF YOUR MACHINE DOESN'T HAVE 'vprintf()' OR 'vsprintf()' # # Vax BSD and IBM AOS don't have vprintf or vsprintf. # Note that our local library versions of sprintf have been updated # to return int, the number of characters in the formatted string, # whereas the versions in stock 4.3BSD do not so return. You may # have to remove the "-DINTSPRINTF" below if you're compiling for # stock 4.3BSD or for some other Vax or RT library package where # sprintf returns char *. # # Also, I define NOVOID on the Vax because I'm using pcc to compile. # If you use gcc or some other better compiler, this should not be # necessary. I define NOSTDHDRS on the RT because we don't have # standard ANSI header files installed for the RT, even though the RT # compiler claims to be ANSI-compliant. # # (for BSD 4.3 VAX, uncomment the following line) #VPRINTF = -DNEED_VPRINTF -DINTSPRINTF -DLONGINT -DNOVOID # (for (stock) IBM RT AOS 4.3, uncomment the following line) #VPRINTF = -DNEED_VPRINTF -DLONGINT -DNOSTDHDRS # If your machine does not have the 'setitimer()' call, but does # have the 'usleep()' call, uncomment the following line: # #TIMERS = -DUSLEEP # # alternately, if your machine does not have EITHER the 'setitimer()' or # the 'usleep()' call, uncomment the following line: # #TIMERS = -DNOTIMER # If you are using an AT&T machine, uncomment the following line # If you have ptoblems compiling xv.c and xvdir.c because of the DIR # reference in dirent.h, append '-DATT' to the following line: # #ATT = -DSYSV -DDIRENT -DUSLEEP -DATT # For SCO and ODT machines, uncomment the following: # #SCO = -Dsco -DPOSIX -DNOTIMER # # Itimers will be in 3.2v3 (yeah!) but that won't be out in the public's # hands for a while. Hey, it's just the fish anyways. # # Also, you'll want to change LIBS to # # -lX11 -lm -lsocket -lmalloc -lc -lx # # -lx must be after -lc so you get the right directory routines. # CFLAGS = -O2 $(NEED_DIRENT) $(BROKECOLS) $(VPRINTF) $(TIMERS) $(ATT) $(SCO) \ $(UNIX) LIBS = -lX11 -lm BITMAPS = bitmaps/grasp bitmaps/penn bitmaps/down bitmaps/down1 \ bitmaps/up bitmaps/up1 bitmaps/scrlgray bitmaps/gray50 \ bitmaps/gray25 bitmaps/i_fifo bitmaps/i_chr bitmaps/i_dir \ bitmaps/i_blk bitmaps/i_lnk bitmaps/i_sock bitmaps/i_reg \ bitmaps/rb_off bitmaps/rb_on bitmaps/rb_off1 bitmaps/rb_on1 \ bitmaps/fc_left bitmaps/fc_leftm bitmaps/fc_mid bitmaps/fc_midm \ bitmaps/fc_right bitmaps/fc_rightm bitmaps/fc_left1 \ bitmaps/fc_left1m bitmaps/fc_right1 bitmaps/fc_right1m \ bitmaps/icon OBJS = xv.o xvmisc.o xv24to8.o xvgif.o xvpm.o xvinfo.o xvctrl.o xvscrl.o \ xvgifwr.o xvdir.o xvbutt.o xvpbm.o xvxbm.o xvgam.o xvfish.o \ vprintf.o MISC = README PATCHLEVEL .c.o: ; $(CC) -c $(CFLAGS) -o $@ $*.c all: xv bggen xv: $(OBJS) $(CC) $(CFLAGS) -o xv $(OBJS) $(LIBS) bggen: bggen.c $(CC) $(CFLAGS) -o bggen bggen.c clean: rm -f $(OBJS) tar: tar cf xv.tar Makefile* Imakefile *.c *.h bitmaps docs $(MISC) xv.3100: bitmaps.h cc -O3 *.c -o xv $(XLIB) $(OBJS): xv.h xv.o: bitmaps.h xvmisc.o: bitmaps.h xvinfo.o: bitmaps.h xvctrl.o: bitmaps.h xvscrl.o: bitmaps.h xvbutt.o: bitmaps.h bitmaps.h: $(BITMAPS) cat $(BITMAPS) > bitmaps.h \BARFOO\ else echo "will not over write ./Makefile" fi if `test ! -s ./Makefile.std` then echo "writting ./Makefile.std" cat > ./Makefile.std << '\BARFOO\' # Makefile for xv # # your C compiler of choice CC = cc ################ CONFIGURATION OPTIONS ################# # if you are running on a SysV-based machine, such as HP, Silicon Graphics, # etc, uncomment the following line to get you most of the way there. # #UNIX = -DSVR4 # If you are running on a POSIX-compatible machine, such as an # IBM RS6000, you MAY need to uncomment the 'NEED_DIRENT' line. # To determine if such is the case, do a 'man readdir' on your machine. If # readdir() returns a pointer to 'struct direct', you will not have # to change anything. If, however, readdir() returns a pointer to # 'struct dirent', you will have to add the '-DDIRENT' to CFLAGS # #NEED_DIRENT = -DDIRENT # If, when 'Applying' colors, or when loading new pictures, you get an # X Protocol Error on the XFreeColors() call, your X Server is Wrong. # Several workarounds: You can specify '-bfc' on the command line, or # set the 'xv.brokeFreeCols' resource to 'true'. Alternately, you can # uncomment the BROKECOLS line below to compile in the workarounds # permanently. If you do this, '-bfc' will toggle OFF the workarounds. # Noteworthy Offenders: AIX 3.1 on IBM 6000, and OLW on Suns # #BROKECOLS = -DBROKEFREECOLS # IF YOUR MACHINE DOESN'T HAVE 'vprintf()' OR 'vsprintf()' # # Vax BSD and IBM AOS don't have vprintf or vsprintf. # Note that our local library versions of sprintf have been updated # to return int, the number of characters in the formatted string, # whereas the versions in stock 4.3BSD do not so return. You may # have to remove the "-DINTSPRINTF" below if you're compiling for # stock 4.3BSD or for some other Vax or RT library package where # sprintf returns char *. # # Also, I define NOVOID on the Vax because I'm using pcc to compile. # If you use gcc or some other better compiler, this should not be # necessary. I define NOSTDHDRS on the RT because we don't have # standard ANSI header files installed for the RT, even though the RT # compiler claims to be ANSI-compliant. # # (for BSD 4.3 VAX, uncomment the following line) #VPRINTF = -DNEED_VPRINTF -DINTSPRINTF -DLONGINT -DNOVOID # (for (stock) IBM RT AOS 4.3, uncomment the following line) #VPRINTF = -DNEED_VPRINTF -DLONGINT -DNOSTDHDRS # If your machine does not have the 'setitimer()' call, but does # have the 'usleep()' call, uncomment the following line: # #TIMERS = -DUSLEEP # # alternately, if your machine does not have EITHER the 'setitimer()' or # the 'usleep()' call, uncomment the following line: # #TIMERS = -DNOTIMER # If you are using an AT&T machine, uncomment the following line # If you have ptoblems compiling xv.c and xvdir.c because of the DIR # reference in dirent.h, append '-DATT' to the following line: # #ATT = -DSYSV -DDIRENT -DUSLEEP -DATT # For SCO and ODT machines, uncomment the following: # #SCO = -Dsco -DPOSIX -DNOTIMER # # Itimers will be in 3.2v3 (yeah!) but that won't be out in the public's # hands for a while. Hey, it's just the fish anyways. # # Also, you'll want to change LIBS to # # -lX11 -lm -lsocket -lmalloc -lc -lx # # -lx must be after -lc so you get the right directory routines. # CFLAGS = -O $(NEED_DIRENT) $(BROKECOLS) $(VPRINTF) $(TIMERS) $(ATT) $(SCO) \ $(UNIX) LIBS = -lX11 -lm BITMAPS = bitmaps/grasp bitmaps/penn bitmaps/down bitmaps/down1 \ bitmaps/up bitmaps/up1 bitmaps/scrlgray bitmaps/gray50 \ bitmaps/gray25 bitmaps/i_fifo bitmaps/i_chr bitmaps/i_dir \ bitmaps/i_blk bitmaps/i_lnk bitmaps/i_sock bitmaps/i_reg \ bitmaps/rb_off bitmaps/rb_on bitmaps/rb_off1 bitmaps/rb_on1 \ bitmaps/fc_left bitmaps/fc_leftm bitmaps/fc_mid bitmaps/fc_midm \ bitmaps/fc_right bitmaps/fc_rightm bitmaps/fc_left1 \ bitmaps/fc_left1m bitmaps/fc_right1 bitmaps/fc_right1m \ bitmaps/icon OBJS = xv.o xvmisc.o xv24to8.o xvgif.o xvpm.o xvinfo.o xvctrl.o xvscrl.o \ xvgifwr.o xvdir.o xvbutt.o xvpbm.o xvxbm.o xvgam.o xvfish.o \ vprintf.o MISC = README PATCHLEVEL .c.o: ; $(CC) -c $(CFLAGS) -o $@ $*.c all: xv bggen xv: $(OBJS) $(CC) $(CFLAGS) -o xv $(OBJS) $(LIBS) bggen: bggen.c $(CC) $(CFLAGS) -o bggen bggen.c clean: rm -f $(OBJS) tar: tar cf xv.tar Makefile* Imakefile *.c *.h bitmaps docs $(MISC) xv.3100: bitmaps.h cc -O3 *.c -o xv $(XLIB) $(OBJS): xv.h xv.o: bitmaps.h xvmisc.o: bitmaps.h xvinfo.o: bitmaps.h xvctrl.o: bitmaps.h xvscrl.o: bitmaps.h xvbutt.o: bitmaps.h bitmaps.h: $(BITMAPS) cat $(BITMAPS) > bitmaps.h \BARFOO\ else echo "will not over write ./Makefile.std" fi if `test ! -s ./Imakefile` then echo "writting ./Imakefile" cat > ./Imakefile << '\BARFOO\' /* * if you are running on a SysV-based machine, such as HP, Silicon Graphics, * etc, uncomment the following line to get you *most* of the way there. */ /* UNIX = -DSVR4 */ /* * If you are running on a POSIX-compatible machine, such as an * IBM RS6000, you MAY need uncomment the 'NEED_DIRENT' line. * To determine if such is the case, do a 'man readdir' on your machine. If * readdir() returns a pointer to 'struct direct', you will not have * to change anything. If, however, readdir() returns a pointer to * 'struct dirent', you will have to add the '-DDIRENT' to CFLAGS */ /* NEED_DIRENT = -DDIRENT */ /* If, when 'Applying' colors, or when loading new pictures, you get an * X Protocol Error on the XFreeColors() call, your X Server is Wrong. * Several workarounds: You can specify '-bfc' on the command line, or * set the 'xv.brokeFreeCols' resource to 'true'. Alternately, you can * uncomment the BROKECOLS line below to compile in the workarounds * permanently. If you do this, '-bfc' will toggle OFF the workarounds. * * Noteworthy Offenders: AIX 3.1 on IBM 6000, and OLW on Suns */ /* BROKECOLS = -DBROKEFREECOLS */ /* IF YOUR MACHINE DOESN'T HAVE 'vprintf()' OR 'vsprintf()' * * Vax BSD and IBM AOS don't have vprintf or vsprintf. * Note that our local library versions of sprintf have been updated * to return int, the number of characters in the formatted string, * whereas the versions in stock 4.3BSD do not so return. You may * have to remove the "-DINTSPRINTF" below if you're compiling for * stock 4.3BSD or for some other Vax or RT library package where * sprintf returns char *. * * Also, I define NOVOID on the Vax because I'm using pcc to compile. * If you use gcc or some other better compiler, this should not be * necessary. I define NOSTDHDRS on the RT because we don't have * standard ANSI header files installed for the RT, even though the RT * compiler claims to be ANSI-compliant. */ #if defined(VaxArchitecture) && !defined(UltrixArchitecture) VPRINTF= -DNEED_VPRINTF -DINTSPRINTF -DLONGINT -DNOVOID #else # if defined(RtArchitecture) && !defined(AIXArchitecture) VPRINTF= -DNEED_VPRINTF -DINTSPRINTF -DLONGINT -DNOSTDHDRS # endif #endif /* If your machine does not have the 'setitimer()' call, but does * have the 'usleep()' call, uncomment the following line: */ /* TIMERS = -DUSLEEP */ /* * alternately, if your machine does not have EITHER the 'setitimer()' or * the 'usleep()' call, uncomment the following line: */ /* TIMERS = -DNOTIMER */ /* If you are using an AT&T machine, uncomment the following line * If you have ptoblems compiling xv.c and xvdir.c because of the DIR * reference in dirent.h, append '-DATT' to the following line: */ /* ATT = -DSYSV -DDIRENT -DUSLEEP -DATT */ #if defined(SCOArchitecture) DEFINES= -DPOSIX -DNOITIMER SYS_LIBRARIES= $(XLIB) -lm -lc -lx #else SYS_LIBRARIES= $(XLIB) -lm #endif CCOPTIONS= $(UNIX) $(NEED_DIRENT) $(BROKECOLS) $(VPRINTF) $(TIMERS) $(ATT) SYS_LIBRARIES= -lX11 -lm BITMAPS = bitmaps/grasp bitmaps/penn bitmaps/down bitmaps/down1 \ bitmaps/up bitmaps/up1 bitmaps/scrlgray bitmaps/gray50 \ bitmaps/gray25 bitmaps/i_fifo bitmaps/i_chr bitmaps/i_dir \ bitmaps/i_blk bitmaps/i_lnk bitmaps/i_sock bitmaps/i_reg \ bitmaps/rb_off bitmaps/rb_on bitmaps/rb_off1 bitmaps/rb_on1 \ bitmaps/fc_left bitmaps/fc_leftm bitmaps/fc_mid bitmaps/fc_midm \ bitmaps/fc_right bitmaps/fc_rightm bitmaps/fc_left1 \ bitmaps/fc_left1m bitmaps/fc_right1 bitmaps/fc_right1m \ bitmaps/icon SRCS1 = xv.c xv24to8.c xvbutt.c xvctrl.c xvdir.c xvfish.c xvgam.c\ xvgif.c xvgifwr.c xvinfo.c xvmisc.c xvpbm.c xvpm.c xvscrl.c\ xvxbm.c vprintf.c OBJS1 = xv.o xv24to8.o xvbutt.o xvctrl.o xvdir.o xvfish.o xvgam.o\ xvgif.o xvgifwr.o xvinfo.o xvmisc.o xvpbm.o xvpm.o xvscrl.o \ xvxbm.o vprintf.o SRCS2= bggen.c OBJS2= bggen.o PROGRAMS= xv bggen ComplexProgramTarget_1(xv,,) ComplexProgramTarget_2(bggen,,) InstallNonExec(docs/xv.man,$(MANDIR)/xv.ManSuffix) InstallNonExec(docs/bggen.man,$(MANDIR)/bggen.ManSuffix) tar: tar cf xv.tar Makefile *.c *.h bitmaps docs $(MISC) bitmaps.h: $(BITMAPS) cat $(BITMAPS) > bitmaps.h depend:: bitmaps.h \BARFOO\ else echo "will not over write ./Imakefile" fi if `test ! -s ./bggen.c` then echo "writting ./bggen.c" cat > ./bggen.c << '\BARFOO\' /* * bggen.c - a program that generates backgrounds for use with XV * * by John Bradley, University of Pennsylvania * (bradley@cis.upenn.edu) * * Rev: 8/31/90 * Rev: 10/17/90 - added '-w' option */ /* * Copyright 1989, 1990 by the University of Pennsylvania * * Permission to use, copy, and distribute for non-commercial purposes, * is hereby granted without fee, providing that the above copyright * notice appear in all copies and that both the copyright notice and this * permission notice appear in supporting documentation. * * The software may be modified for your own purposes, but modified versions * may not be distributed. * * This software is provided "as is" without any express or implied warranty. */ #include <stdio.h> #define DEFSIZE 1024 #define MAXCOLS 128 struct color { int r,g,b; int y; } cols[MAXCOLS], *cur, *nex; int bmask[8] = { 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; main(argc,argv) int argc; char **argv; { int i,j,cnt,numcols; int high = DEFSIZE; int wide = 1; int bits = 8; int r, g, b; cnt = 0; numcols = 0; for (i=1; i<argc; i++) { if (!strcmp(argv[i],"-s")) high = atoi(argv[++i]); else if (!strcmp(argv[i],"-w")) wide = atoi(argv[++i]); else if (!strcmp(argv[i],"-b")) bits = atoi(argv[++i]); else if (argv[i][0]=='-') break; /* any other '-' option is unknown */ else { switch (cnt) { case 0: cols[numcols].r = atoi(argv[i]); break; case 1: cols[numcols].g = atoi(argv[i]); break; case 2: cols[numcols].b = atoi(argv[i]); break; } cnt++; if (cnt==3) { if (numcols<MAXCOLS) numcols++; cnt = 0; } } } if (cnt || numcols==0 || high<1 || bits<1 || bits>8) { fprintf(stderr,"usage: %s [-s size] [-w width] [-b bits] %s\n\n", argv[0], "r1 g1 b1 [r2 g2 b2 ...]"); fprintf(stderr,"\tThis will generate a WIDTHxSIZE vertical color band.\n"); fprintf(stderr,"\t(Default: 1x%d) To set your background\n",DEFSIZE); fprintf(stderr,"\t'bits' is the number of significant bits in the\n"); fprintf(stderr,"\tcolor specifications. (1-8)\n"); fprintf(stderr,"\tpipe the resulting output into this cmd:\n"); fprintf(stderr,"\t\t'xv -root -quit -slow24'\n\n"); exit(1); } printf("P3 %d %d 255\n",wide,high); /* special case code for numcols==1 */ if (numcols==1) { for (i=0; i<high; i++) for (j=0; j<wide; j++) printf("%d %d %d\n",cols[0].r,cols[0].g,cols[0].b); } else { /* fill in 'y' field of cols[] */ for (i=0; i<numcols; i++) cols[i].y = ((high-1) * i) / (numcols-1); cur = &cols[0]; nex = cur+1; for (i=0; i<high; i++) { /* advance to next pair of colors if we're outside region */ while (nex->y < i) { cur++; nex++; } r = cur->r + ((nex->r - cur->r) * (i - cur->y)) / (nex->y - cur->y); g = cur->g + ((nex->g - cur->g) * (i - cur->y)) / (nex->y - cur->y); b = cur->b + ((nex->b - cur->b) * (i - cur->y)) / (nex->y - cur->y); r = r & bmask[bits-1]; g = g & bmask[bits-1]; b = b & bmask[bits-1]; for (j=0; j<wide; j++) printf("%d %d %d\n",r,g,b); } } } \BARFOO\ else echo "will not over write ./bggen.c" fi if `test ! -s ./vprintf.c` then echo "writting ./vprintf.c" cat > ./vprintf.c << '\BARFOO\' #ifdef NEED_VPRINTF #include <stdio.h> /* Portable vsprintf by Robert A. Larson <blarson@skat.usc.edu> */ /* Portable vfprintf by Robert A. Larson <blarson@skat.usc.edu> */ /* Copyright 1989 Robert A. Larson. * Distribution in any form is allowed as long as the author * retains credit, changes are noted by their author and the * copyright message remains intact. This program comes as-is * with no warentee of fitness for any purpouse. * * Thanks to Doug Gwen, Chris Torek, and others who helped clarify * the ansi printf specs. * * Please send any bug fixes and improvments to blarson@skat.usc.edu . * The use of goto is NOT a bug. */ /* Feb 7, 1989 blarson First usenet release */ /* This code implements the vsprintf function, without relying on * the existance of _doprint or other system specific code. * * Define NOVOID if void * is not a supported type. * * Two compile options are available for efficency: * INTSPRINTF should be defined if sprintf is int and returns * the number of chacters formated. * LONGINT should be defined if sizeof(long) == sizeof(int) * * They only make the code smaller and faster, they need not be * defined. * * UNSIGNEDSPECIAL should be defined if unsigned is treated differently * than int in argument passing. If this is definded, and LONGINT is not, * the compiler must support the type unsingned long. * * Most quirks and bugs of the available sprintf fuction are duplicated, * however * in the width and precision fields will work correctly * even if sprintf does not support this, as will the n format. * * Bad format strings, or those with very long width and precision * fields (including expanded * fields) will cause undesired results. */ #ifdef OSK /* os9/68k can take advantage of both */ #define LONGINT #define INTSPRINTF #endif /* This must be a typedef not a #define! */ #ifdef NOVOID typedef char *pointer; #else typedef void *pointer; #endif #ifdef INTSPRINTF #define Sprintf(string,format,arg) (sprintf((string),(format),(arg))) #else #define Sprintf(string,format,arg) (\ sprintf((string),(format),(arg)),\ strlen(string)\ ) #endif #if defined(__STDC__) && !defined(NOSTDHDRS) #include <stdarg.h> #else #include <varargs.h> #endif typedef int *intp; int vsprintf(dest, format, args) char *dest; register char *format; va_list args; { register char *dp = dest; register char c; register char *tp; char tempfmt[64]; #ifndef LONGINT int longflag; #endif tempfmt[0] = '%'; while( (c = *format++) != 0) { if(c=='%') { tp = &tempfmt[1]; #ifndef LONGINT longflag = 0; #endif continue_format: switch(c = *format++) { case 's': *tp++ = c; *tp = '\0'; dp += Sprintf(dp, tempfmt, va_arg(args, char *)); break; case 'u': case 'x': case 'o': case 'X': #ifdef UNSIGNEDSPECIAL *tp++ = c; *tp = '\0'; #ifndef LONGINT if(longflag) dp += Sprintf(dp, tempfmt, va_arg(args, unsigned long)); else #endif dp += Sprintf(dp, tempfmt, va_arg(args, unsigned)); break; #endif case 'd': case 'c': case 'i': *tp++ = c; *tp = '\0'; #ifndef LONGINT if(longflag) dp += Sprintf(dp, tempfmt, va_arg(args, long)); else #endif dp += Sprintf(dp, tempfmt, va_arg(args, int)); break; case 'f': case 'e': case 'E': case 'g': case 'G': *tp++ = c; *tp = '\0'; dp += Sprintf(dp, tempfmt, va_arg(args, double)); break; case 'p': *tp++ = c; *tp = '\0'; dp += Sprintf(dp, tempfmt, va_arg(args, pointer)); break; case '-': case '+': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': case ' ': case '#': case 'h': *tp++ = c; goto continue_format; case 'l': #ifndef LONGINT longflag = 1; *tp++ = c; #endif goto continue_format; case '*': tp += Sprintf(tp, "%d", va_arg(args, int)); goto continue_format; case 'n': *va_arg(args, intp) = dp - dest; break; case '%': default: *dp++ = c; break; } } else *dp++ = c; } *dp = '\0'; return dp - dest; } int vfprintf(dest, format, args) FILE *dest; register char *format; va_list args; { register char c; register char *tp; register int count = 0; char tempfmt[64]; #ifndef LONGINT int longflag; #endif tempfmt[0] = '%'; while(c = *format++) { if(c=='%') { tp = &tempfmt[1]; #ifndef LONGINT longflag = 0; #endif continue_format: switch(c = *format++) { case 's': *tp++ = c; *tp = '\0'; count += fprintf(dest, tempfmt, va_arg(args, char *)); break; case 'u': case 'x': case 'o': case 'X': #ifdef UNSIGNEDSPECIAL *tp++ = c; *tp = '\0'; #ifndef LONGINT if(longflag) count += fprintf(dest, tempfmt, va_arg(args, unsigned long)); else #endif count += fprintf(dest, tempfmt, va_arg(args, unsigned)); break; #endif case 'd': case 'c': case 'i': *tp++ = c; *tp = '\0'; #ifndef LONGINT if(longflag) count += fprintf(dest, tempfmt, va_arg(args, long)); else #endif count += fprintf(dest, tempfmt, va_arg(args, int)); break; case 'f': case 'e': case 'E': case 'g': case 'G': *tp++ = c; *tp = '\0'; count += fprintf(dest, tempfmt, va_arg(args, double)); break; case 'p': *tp++ = c; *tp = '\0'; count += fprintf(dest, tempfmt, va_arg(args, pointer)); break; case '-': case '+': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': case ' ': case '#': case 'h': *tp++ = c; goto continue_format; case 'l': #ifndef LONGINT longflag = 1; *tp++ = c; #endif goto continue_format; case '*': tp += Sprintf(tp, "%d", va_arg(args, int)); goto continue_format; case 'n': *va_arg(args, intp) = count; break; case '%': default: putc(c, dest); count++; break; } } else { putc(c, dest); count++; } } return count; } vprintf(format, args) char *format; va_list args; { return vfprintf(stdout, format, args); } #endif \BARFOO\ else echo "will not over write ./vprintf.c" fi echo "Finished archive 10 of 10" exit dan ---------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com Opinions expressed reflect those of the author only. -- dan ---------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com Opinions expressed reflect those of the author only.