home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-12-10 | 32.3 KB | 1,328 lines |
- Path: uunet!cs.utexas.edu!sun-barr!newstop!exodus!appserv!halibut.cis.upenn.edu
- From: bradley@halibut.cis.upenn.edu (John Bradley)
- Newsgroups: comp.sources.x
- Subject: v10i082: xv - display and manipulate images, Part04/10
- Message-ID: <320@appserv.Eng.Sun.COM>
- Date: 27 Nov 90 20:08:20 GMT
- References: <csx-10i079:xv@uunet.UU.NET>
- Sender: news@exodus.Eng.Sun.COM
- Lines: 1311
- Approved: argv@sun.com
-
- Submitted-by: bradley@halibut.cis.upenn.edu (John Bradley)
- Posting-number: Volume 10, Issue 82
- Archive-name: xv/part04
-
- #!/bin/sh
- # to extract, remove the header and type "sh filename"
- if `test ! -s ./xvpbm.c`
- then
- echo "writting ./xvpbm.c"
- cat > ./xvpbm.c << '\BARFOO\'
- /*
- * xvpbm.c - load routine for 'pm' format pictures
- *
- * LoadPBM(fname, numcols) - loads a PBM, PGM, or PPM file
- * WritePBM(fp,pic,w,h,r,g,b,numcols,style,raw,cmt)
- */
-
- /*
- * 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 "xv.h"
-
-
-
- /* comments on error handling:
- a truncated file is not considered a Major Error. The file is loaded, the
- rest of the pic is filled with 0's.
-
- a file with garbage characters in it is an unloadable file. All allocated
- stuff is tossed, and LoadPBM returns non-zero
-
- not being able to malloc is a Fatal Error. The program is aborted. */
-
-
- #define TRUNCSTR "File appears to be truncated."
-
- static int garbage;
- static long numgot, filesize;
-
-
- static int loadpbm(), loadpgm(), loadppm();
- static int getint(), getbit(), PBMerr();
-
-
- /*******************************************/
- int LoadPBM(fname,nc)
- char *fname;
- int nc;
- /*******************************************/
- {
- FILE *fp;
- int c, c1;
- int w, h, maxv, rv;
-
- garbage = maxv = 0;
-
- /* open the stream, if necesary */
- fp=fopen(fname,"r");
- if (!fp) return 1;
-
- /* figure out the file size (for Informational Purposes Only) */
- fseek(fp, 0L, 2);
- filesize = ftell(fp);
- fseek(fp, 0L, 0);
-
- /* read the first two bytes of the file to determine which format
- this file is. "P1" = ascii bitmap, "P2" = ascii greymap,
- "P3" = ascii pixmap, "P4" = raw bitmap, "P5" = raw greymap,
- "P6" = raw pixmap */
-
- c = getc(fp); c1 = getc(fp);
- if (c!='P' || c1<'1' || c1>'6') return(PBMerr("unknown format"));
-
- /* read in header information */
- w = getint(fp); h = getint(fp);
-
- /* if we're not reading a bitmap, read the 'max value' */
- if ( !(c1=='1' || c1=='4')) {
- maxv = getint(fp);
- if (maxv < 1) garbage=1; /* to avoid 'div by zero' probs */
- }
-
-
- if (garbage) {
- if (fp!=stdin) fclose(fp);
- return (PBMerr("Garbage characters in header."));
- }
-
- rv = 0;
-
- /* call the appropriate subroutine to handle format-specific stuff */
- if (c1=='1' || c1=='4') rv = loadpbm(fp,w,h, c1=='4' ? 1 : 0);
- else if (c1=='2' || c1=='5') rv = loadpgm(fp,w,h, maxv, c1=='5' ? 1 : 0);
- else if (c1=='3' || c1=='6') rv = loadppm(fp,w,h, maxv, c1=='6' ? 1 : 0, nc);
-
- if (fp!=stdin) fclose(fp);
- return(rv);
- }
-
-
-
- /*******************************************/
- static int loadpbm(fp, w, h, raw)
- FILE *fp;
- int w,h,raw;
- {
- byte *pix;
- int i,j,bit;
-
-
- SetISTR(ISTR_FORMAT,"PBM, %s format. (%ld bytes)",
- (raw) ? "raw" : "ascii", filesize);
-
- /* load up the XV global variables */
- pic = (byte *) calloc(w*h,1);
- if (!pic) FatalError("couldn't malloc 'pic'");
-
- pWIDE = w; pHIGH = h;
-
- /* B/W bitmaps have a two entry colormap */
- r[0] = g[0] = b[0] = 255; /* 0 = white */
- r[1] = g[1] = b[1] = 0; /* 1 = black */
-
- if (!raw) {
- numgot = 0;
- for (i=0, pix=pic; i<h; i++)
- for (j=0; j<w; j++, pix++)
- *pix = getbit(fp);
-
- if (numgot != w*h) PBMerr(TRUNCSTR);
- if (garbage) {
- free(pic);
- return(PBMerr("Garbage characters in image data."));
- }
- }
-
-
- else { /* read raw bits */
- int trunc = 0, k = 0;
-
- for (i=0, pix=pic; i<h; i++)
- for (j=0,bit=0; j<w; j++, pix++, bit++) {
-
- bit &= 7;
- if (!bit) {
- k = getc(fp);
- if (k==EOF) { trunc=1; k=0; }
- }
-
- *pix = (k&0x80) ? 1 : 0;
- k = k << 1;
- }
-
- if (trunc) PBMerr(TRUNCSTR);
- }
-
- return 0;
- }
-
-
- /*******************************************/
- static int loadpgm(fp, w, h, maxv, raw)
- FILE *fp;
- int w,h,maxv,raw;
- {
- byte *pix;
- int i,j,bitshift;
-
- SetISTR(ISTR_FORMAT,"PGM, %s format. (%ld bytes)",
- (raw) ? "raw" : "ascii", filesize);
-
- /* load up the XV global variables */
- pic = (byte *) calloc(w*h,1);
- if (!pic) FatalError("couldn't malloc 'pic'");
-
- pWIDE = w; pHIGH = h;
-
- /* if maxv>255, keep dropping bits until it's reasonable */
- bitshift = 0;
- while (maxv>255) { maxv = maxv>>1; bitshift++; }
-
- /* fill in a greyscale colormap where maxv maps to 255 */
- for (i=0; i<=maxv; i++)
- r[i] = g[i] = b[i] = (i*255)/maxv;
-
- if (!raw) {
- numgot = 0;
- for (i=0, pix=pic; i<h; i++)
- for (j=0; j<w; j++, pix++)
- *pix = (getint(fp) >> bitshift);
- }
-
- else numgot = fread(pic, 1, w*h, fp); /* read raw data */
-
- if (numgot != w*h) PBMerr(TRUNCSTR);
-
- if (garbage) {
- free(pic);
- return (PBMerr("Garbage characters in image data."));
- }
-
- return 0;
- }
-
-
- /*******************************************/
- static int loadppm(fp, w, h, maxv, raw, nc)
- FILE *fp;
- int w,h,maxv,raw,nc;
- {
- byte *pix, *pic24, scale[256];
- int i,j,bitshift;
-
- SetISTR(ISTR_FORMAT,"PPM, %s format. (%ld bytes)",
- (raw) ? "raw" : "ascii", filesize);
-
- /* allocate 24-bit image */
- pic24 = (byte *) calloc(w*h*3,1);
- if (!pic24) FatalError("couldn't malloc 'pic24'");
-
- /* if maxv>255, keep dropping bits until it's reasonable */
- bitshift = 0;
- while (maxv>255) { maxv = maxv>>1; bitshift++; }
-
- if (!raw) {
- numgot = 0;
- for (i=0, pix=pic24; i<h; i++)
- for (j=0; j<w*3; j++, pix++)
- *pix = (getint(fp) >> bitshift);
- }
-
- else numgot = fread(pic24, 1, w*h*3, fp); /* read raw data */
-
- if (numgot != w*h*3) PBMerr(TRUNCSTR);
-
- if (garbage) {
- free(pic24);
- return(PBMerr("Garbage characters in image data."));
- }
-
- /* have to scale all RGB values up (Conv24to8 expects RGB values to
- range from 0-255 */
-
- if (maxv<255) {
- for (i=0; i<=maxv; i++) scale[i] = (i * 255) / maxv;
-
- for (i=0, pix=pic24; i<h; i++)
- for (j=0; j<w*3; j++, pix++)
- *pix = scale[*pix];
- }
-
- i = Conv24to8(pic24,w,h,nc);
- free(pic24);
- return i;
- }
-
-
-
- /*******************************************/
- static int getint(fp)
- FILE *fp;
- {
- int c, i;
-
- /* skip forward to start of next number */
- c = getc(fp);
- while (1) {
- /* eat comments */
- if (c=='#') { /* if we're at a comment, read to end of line */
- while (c != '\n' && c != EOF) c=getc(fp);
- }
-
- if (c==EOF) return 0;
- if (c>='0' && c<='9') break; /* we've found what we were looking for */
-
- /* see if we are getting garbage (non-whitespace) */
- if (c!=' ' && c!='\t' && c!='\r' && c!='\n' && c!=',') garbage=1;
-
- c = getc(fp);
- }
-
-
- /* we're at the start of a number, continue until we hit a non-number */
- i = 0;
- while (1) {
- i = (i*10) + (c - '0');
- c = getc(fp);
- if (c==EOF) return i;
- if (c<'0' || c>'9') break;
- }
-
- numgot++;
- return i;
- }
-
-
-
- /*******************************************/
- static int getbit(fp)
- FILE *fp;
- {
- int c;
-
- /* skip forward to start of next number */
- c = getc(fp);
- while (1) {
- /* eat comments */
- if (c=='#') { /* if we're at a comment, read to end of line */
- while (c != '\n' && c != EOF) c=getc(fp);
- }
-
- if (c==EOF) return 0;
- if (c=='0' || c=='1') break; /* we've found what we were looking for */
-
- /* see if we are getting garbage (non-whitespace) */
- if (c!=' ' && c!='\t' && c!='\r' && c!='\n' && c!=',') garbage=1;
-
- c = getc(fp);
- }
-
-
- numgot++;
- return(c-'0');
- }
-
-
- /*******************************************/
- static int PBMerr(st)
- char *st;
- {
- SetISTR(ISTR_WARNING,st);
- return 1;
- }
-
-
-
-
-
- /*******************************************/
- 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;
- {
- /* writes a PBM/PGM/PPM file to the already open stream
- if (raw), writes as RAW bytes, otherwise writes as ASCII
- 'colorstyle' single-handedly determines the type of file written
- if colorstyle==0, (Full Color) a PPM file is written
- if colorstyle==1, (Greyscale) a PGM file is written
- if colorstyle==2, (B/W stipple) a PBM file is written */
-
- int magic;
- byte *pix;
- int i,j,len;
-
- /* calc the appropriate magic number for this file type */
- magic = 0;
- if (colorstyle==0) magic = 3;
- else if (colorstyle==1) magic = 2;
- else if (colorstyle==2) magic = 1;
-
- if (raw && magic) magic+=3;
-
- if (!magic) return(PBMerr("WritePBM: unknown file format"));
-
- /* write the header info */
- fprintf(fp,"P%d\n",magic);
- fprintf(fp,"# created by 'xv %s'\n", namelist[curname]);
- fprintf(fp,"%d %d\n",w,h);
- if (colorstyle!=2) fprintf(fp,"255\n");
-
- if (ferror(fp)) return -1;
-
- /* write the image data */
-
- if (colorstyle==0) { /* 24bit RGB, 3 bytes per pixel */
- for (i=0, pix=pic, len=0; i<h; i++)
- for (j=0; j<w; j++,pix++) {
- if (raw) {
- putc(r[*pix],fp);
- putc(g[*pix],fp);
- putc(b[*pix],fp);
- }
- else {
- fprintf(fp,"%3d %3d %3d ",r[*pix], g[*pix], b[*pix]);
- len+=12;
- if (len>58) { fprintf(fp,"\n"); len=0; }
- }
- }
- }
-
- else if (colorstyle==1) { /* 8-bit greyscale */
- byte rgb[256];
- for (i=0; i<numcols; i++) rgb[i] = MONO(rmap[i],gmap[i],bmap[i]);
- for (i=0, pix=pic, len=0; i<w*h; i++,pix++) {
- if (raw) putc(rgb[*pix],fp);
- else {
- fprintf(fp,"%3d ",rgb[*pix]);
- len += 4;
- if (len>66) { fprintf(fp,"\n"); len=0; }
- }
- }
- }
-
- else if (colorstyle==2) { /* 1-bit B/W stipple */
- int bit,k;
- for (i=0, pix=pic, len=0; i<h; i++) {
- for (j=0, bit=0, k=0; j<w; j++, pix++) {
- if (raw) {
- k = (k << 1) | *pix;
- bit++;
- if (bit==8) {
- fputc(~k,fp);
- bit = k = 0;
- }
- }
- else {
- if (*pix) fprintf(fp,"0 ");
- else fprintf(fp,"1 ");
- len+=2;
- if (len>68) { fprintf(fp,"\n"); len=0; }
- }
- } /* j */
- if (raw && bit) {
- k = k << (8-bit);
- fputc(~k,fp);
- }
- }
- }
-
- if (ferror(fp)) return -1;
-
- return 0;
- }
-
-
-
-
-
-
-
- \BARFOO\
- else
- echo "will not over write ./xvpbm.c"
- fi
- if `test ! -s ./xvpm.c`
- then
- echo "writting ./xvpm.c"
- cat > ./xvpm.c << '\BARFOO\'
- /*
- * xvpm.c - load routine for 'pm' format pictures
- *
- * LoadPM(fname, numcols) - loads a PM pic, does 24to8 code if nec.
- * WritePM(fp, pic, w, h, r,g,b, numcols, style)
- * WriteRaw(fp, pic, w, h, r,g,b, numcols, style)
- */
-
- /*
- * 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 "xv.h"
- #include "pm.h"
-
- pmpic thePic;
-
- static int PMError();
- static void flipl();
-
- /*******************************************/
- int LoadPM(fname,nc)
- char *fname;
- int nc;
- /*******************************************/
- {
- FILE *fp;
- int isize,i,flipit,w,h,rv;
-
- rv = 0;
- thePic.pm_image = NULL;
-
- /* read in the PM picture */
- fp=fopen(fname,"r");
- if (!fp) return( PMError("unable to open file") );
-
- flipit = 0;
- fread(&thePic,PM_IOHDR_SIZE,1,fp);
- if (thePic.pm_id != PM_MAGICNO) {
- flipl( (byte *) &thePic.pm_id);
- if (thePic.pm_id == PM_MAGICNO) flipit = 1;
- else flipl( (byte *) &thePic.pm_id);
- }
- if (thePic.pm_id != PM_MAGICNO) return( PMError("not a PM file") );
-
- if (flipit) {
- flipl((byte *) &thePic.pm_np); flipl((byte *) &thePic.pm_nrow);
- flipl((byte *) &thePic.pm_ncol); flipl((byte *) &thePic.pm_nband);
- flipl((byte *) &thePic.pm_form); flipl((byte *) &thePic.pm_cmtsize);
- }
-
- /* make sure that the input picture can be dealt with */
- if ( thePic.pm_nband!=1 ||
- (thePic.pm_form!=PM_I && thePic.pm_form!=PM_C) ||
- (thePic.pm_form==PM_I && thePic.pm_np>1) ||
- (thePic.pm_form==PM_C && (thePic.pm_np==2 || thePic.pm_np>4)) ) {
- fprintf(stderr,"PM picture not in a displayable format.\n");
- fprintf(stderr,"(ie, 1-plane PM_I, or 1-, 3-, or 4-plane PM_C)\n");
- return 1;
- }
-
- w = thePic.pm_ncol; h = thePic.pm_nrow;
-
- isize = pm_isize(&thePic);
-
- if (DEBUG)
- fprintf(stderr,"%s: LoadPM() - loading a %dx%d %s pic, %d planes\n",
- cmd, w, h, (thePic.pm_form==PM_I) ? "PM_I" : "PM_C",
- thePic.pm_np);
-
- SetISTR(ISTR_FORMAT,"PM, %s. (%d plane %s) (%d bytes)",
- (thePic.pm_form==PM_I || thePic.pm_np>1) ?
- "24-bit color" : "8-bit greyscale",
- thePic.pm_np, (thePic.pm_form==PM_I) ? "PM_I" : "PM_C",
- isize + PM_IOHDR_SIZE + thePic.pm_cmtsize);
-
- /* allocate memory for picture and read it in */
- thePic.pm_image = (char *) malloc(isize);
- if (thePic.pm_image == NULL)
- return( PMError("unable to malloc PM picture") );
-
- if (fread(thePic.pm_image, (unsigned) isize, 1, fp) != 1)
- return( PMError("file read error") );
- if (fp!=stdin) fclose(fp);
-
- if (DEBUG) fprintf(stderr,"loadpm 1\n");
-
- /* convert PM picture to 'pic' (8 bit) format */
- if (thePic.pm_form == PM_I) {
- int *intptr;
- byte *pic24, *picptr;
-
- if ((pic24 = (byte *) malloc(w*h*3))==NULL)
- return( PMError("unable to malloc 24-bit picture") );
-
- intptr = (int *) thePic.pm_image;
- picptr = pic24;
-
- if (flipit) { /* if flipit, integer is RRGGBBAA instead of AABBGGRR */
- for (i=w*h; i>0; i--, intptr++) {
- *picptr++ = (*intptr>>24) & 0xff;
- *picptr++ = (*intptr>>16) & 0xff;
- *picptr++ = (*intptr>>8) & 0xff;
- }
- }
- else {
- for (i=w*h; i>0; i--, intptr++) {
- *picptr++ = (*intptr) & 0xff;
- *picptr++ = (*intptr>>8) & 0xff;
- *picptr++ = (*intptr>>16) & 0xff;
- }
- }
-
- if (DEBUG) fprintf(stderr,"loadpm 2\n");
-
- free(thePic.pm_image);
- rv=Conv24to8(pic24,w,h,nc);
- free(pic24);
- }
-
-
- else if (thePic.pm_form == PM_C && thePic.pm_np>1) {
- byte *pic24, *picptr, *rptr, *gptr, *bptr;
-
- if ((pic24 = (byte *) malloc(w*h*3))==NULL)
- return( PMError("unable to malloc 24-bit picture") );
-
- rptr = (byte *) thePic.pm_image;
- gptr = rptr + w*h;
- bptr = rptr + w*h*2;
- picptr = pic24;
- for (i=w*h; i>0; i--) {
- *picptr++ = *rptr++;
- *picptr++ = *gptr++;
- *picptr++ = *bptr++;
- }
- free(thePic.pm_image);
- rv=Conv24to8(pic24,w,h,nc);
- free(pic24);
- }
-
- else if (thePic.pm_form == PM_C && thePic.pm_np==1) {
- /* don't have to convert, just point pic at thePic.pm_image */
- pic = (byte *) thePic.pm_image;
- pWIDE = w; pHIGH = h;
- for (i=0; i<256; i++) r[i]=g[i]=b[i]=i; /* and build mono colortable */
- rv = 0;
- }
-
- return rv;
- }
-
-
- /*******************************************/
- int WritePM(fp, pic, w, h, rmap, gmap, bmap, numcols, colorstyle)
- FILE *fp;
- byte *pic;
- int w,h;
- byte *rmap, *gmap, *bmap;
- int numcols, colorstyle;
- {
- /* writes a PM file to the already open stream
- 'colorstyle' single-handedly determines the type of PM pic written
- if colorstyle==0, (Full Color) a 3-plane PM_C pic is written
- if colorstyle==1, (Greyscal) a 1-plane PM_C pic is written
- if colorstyle==0, (B/W stipple) a 1-plane PM_C pic is written */
-
- char foo[256];
- int i;
- byte *p;
-
- /* create 'comment' field */
- sprintf(foo,"created by 'xv %s'\n", namelist[curname]);
-
- /* fill in fields of a pmheader */
- thePic.pm_id = PM_MAGICNO;
- thePic.pm_np = (colorstyle==0) ? 3 : 1;
- thePic.pm_ncol = w;
- thePic.pm_nrow = h;
- thePic.pm_nband = 1;
- thePic.pm_form = PM_C;
- thePic.pm_cmtsize = strlen(foo);
-
- if (fwrite(&thePic, PM_IOHDR_SIZE, 1, fp) != 1) return -1;
-
- /* write the picture data */
- if (colorstyle == 0) { /* 24bit RGB, organized as 3 8bit planes */
- for (i=0,p=pic; i<w*h; i++, p++)
- putc(rmap[*p], fp);
- for (i=0,p=pic; i<w*h; i++, p++)
- putc(gmap[*p], fp);
- for (i=0,p=pic; i<w*h; i++, p++)
- putc(bmap[*p], fp);
- }
-
- else 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);
- }
-
- else /* (colorstyle == 2) */ { /* B/W stipple. pic is 1's and 0's */
- for (i=0, p=pic; i<w*h; i++, p++)
- putc(*p ? 255 : 0,fp);
- }
-
- if (fputs(foo,fp)==EOF) return -1;
-
- return 0;
- }
-
-
- /*****************************/
- static int PMError(st)
- char *st;
- {
- SetISTR(ISTR_WARNING,"LoadPM() - %s",cmd,st);
- Warning();
- if (thePic.pm_image != NULL) free(thePic.pm_image);
- return -1;
- }
-
-
- /*****************************/
- static void flipl(p)
- byte *p;
- {
- byte t;
- t = p[0]; p[0]=p[3]; p[3] = t;
- t = p[1]; p[1]=p[2]; p[2] = t;
- }
-
-
-
- \BARFOO\
- else
- echo "will not over write ./xvpm.c"
- fi
- if `test ! -s ./xvscrl.c`
- then
- echo "writting ./xvscrl.c"
- cat > ./xvscrl.c << '\BARFOO\'
- /*
- * xvscrl.c - Scroll Bar handling functions
- *
- * callable functions:
- *
- * SCCreate() - creates the Scroll Bar window.
- * SCSetRange() - sets min/max/current values of control
- * SCSetVal() - sets value of control
- * SCRedraw() - redraws scroll bar
- * SCTrack() - called when clicked. Operates control 'til mouseup
- */
-
- /*
- * 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 "xv.h"
- #include "bitmaps.h"
-
-
- static Pixmap upPix, downPix; /* up/down arrows */
- static Pixmap up1Pix, down1Pix; /* up/down arrows (lit up) */
- static Pixmap sgray; /* gray stipple for lit scrollbar */
- static int pixmaps_built=0; /* true if pixmaps created already */
-
-
- /* scroll regions */
- #define UPLINE 0
- #define UPPAGE 1
- #define DNLINE 2
- #define DNPAGE 3
- #define THUMB 4
-
- #define SCRLWAIT 150 /* milliseconds to wait between scrolls */
-
- /* local functions */
- #ifdef __STDC__
- static int whereInScrl(SCRL *, int, int);
- static void drawArrow(SCRL *, int);
- #else
- static int whereInScrl();
- static void drawArrow();
- #endif
-
-
- /***************************************************/
- void SCCreate(sp, parent, x, y, vert, len, minv, maxv, curv, page,
- fg, bg, func)
- SCRL *sp;
- Window parent;
- int x,y,vert,len,minv,maxv,curv,page;
- unsigned long fg,bg;
- void (*func)();
- {
-
-
- if (!pixmaps_built) {
- upPix = XCreatePixmapFromBitmapData(theDisp, parent,
- up_bits, up_width, up_height, fg, bg, dispDEEP);
- downPix = XCreatePixmapFromBitmapData(theDisp, parent,
- down_bits, down_width, down_height, fg, bg, dispDEEP);
- up1Pix = XCreatePixmapFromBitmapData(theDisp, parent,
- up1_bits, up1_width, up1_height, fg, bg, dispDEEP);
- down1Pix = XCreatePixmapFromBitmapData(theDisp, parent,
- down1_bits, down1_width, down1_height,fg,bg,dispDEEP);
- sgray = XCreatePixmapFromBitmapData(theDisp, parent,
- scrlgray_bits, scrlgray_width, scrlgray_height,fg,bg,dispDEEP);
- }
-
- sp->vert = vert;
- sp->len = len;
- sp->fg = fg;
- sp->bg = bg;
- sp->uplit = sp->dnlit = 0;
-
- if (vert)
- sp->win = XCreateSimpleWindow(theDisp, parent,x,y,up_width-2,len,1,fg,bg);
- else FatalError("don't know HOW to make horizontal scrollbar");
-
- if (!sp->win) FatalError("can't create scrollbar window");
-
- sp->tsize = up_width-2; /* really only if vertical */
- sp->tmin = up_height-1;
- sp->tmax = len - (up_height-1) - sp->tsize;
- sp->drawobj = func;
-
- SCSetRange(sp, minv, maxv, curv, page);
- XSelectInput(theDisp, sp->win, ExposureMask | ButtonPressMask);
- }
-
-
- /***************************************************/
- void SCSetRange(sp, minv, maxv, curv, page)
- SCRL *sp;
- int minv, maxv, curv, page;
- {
- if (maxv<minv) maxv=minv;
- sp->min = minv; sp->max = maxv; sp->page = page;
- sp->active = (minv < maxv);
-
- /* adjust scroll bar background */
- if (sp->active) XSetWindowBackgroundPixmap(theDisp, sp->win, sgray);
- else XSetWindowBackground(theDisp, sp->win, sp->bg);
-
- SCSetVal(sp, curv);
- }
-
-
- /***************************************************/
- void SCSetVal(sp, curv)
- SCRL *sp;
- int curv;
- {
- RANGE(curv, sp->min, sp->max); /* make sure curv is in-range */
- sp->val = curv;
-
- if (sp->active)
- sp->tpos = sp->tmin + ((sp->tmax - sp->tmin)*(curv - sp->min))
- / (sp->max - sp->min);
- SCRedraw(sp);
- (sp->drawobj)(); /* redraw whatever the scrollbar controls */
- XFlush(theDisp);
- }
-
-
- /***************************************************/
- void SCRedraw(sp)
- SCRL *sp;
- {
- XSetForeground(theDisp, theGC, sp->fg);
- XSetBackground(theDisp, theGC, sp->bg);
-
- XClearWindow(theDisp, sp->win);
-
- if (sp->vert) { /* draw up/down arrows */
- drawArrow(sp,UPLINE);
- drawArrow(sp,DNLINE);
-
- if (sp->active) { /* a thumb is necessary */
- XSetForeground(theDisp, theGC, sp->bg);
- XFillRectangle(theDisp, sp->win, theGC,
- 1, sp->tpos+1, sp->tsize-2, sp->tsize-2);
- XSetForeground(theDisp, theGC, sp->fg);
- XDrawRectangle(theDisp, sp->win, theGC,
- 0, sp->tpos, sp->tsize-1, sp->tsize-1);
- }
- }
- }
-
-
-
- /***************************************************/
- static int whereInScrl(sp,x,y)
- SCRL *sp;
- int x,y;
- {
- int v;
-
- /* returns region # that x,y is in. Returns '-1' if none */
-
- v=0;
- if (sp->vert) {
- if (x<0 || x>up_width-2 || y<0 || y>sp->len) return -1;
- v = y;
- }
-
- /* once we know it's in scroll bar, only have to check 'v' versus len */
- if (v < sp->tmin) return UPLINE;
- if (sp->active) {
- if (v < sp->tpos) return UPPAGE;
- if (v < sp->tpos + sp->tsize) return THUMB;
- if (v <= sp->tmax + sp->tsize) return DNPAGE;
- }
- if (v > sp->tmax+sp->tsize) return DNLINE;
-
- return -1;
- }
-
-
- /***************************************************/
- static void drawArrow(sp,arr)
- SCRL *sp;
- int arr;
- {
- /* only if vertical */
- if (arr == UPLINE) {
- if (sp->uplit)
- XCopyArea(theDisp, up1Pix, sp->win,theGC,0,0,up_width,up_height,-1,-1);
- else
- XCopyArea(theDisp, upPix, sp->win,theGC,0,0,up_width,up_height,-1,-1);
- }
-
- else if (arr == DNLINE) {
- if (sp->dnlit)
- XCopyArea(theDisp, down1Pix,sp->win,theGC,0,0,up_width,up_height,
- -1, sp->len-(up_height-1));
- else
- XCopyArea(theDisp, downPix, sp->win,theGC,0,0,up_width,up_height,
- -1, sp->len-(up_height-1));
- }
-
- XFlush(theDisp);
- }
-
-
- /***************************************************/
- void SCTrack(sp,mx,my)
- SCRL *sp;
- int mx,my;
- {
- Window rW,cW;
- int rx,ry, x,y, ipos, pos, lit, ty, tyoff, ty1;
- unsigned int mask;
-
- /* determine in which of the five regions of the scroll bar the mouse
- was clicked (upline, downline, uppage, downpage, thumb) */
-
- ty = tyoff = 0;
-
- XSetForeground(theDisp, theGC, sp->fg);
- XSetBackground(theDisp, theGC, sp->bg);
-
- /* light up appropriate bit of scroll bar */
- ipos = whereInScrl(sp,mx,my);
- lit = 1;
-
- switch (ipos) {
- case UPLINE: sp->uplit = 1;
- if (sp->val > sp->min) SCSetVal(sp,sp->val-1);
- Timer(SCRLWAIT);
- break;
-
- case DNLINE: sp->dnlit = 1;
- if (sp->val < sp->max) SCSetVal(sp,sp->val+1);
- Timer(SCRLWAIT);
- break;
-
- case UPPAGE: SCSetVal(sp,sp->val - sp->page); break;
- case DNPAGE: SCSetVal(sp,sp->val + sp->page); break;
- case THUMB: tyoff = sp->tpos - my;
- ty = sp->tpos;
- XSetState(theDisp, theGC, sp->fg, sp->bg, GXinvert,
- sp->fg ^ sp->bg);
- XDrawRectangle(theDisp,sp->win,theGC,
- 0, sp->tpos, sp->tsize-1, sp->tsize-1);
- break;
- }
-
- /* VERTICAL CODE ONLY */
- while (XQueryPointer(theDisp,sp->win,&rW,&cW,&rx,&ry,&x,&y,&mask)) {
- if (!(mask & Button1Mask)) break; /* button released */
-
- switch (ipos) {
-
- case THUMB:
- /* do thumb tracking */
- if (x<-16 || x>16+sp->tsize) { /* outside tracking range */
- if (lit) {
- lit = 0;
- XDrawRectangle(theDisp,sp->win,theGC,0,ty,sp->tsize-1,sp->tsize-1);
- }
- }
-
- else { /* inside tracking range */
- if (!lit) { /* not lit, just turn on */
- lit = 1;
- ty = y + tyoff;
- RANGE(ty, sp->tmin, sp->tmax);
- XDrawRectangle(theDisp,sp->win,theGC,0,ty,sp->tsize-1,sp->tsize-1);
- }
- else { /* already lit, more the thumb */
- ty1 = y+tyoff;
- RANGE(ty1, sp->tmin, sp->tmax);
- if (ty != ty1) { /* but only if mouse has moved */
- XDrawRectangle(theDisp, sp->win, theGC,
- 0,ty,sp->tsize-1,sp->tsize-1);
- ty = ty1;
- XDrawRectangle(theDisp, sp->win, theGC,
- 0,ty,sp->tsize-1,sp->tsize-1);
- }
- }
- }
- break;
-
-
- case UPLINE:
- case DNLINE: /* arrows */
- pos = whereInScrl(sp,x,y);
- if (pos == ipos) {
- if (!lit) {
- lit = 1;
- if (ipos == UPLINE) { sp->uplit = 1; drawArrow(sp,UPLINE); }
- else { sp->dnlit = 1; drawArrow(sp,DNLINE); }
- }
-
- else {
- if (sp->val > sp->min && pos==UPLINE) {
- SCSetVal(sp, sp->val-1);
- Timer(SCRLWAIT);
- }
- else if (sp->val < sp->max && pos==DNLINE) {
- SCSetVal(sp, sp->val+1);
- Timer(SCRLWAIT);
- }
- }
- }
-
- else {
- if (lit) {
- lit = 0;
- if (ipos == UPLINE) { sp->uplit = 0; drawArrow(sp,UPLINE); }
- else { sp->dnlit = 0; drawArrow(sp,DNLINE); }
- }
- }
- break;
-
- }
- }
-
-
- if (ipos == THUMB) {
- if (lit) /* turn off */
- XDrawRectangle(theDisp,sp->win,theGC,0,ty,sp->tsize-1,sp->tsize-1);
-
- XSetState(theDisp, theGC, sp->fg, sp->bg, GXcopy, AllPlanes);
-
- if (lit && ty != sp->tpos) { /* if thumb was moved, ROUND to new val */
- int dt, dv;
- dt = sp->tmax - sp->tmin;
- dv = sp->max - sp->min;
- SCSetVal(sp, sp->min + (dv*(ty - sp->tmin)+dt/2) / dt);
- }
- }
-
- if (lit && ipos == UPLINE) { sp->uplit = 0; drawArrow(sp, UPLINE); }
- if (lit && ipos == DNLINE) { sp->dnlit = 0; drawArrow(sp, DNLINE); }
- }
-
-
-
-
- \BARFOO\
- else
- echo "will not over write ./xvscrl.c"
- fi
- if `test ! -s ./xvxbm.c`
- then
- echo "writting ./xvxbm.c"
- cat > ./xvxbm.c << '\BARFOO\'
- /*
- * xvxbm.c - load routine for X11 Bitmap format pictures
- *
- * LoadXBM(fname) - loads an X11 Bitmap file\
- * WriteXBM(fp, pic, w, h)
- */
-
- /*
- * 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 "xv.h"
-
-
-
- /*
- * File Format:
- * (format identifier: "#define" as first couple chars in file)
- *
- * looks for first line beginning with '#define'
- * reads "#define identifier width" (identifier is ignored)
- * looks for next line beginning with '#define'
- * reads "#define identifier height" (identifier is ignored)
- * looks for next occurence of characters '0x'
- * read next two chars as two hex digits
- * move forward to next occurence of '0x'
- * repeat
- */
-
-
- static int XBMError();
-
-
- /*******************************************/
- int LoadXBM(fname,nc)
- char *fname;
- int nc;
- /*******************************************/
- {
- FILE *fp;
- int c, c1;
- int i, j, k, bit, w, h;
- byte *pix;
- long filesize;
- char line[256];
- byte hex[256];
-
- k = 0;
-
- fp=fopen(fname,"r");
- if (!fp) return 1;
-
- /* figure out the file size (for Informational Purposes Only) */
- fseek(fp, 0L, 2);
- filesize = ftell(fp);
- fseek(fp, 0L, 0);
-
-
- /* read width: skip lines until we hit a #define */
- while (1) {
- if (!fgets(line,256,fp))
- return(XBMError("EOF reached in header info."));
-
- if (strncmp(line,"#define",7)==0) {
- if (sscanf(line,"#define %*s %d", &w) != 1)
- return(XBMError("Unable to read 'width'"));
- else break;
- }
- }
-
-
- /* read height: skip lines until we hit another #define */
- while (1) {
- if (!fgets(line,256,fp))
- return(XBMError("EOF reached in header info."));
-
- if (strncmp(line,"#define",7)==0) {
- if (sscanf(line,"#define %*s %d", &h) != 1)
- return(XBMError("Unable to read 'height'"));
- else break;
- }
- }
-
-
-
- /* scan forward until we see the first '0x' */
- c = getc(fp); c1 = getc(fp);
- while (c1!=EOF && !(c=='0' && c1=='x') ) { c = c1; c1 = getc(fp); }
-
- if (c1==EOF)
- return(XBMError("No bitmap data found"));
-
-
- /* load up the stuff XV expects us to load up */
-
- SetISTR(ISTR_FORMAT,"X11 Bitmap (%ld bytes)", filesize);
-
- pic = (byte *) calloc(w*h,1);
- if (!pic) FatalError("couldn't malloc 'pic'");
-
- pWIDE = w; pHIGH = h;
-
- /* B/W bitmaps have a two entry colormap */
- r[0] = g[0] = b[0] = 255; /* 0 = white */
- r[1] = g[1] = b[1] = 0; /* 1 = black */
-
-
- /* initialize the 'hex' array for zippy ASCII-hex -> int conversion */
-
- for (i=0; i<256; i++) hex[i]=0;
- for (i='0'; i<='9'; i++) hex[i] = i - '0';
- for (i='a'; i<='f'; i++) hex[i] = i + 10 - 'a';
- for (i='A'; i<='F'; i++) hex[i] = i + 10 - 'A';
-
- /* read/convert the image data */
-
- for (i=0, pix=pic; i<h; i++)
- for (j=0,bit=0; j<w; j++, pix++, bit = ++bit&7) {
-
- if (!bit) {
- /* get next byte from file. we're already positioned at it */
- c = getc(fp); c1 = getc(fp);
- if (c<0 || c1<0) {
- /* EOF: break out of loop */
- c=c1='0'; i=h; j=w;
- XBMError("The file would appear to be truncated.");
- }
-
- k = (hex[c] << 4) + hex[c1];
-
- /* advance to next '0x' */
- c = getc(fp); c1 = getc(fp);
- while (c1!=EOF && !(c=='0' && c1=='x') ) { c = c1; c1 = getc(fp); }
- }
-
- *pix = (k&1) ? 1 : 0;
- k = k >> 1;
- }
-
- fclose(fp);
-
- return 0;
- }
-
-
-
- /*******************************************/
- static int XBMError(st)
- char *st;
- {
- SetISTR(ISTR_WARNING,st);
- return 1;
- }
-
-
- /*******************************************/
- int WriteXBM(fp, pic, w, h, fname)
- FILE *fp;
- byte *pic;
- int w,h;
- char *fname;
- {
- /* pic is expected to be an array of w*h bytes. '0' is considered 'black'
- non-zero is considered white. Some sort of stippling algorithm should've
- been called already to produce pic, otherwise the output won't be at all
- useful */
-
- int i,j,k,bit,len,nbytes;
- byte *pix;
- char name[256], *foo;
-
- /* figure out a reasonable basename */
- strcpy(name,fname);
- foo = strchr(name,'.');
- if (foo) *foo='\0'; /* truncated name at first '.' */
-
- fprintf(fp,"#define %s_width %d\n",name,w);
- fprintf(fp,"#define %s_height %d\n",name,h);
- fprintf(fp,"static char %s_bits[] = {\n",name);
-
- fprintf(fp," ");
-
- nbytes = h * ((w+7)/8); /* # of bytes to write */
-
- for (i=0, len=1, pix=pic; i<h; i++) {
- for (j=bit=k=0; j<w; j++,pix++) {
- k = (k>>1);
- if (*pix) k |= 0x80;
- bit++;
- if (bit==8) {
- fprintf(fp,"0x%02x",(byte) ~k);
- nbytes--; len += 4;
- if (nbytes) { fprintf(fp,","); len++; }
- if (len>72) { fprintf(fp,"\n "); len=1; }
- bit = k = 0;
- }
- }
-
- if (bit) {
- k = k >> (8-bit);
- fprintf(fp,"0x%02x",(byte) ~k);
- nbytes--; len += 4;
- if (nbytes) { fprintf(fp,","); len++; }
- if (len>72) { fprintf(fp,"\n "); len=1; }
- }
- }
-
- fprintf(fp,"};\n");
-
- if (ferror(fp)) return -1;
- return 0;
- }
- \BARFOO\
- else
- echo "will not over write ./xvxbm.c"
- fi
- echo "Finished archive 4 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.
-