bradley@halibut.cis.upenn.edu (John Bradley) (11/28/90)
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.