jimf@saber.com (09/28/90)
Submitted-by: saber.com!jimf@saber.com Posting-number: Volume 9, Issue 55 Archive-name: xloadimage/part08 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 8 (of 9)." # Contents: window.c xloadimage.c xpixmap.c zoom.c # Wrapped by jimf@armory on Tue Sep 25 19:37:42 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'window.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'window.c'\" else echo shar: Extracting \"'window.c'\" \(11558 characters\) sed "s/^X//" >'window.c' <<'END_OF_FILE' X/* window.c: X * X * display an image in a window X * X * jim frost 10.03.89 X * X * Copyright 1989, 1990 Jim Frost. See included file "copyright.h" for X * complete copyright information. X */ X X#include "copyright.h" X#include "xloadimage.h" X#include <ctype.h> X#include <X11/cursorfont.h> X X#ifdef SYSV X#include <strings.h> X#define index strchr Xy#define rindex strrchr X#else Xchar *index(); Xchar *rindex(); X#endif X Xstatic Window ImageWindow= 0; X Xstatic void setCursor(disp, window, iw, ih, ww, wh, cursor) X Display *disp; X Window window; X unsigned int iw, ih; X unsigned int ww, wh; X Cursor *cursor; X{ XSetWindowAttributes swa; X X if ((ww >= iw) && (wh >= ih)) X swa.cursor= XCreateFontCursor(disp, XC_icon); X else if ((ww < iw) && (wh >= ih)) X swa.cursor= XCreateFontCursor(disp, XC_sb_h_double_arrow); X else if ((ww >= iw) && (wh < ih)) X swa.cursor= XCreateFontCursor(disp, XC_sb_v_double_arrow); X else X swa.cursor= XCreateFontCursor(disp, XC_fleur); X XChangeWindowAttributes(disp, window, CWCursor, &swa); X XFreeCursor(disp, *cursor); X *cursor= swa.cursor; X} X X/* place an image X */ X Xstatic void placeImage(width, height, winwidth, winheight, rx, ry) X int width, height, winwidth, winheight; X int *rx, *ry; /* supplied and returned */ X{ int pixx, pixy; X X pixx= *rx; X pixy= *ry; X X if (winwidth > width) X pixx= (winwidth - width) / 2; X else { X if ((pixx < 0) && (pixx + width < winwidth)) X pixx= winwidth - width; X if (pixx > 0) X pixx= 0; X } X if (winheight > height) X pixy= (winheight - height) / 2; X else { X if ((pixy < 0) && (pixy + height < winheight)) X pixy= winheight - height; X if (pixy > 0) X pixy= 0; X } X *rx= pixx; X *ry= pixy; X} X X/* blit an image X */ X Xstatic void blitImage(disp, pixmap, window, gc, pixx, pixy, width, height, X winwidth, winheight, x, y, w, h) X Display *disp; X Pixmap pixmap; X Window window; X GC gc; X int pixx, pixy, width, height, winwidth, winheight, x, y, w, h; X{ X if (x + w > winwidth) X w= winwidth - x; X if (y + h > winheight) X h= winheight - y; X if (x < pixx) { X XClearArea(disp, window, x, y, pixx - x, y + h, False); X w -= (pixx - x); X x= pixx; X } X if (y < pixy) { X XClearArea(disp, window, x, y, w, pixy - y, False); X h -= (pixy - y); X y= pixy; X } X if (x + w > pixx + width) { X XClearArea(disp, window, pixx + width, y, w - width, h, False); X w= width; X } X if (y + h > pixy + height) { X XClearArea(disp, window, x, pixy + height, w, h - height, False); X h= height; X } X XCopyArea(disp, pixmap, ImageWindow, gc, x - pixx, y - pixy, w, h, X x, y); X} X X/* clean up static window if we're through with it X */ X Xvoid cleanUpWindow(disp) X Display *disp; X{ X if (ImageWindow) X XDestroyWindow(disp, ImageWindow); X ImageWindow= 0; X} X X/* this attempts to convert an image title into a reasonable icon name X */ X Xstatic char *iconName(s) X char *s; X{ static char buf[BUFSIZ]; X char *t; X X buf[BUFSIZ - 1]= '\0'; X strncpy(buf, s, BUFSIZ - 1); X t= index(buf, ' '); /* strip off stuff following 1st word. this strips */ X if (t) /* info added by processing functions too. */ X *t= '\0'; X X /* strip off leading path. if you don't use unix-style paths, you might X * want to change this. X */ X X if (t= rindex(buf, '/')) { X for (s= buf, t++; *t; s++, t++) X *s= *t; X *s= '\0'; X } X t= index(buf, '.'); /* look for an extension and strip it off */ X if (t) X *t= '\0'; X return(buf); X} X Xchar imageInWindow(disp, scrn, image, user_geometry, X fullscreen, install, slideshow, argc, argv, verbose) X Display *disp; X int scrn; X Image *image; X char *user_geometry; X unsigned int fullscreen; X unsigned int install; X unsigned int slideshow; X int argc; X char *argv[]; X unsigned int verbose; X{ Pixmap pixmap; X Colormap xcmap; X static Colormap tmpxcmap= 0; /* used when in slideshow mode */ X XSetWindowAttributes swa; X XSizeHints sh; X XWMHints wmh; X XGCValues gcv; X GC gc; X int pixx, pixy; X int lastx, lasty, mousex, mousey; X int paint; X union { X XEvent event; X XAnyEvent any; X XButtonEvent button; X XKeyEvent key; X XConfigureEvent configure; X XExposeEvent expose; X XMotionEvent motion; X XResizeRequestEvent resize; X } event; X unsigned int winx, winy, winwidth, winheight; X char def_geom[30]; X X /* figure out the window size. unless specifically requested to do so, X * we will not exceed 90% of display real estate. X */ X X sprintf(def_geom, "%ux%u+0+0", image->width, image->height); X XGeometry(disp, scrn, user_geometry, def_geom, 0, 1, 1, 0, 0, X &winx, &winy, &winwidth, &winheight); X X if (fullscreen) { X winwidth= DisplayWidth(disp, scrn); X winheight= DisplayHeight(disp, scrn); X } X else { X lastx= (winwidth || winheight); /* user set size flag */ X if (!winwidth) { X winwidth= image->width; X if (winwidth > DisplayWidth(disp, scrn) * 0.9) X winwidth= DisplayWidth(disp, scrn) * 0.9; X } X if (!winheight) { X winheight= image->height; X if (winheight > DisplayHeight(disp, scrn) * 0.9) X winheight= DisplayHeight(disp, scrn) * 0.9; X } X } X X if (! sendImageToX(disp, scrn, DefaultVisual(disp, scrn), X image, &pixmap, &xcmap, verbose)) X exit(1); X X swa.background_pixel= BlackPixel(disp,scrn); X swa.backing_store= NotUseful; X swa.bit_gravity= NorthWestGravity; X swa.cursor= XCreateFontCursor(disp, XC_watch); X swa.colormap= xcmap; X swa.event_mask= ButtonPressMask | Button1MotionMask | KeyPressMask | X ExposureMask | StructureNotifyMask | EnterWindowMask | LeaveWindowMask; X swa.save_under= False; X swa.override_redirect= (fullscreen ? True : False); X if (!ImageWindow) { X static XClassHint classHint; X ImageWindow= XCreateWindow(disp, RootWindow(disp, scrn), winx, winy, X winwidth, winheight, 0, X DefaultDepth(disp, scrn), X InputOutput, CopyFromParent, X CWBackPixel | CWBackingStore | X CWBitGravity | CWCursor | CWColormap | X CWEventMask | CWSaveUnder, &swa); X XSetCommand(disp, ImageWindow, argv, argc); X classHint.res_class = "xloadimage"; X classHint.res_name=NULL; X (void) XSetClassHint(disp,ImageWindow,&classHint); X paint= 0; X } X else { X XResizeWindow(disp, ImageWindow, winwidth, winheight); X XChangeWindowAttributes(disp, ImageWindow, CWColormap, &swa); X paint= 1; X } X XStoreName(disp, ImageWindow, image->title); X XSetIconName(disp, ImageWindow, iconName(image->title)); X X sh.width= winwidth; X sh.height= winheight; X if (fullscreen) { X sh.min_width= sh.max_width= winwidth; X sh.min_height= sh.max_height= winheight; X } X else { X sh.min_width= 1; X sh.min_height= 1; X sh.max_width= image->width; X sh.max_height= image->height; X } X sh.width_inc= 1; X sh.height_inc= 1; X if (slideshow) { X sh.flags= PMinSize | PResizeInc; X } else { X sh.flags= PMinSize | PMaxSize | PResizeInc; X } X if (lastx || fullscreen) X sh.flags |= USSize; X else X sh.flags |= PSize; X if (fullscreen) { X sh.x= sh.y= 0; X sh.flags |= USPosition; X } X else if (winx || winy) { X sh.x= winx; X sh.y= winy; X sh.flags |= USPosition; X } X XSetNormalHints(disp, ImageWindow, &sh); X X wmh.input= True; X wmh.flags= InputHint; X XSetWMHints(disp, ImageWindow, &wmh); X X gcv.function= GXcopy; X gcv.foreground= 0; X gc= XCreateGC(disp, ImageWindow, GCFunction | GCForeground, &gcv); X XMapWindow(disp, ImageWindow); X placeImage(image->width, image->height, winwidth, winheight, &pixx, &pixy); X if (paint) X blitImage(disp, pixmap, ImageWindow, gc, X pixx, pixy, image->width, image->height, winwidth, winheight, X 0, 0, winwidth, winheight); X setCursor(disp, ImageWindow, image->width, image->height, X winwidth, winheight, &(swa.cursor)); X X /* free old image's colormap if necessary. this is done here to minimize X * technicolor when swapping images. X */ X X if (slideshow && tmpxcmap) { X XFreeColormap(disp, tmpxcmap); X tmpxcmap= 0; X } X X lastx= lasty= -1; X for (;;) { X XNextEvent(disp, &event); X switch (event.any.type) { X case ButtonPress: X if (event.button.button == 1) { X lastx= event.button.x; X lasty= event.button.y; X break; X } X break; X X case KeyPress: { X char buf[128]; X KeySym ks; X XComposeStatus status; X char ret; X Cursor cursor; X X XLookupString(&event.key,buf,128,&ks,&status); X ret= buf[0]; X if (isupper(ret)) X ret= tolower(ret); X switch (ret) { X case 'n': X case 'p': X cursor= swa.cursor; X swa.cursor= XCreateFontCursor(disp, XC_watch); X XChangeWindowAttributes(disp, ImageWindow, CWCursor, &swa); X XFreeCursor(disp, cursor); X XFlush(disp); X /* FALLTHRU */ X case '\003': /* ^C */ X case 'q': X XFreeCursor(disp, swa.cursor); X XFreePixmap(disp, pixmap); X X /* XCopyColormapAndFree accomplishes two things. First, it frees up X * all our colors in the default colormap. second, on some displays X * it will help cut down on technicolor. i tried to duplicate the X * current colormap exactly but some servers return BadValue when X * trying XQueryColor on an unallocated colormap entry so I gave up. X */ X X if (slideshow && xcmap == DefaultColormap(disp, scrn) && (ret != 'q')) X tmpxcmap= XCopyColormapAndFree(disp, xcmap); X if (xcmap != DefaultColormap(disp, scrn)) X XFreeColormap(disp, xcmap); X return(ret); X } X break; X } X X case MotionNotify: X if ((image->width <= winwidth) && (image->height <= winheight)) X break; /* we're AT&T */ X mousex= event.button.x; X mousey= event.button.y; X while (XCheckTypedEvent(disp, MotionNotify, &event) == True) { X mousex= event.button.x; X mousey= event.button.y; X } X pixx -= (lastx - mousex); X pixy -= (lasty - mousey); X lastx= mousex; X lasty= mousey; X placeImage(image->width, image->height, winwidth, winheight, X &pixx, &pixy); X blitImage(disp, pixmap, ImageWindow, gc, X pixx, pixy, image->width, image->height, winwidth, winheight, X 0, 0, winwidth, winheight); X break; X X case ConfigureNotify: X winwidth= event.configure.width; X winheight= event.configure.height; X X placeImage(image->width, image->height, winwidth, winheight, X &pixx, &pixy); X X /* configure the cursor to indicate which directions we can drag X */ X X setCursor(disp, ImageWindow, image->width, image->height, X winwidth, winheight, &(swa.cursor)); X X /* repaint X */ X X blitImage(disp, pixmap, ImageWindow, gc, X pixx, pixy, image->width, image->height, winwidth, winheight, X 0, 0, winwidth, winheight); X break; X X case DestroyNotify: X XFreeCursor(disp, swa.cursor); X XFreePixmap(disp, pixmap); X if (xcmap != DefaultColormap(disp, scrn)) X XFreeColormap(disp, xcmap); X return('\0'); X X case Expose: X blitImage(disp, pixmap, ImageWindow, gc, X pixx, pixy, image->width, image->height, winwidth, winheight, X event.expose.x, event.expose.y, X event.expose.width, event.expose.height); X break; X X case EnterNotify: X if (install) X XInstallColormap(disp, xcmap); X break; X X case LeaveNotify: X if (install) X XUninstallColormap(disp, xcmap); X } X } X} END_OF_FILE if test 11558 -ne `wc -c <'window.c'`; then echo shar: \"'window.c'\" unpacked with wrong size! fi # end of 'window.c' fi if test -f 'xloadimage.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xloadimage.c'\" else echo shar: Extracting \"'xloadimage.c'\" \(12257 characters\) sed "s/^X//" >'xloadimage.c' <<'END_OF_FILE' X/* loadimage.c: X * X * generic image loader for X11 X * X * jim frost 09.27.89 X * X * Copyright 1989, 1990 Jim Frost. See included file "copyright.h" for X * complete copyright information. X */ X X#include "copyright.h" X#include "xloadimage.h" X#include "patchlevel" X Xextern double atof(); X X/* options array and definitions. note that the enum values must be in the X * same order as the options strings. X */ X Xchar *Options[] = { X "onroot", /* global options */ X "border", X "display", X "fullscreen", X "geometry", X "help", X "identify", X "list", X "install", X "path", X "quiet", X "slideshow", X "supported", X "verbose", X "version", X "view", X X "at", /* image options */ X "background", X "brighten", X "gamma", X "center", X "clip", X "colors", X "dither", X "foreground", X "halftone", X "name", X "rotate", X "smooth", X "xzoom", X "yzoom", X "zoom", X NULL X}; X Xenum { X X /* global options X */ X X ONROOT= 0, BORDER, DISPLAY, FULLSCREEN, GEOMETRY, HELP, IDENTIFY, LIST, X INSTALL, PATH, QUIET, SLIDESHOW, SUPPORTED, VERBOSE, VER_NUM, VIEW, X X /* local options X */ X X AT, BACKGROUND, BRIGHT, GAMMA, CENTER, CLIP, COLORS, DITHER, FOREGROUND, X HALFTONE, NAME, ROTATE, SMOOTH, XZOOM, YZOOM, ZOOM X}; X X/* if an image loader needs to have our display and screen, it will get X * them from here. this is done to keep most of the image routines X * clean X */ X XDisplay *Disp= NULL; Xint Scrn= 0; X X/* the real thing X */ X Xmain(argc, argv) X int argc; X char *argv[]; X{ char *border; X char *dname; X unsigned int identify; X unsigned int install; X unsigned int slideshow; X unsigned int verbose; X Image *dispimage; /* image that will be sent to the display */ X Image *newimage; /* new image we're loading */ X Display *disp; /* display we're sending to */ X int scrn; /* screen we're sending to */ X XColor xcolor; /* color for border option */ X ImageOptions images[MAXIMAGES]; /* list of image w/ options to load */ X int a; X unsigned int imagecount; /* number of images in ImageName array */ X char *user_geometry; /* -geometry passed by user */ X unsigned int winwidth, winheight; /* geometry of image */ X unsigned int slide_bright= 0; /* options which are propagated to all */ X unsigned int slide_colors= 0; /* images when in -slideshow mode */ X unsigned int slide_dither= 0; X float slide_gamma= 1.0; X unsigned int slide_smooth= 0; X unsigned int slide_xzoom= 0; X unsigned int slide_yzoom= 0; X X if (argc < 2) X usage(argv[0]); X X /* defaults and other initial settings. some of these depend on what X * our name was when invoked. X */ X X loadPathsAndExts(); X onroot= 0; X verbose= 1; X if (!strcmp(tail(argv[0]), "xview")) { X onroot= 0; X verbose= 1; X } X else if (!strcmp(tail(argv[0]), "xsetbg")) { X onroot= 1; X verbose= 0; X } X border= NULL; X dname= NULL; X fullscreen= 0; X identify= 0; X install= 0; X slideshow= 0; X user_geometry = NULL; X winwidth= winheight= 0; X X imagecount= 0; X for (a= 0; a < MAXIMAGES; a++) { X images[a].name= NULL; X images[a].atx= images[a].aty= 0; X images[a].bright= 0; X images[a].gamma= 1.0; X images[a].center= 0; X images[a].clipx= images[a].clipy= 0; X images[a].clipw= images[a].cliph= 0; X images[a].dither= 0; X images[a].colors= 0; X images[a].rotate= 0; X images[a].fg= images[a].bg= NULL; X images[a].xzoom= images[a].yzoom= 0; X images[a].smooth= 0; X } X for (a= 1; a < argc; a++) { X switch (optionNumber(argv[a], Options)) { X case OPT_BADOPT: X printf("%s: Bad option\n", argv[a]); X usage(argv[0]); X /* NOTREACHED */ X X case OPT_NOTOPT: X if (imagecount == MAXIMAGES) X printf("%s: Too many images (ignoring)\n", argv[++a]); X else { X images[imagecount++].name= argv[a]; X if (slideshow && (imagecount < MAXIMAGES)) { X images[imagecount].bright= slide_bright; X images[imagecount].gamma= slide_gamma; X images[imagecount].dither= slide_dither; X images[imagecount].colors= slide_colors; X images[imagecount].smooth= slide_smooth; X images[imagecount].xzoom= slide_xzoom; X images[imagecount].yzoom= slide_yzoom; X } X } X break; X X case OPT_SHORTOPT: X printf("%s: Not enough characters to identify option\n", argv[a]); X usage(argv[0]); X /* NOTREACHED */ X X /* process options global to everything X */ X X case ONROOT: X onroot= 1; X break; X X case BORDER: X if (argv[++a]) X border= argv[a]; X break; X X case DISPLAY: X if (argv[++a]) X dname= argv[a]; X break; X X case FULLSCREEN: X fullscreen= 1; X break; X X case GEOMETRY: X if (argv[++a]) X user_geometry = argv[a]; X break; X X case HELP: X usage(argv[0]); X exit(0); X X case IDENTIFY: X identify= 1; X break; X X case LIST: X listImages(); X exit(0); X X case INSTALL: X install= 1; X break; X X case PATH: X showPath(); X break; X X case QUIET: X verbose= 0; X break; X X case SLIDESHOW: X slideshow= 1; X break; X X case SUPPORTED: X supportedImageTypes(); X break; X X case VERBOSE: X verbose= 1; X break; X X case VER_NUM: X printf("Xloadimage version %s patchlevel %s by Jim Frost\n", X VERSION, PATCHLEVEL); X break; X X case VIEW: X onroot= 0; X break; X X /* process options local to an image X */ X X case AT: X if (!argv[++a]) X break; X if (sscanf(argv[a], "%d,%d", X &images[imagecount].atx, &images[imagecount].aty) != 2) { X printf("Bad argument to -at\n"); X usage(argv[0]); X /* NOTREACHED */ X } X break; X X case BACKGROUND: X if (argv[++a]) X images[imagecount].bg= argv[a]; X break; X X case BRIGHT: X if (argv[++a]) { X images[imagecount].bright= atoi(argv[a]); X if (slideshow) X slide_bright= images[imagecount].bright; X } X break; X X case GAMMA: X if (argv[++a]) { X images[imagecount].gamma= atof(argv[a]); X if (slideshow) X slide_gamma= images[imagecount].gamma; X } X break; X X case CENTER: X images[imagecount].center= 1; X break; X X case CLIP: X if (!argv[++a]) X break; X if (sscanf(argv[a], "%d,%d,%d,%d", X &images[imagecount].clipx, &images[imagecount].clipy, X &images[imagecount].clipw, &images[imagecount].cliph) != 4) { X printf("Bad argument to -clip\n"); X usage(argv[0]); X /* NOTREACHED */ X } X break; X X case COLORS: X if (!argv[++a]) X break; X images[imagecount].colors= atoi(argv[a]); X if (images[imagecount].colors < 2) { X printf("Argument to -colors is too low (ignored)\n"); X images[imagecount].colors= 0; X } X else if (images[imagecount].colors > 65536) { X printf("Argument to -colors is too high (ignored)\n"); X images[imagecount].colors= 0; X } X if (slideshow) X slide_colors= images[imagecount].colors; X break; X X case DITHER: X images[imagecount].dither= 1; X if (slideshow) X slide_dither= 1; X break; X X case FOREGROUND: X if (argv[++a]) X images[imagecount].fg= argv[a]; X break; X X case HALFTONE: X images[imagecount].dither= 2; X if (slideshow) X slide_dither= 2; X break; X X case NAME: X if (imagecount == MAXIMAGES) X printf("%s: Too many images (ignoring)\n", argv[++a]); X else X images[imagecount++].name= argv[++a]; X break; X X case ROTATE: X if (!argv[++a]) X break; X images[imagecount].rotate = atoi(argv[a]); X if ((images[imagecount].rotate % 90) != 0) X { printf("Argument to -rotate must be a multiple of 90 (ignored)\n"); X images[imagecount].rotate = 0; X } X else X while (images[imagecount].rotate < 0) X images[imagecount].rotate += 360; X break; X X case SMOOTH: X if (slideshow) { X slide_smooth++; X images[imagecount].smooth= slide_smooth; X } X else X images[imagecount].smooth++; /* add a smoothing iteration */ X break; X X case XZOOM: X if (argv[++a]) { X images[imagecount].xzoom= atoi(argv[a]); X if (slideshow) X slide_xzoom= images[imagecount].xzoom; X } X break; X X case YZOOM: X if (argv[++a]) { X images[imagecount].yzoom= atoi(argv[a]); X if (slideshow) X slide_yzoom= images[imagecount].yzoom; X } X break; X X case ZOOM: X if (argv[++a]) { X images[imagecount].xzoom= images[imagecount].yzoom= atoi(argv[a]); X if (slideshow) X slide_xzoom= slide_yzoom= images[imagecount].xzoom; X } X break; X X default: X X /* this should not happen! X */ X X printf("%s: Internal error parsing arguments\n", argv[0]); X exit(1); X } X } X X if (!imagecount) /* NO-OP from here on */ X exit(0); X X if (identify) { /* identify the named image(s) */ X for (a= 0; a < imagecount; a++) X identifyImage(images[a].name); X exit(0); X } X X /* filter out mutually exclusive flags X */ X X if (onroot && slideshow) { X printf("\ X%s: -onroot and -slideshow are mutually exclusive (-onroot ignored)\n", X argv[0]); X onroot= 0; X } X X /* start talking to the display X */ X X if (! (Disp= disp= XOpenDisplay(dname))) { X printf("%s: Cannot open display\n", XDisplayName(dname)); X exit(1); X } X Scrn= scrn= DefaultScreen(disp); X#if defined(mips) || defined(_IBMR2) X XSetIOErrorHandler(ioErrorHandler); X#else X XSetIOErrorHandler((XIOErrorHandler)ioErrorHandler); X#endif X X dispimage= NULL; X X if (onroot && (winwidth || winheight || images[0].center || X images[0].atx || images[0].aty)) { X if (!winwidth) X winwidth= DisplayWidth(disp, scrn); X if (!winheight) X winheight= DisplayHeight(disp, scrn); X if (DefaultDepth(disp, scrn) == 1) X dispimage= newBitImage(winwidth, winheight); X else { X dispimage= newRGBImage(winwidth, winheight, DefaultDepth(disp, scrn)); X dispimage->rgb.used= 1; X } X *(dispimage->rgb.red)= 65535; /* default border value is white */ X *(dispimage->rgb.green)= 65535; X *(dispimage->rgb.blue)= 65535; X if (border) { X XParseColor(disp, DefaultColormap(disp, scrn), border, &xcolor); X *dispimage->rgb.red= xcolor.red; X *dispimage->rgb.green= xcolor.green; X *dispimage->rgb.blue= xcolor.blue; X } X X /* bitmap needs both black and white X */ X X if (DefaultDepth(disp, scrn) == 1) { X if (*(dispimage->rgb.red)) { X *(dispimage->rgb.red + 1)= 0; X *(dispimage->rgb.green + 1)= 0; X *(dispimage->rgb.blue + 1)= 0; X } X else { X *(dispimage->rgb.red + 1)= 65535; X *(dispimage->rgb.green + 1)= 65535; X *(dispimage->rgb.blue + 1)= 65535; X } X } X fill(dispimage, 0, 0, winwidth, winheight, 0); X } X X /* load in each named image X */ X X for (a= 0; a < imagecount; a++) { X if (! (newimage= loadImage(images[a].name, verbose))) X continue; X if (!images[a].dither && X ((dispimage && BITMAPP(dispimage)) || (DefaultDepth(disp, scrn) == 1))) X images[a].dither= 1; X newimage= processImage(disp, scrn, newimage, &images[a], verbose); X if (images[a].center && dispimage) { X images[a].atx= (int)(dispimage->width - newimage->width) / 2; X images[a].aty= (int)(dispimage->height - newimage->height) / 2; X } X if (dispimage) { X if (! dispimage->title) X dispimage->title= dupString(newimage->title); X merge(dispimage, newimage, images[a].atx, images[a].aty, verbose); X freeImage(newimage); X } X else X dispimage= newimage; X if (slideshow) { X switch(imageInWindow(disp, scrn, dispimage, user_geometry, X fullscreen, install, slideshow, argc, argv, X verbose)) { X case '\0': /* window got nuked by someone */ X XCloseDisplay(disp); X exit(1); X case '\003': X case 'q': /* user quit */ X XCloseDisplay(disp); X exit(0); X X case 'n': /* next image */ X break; X case 'p': /* previous image */ X if (a > 0) X a -= 2; X else X a--; X break; X } X freeImage(dispimage); X dispimage= NULL; X } X } X X if (!slideshow && !dispimage) { X printf("No images to display\n"); X exit(1); X } X X if (onroot) X imageOnRoot(disp, scrn, dispimage, verbose); X else { X if (!slideshow) X imageInWindow(disp, scrn, dispimage, user_geometry, X fullscreen, install, slideshow, argc, argv, verbose); X cleanUpWindow(disp); X } X XCloseDisplay(disp); X exit(0); X} END_OF_FILE if test 12257 -ne `wc -c <'xloadimage.c'`; then echo shar: \"'xloadimage.c'\" unpacked with wrong size! fi # end of 'xloadimage.c' fi if test -f 'xpixmap.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xpixmap.c'\" else echo shar: Extracting \"'xpixmap.c'\" \(5893 characters\) sed "s/^X//" >'xpixmap.c' <<'END_OF_FILE' X/* xpixmap.c: X * X * XPixMap format file read and identify routines. these can handle any X * "format 1" XPixmap file with up to BUFSIZ - 1 chars per pixel. it's X * not nearly as picky as it might be. X * X * unlike most image loading routines, this is X specific since it X * requires X color name parsing. to handle this we have global X X * variables for display and screen. it's ugly but it keeps the rest X * of the image routines clean. X * X * Copyright 1989 Jim Frost. See included file "copyright.h" for complete X * copyright information. X */ X X#include "copyright.h" X#include "xloadimage.h" X X#ifdef SYSV X#include <string.h> X#define rindex strrchr X#else Xchar *rindex(); X#endif X Xextern Display *Disp; /* X display, null if in "identify" mode */ Xextern int Scrn; /* X screen number */ X X#define XPM_FORMAT 1 X Xstatic void corrupted(fullname, zf) X char *fullname; X ZFILE *zf; X{ X zclose(zf); X printf("%s: X Pixmap file is corrupted\n", fullname); X exit(1); X} X XImage *xpixmapLoad(fullname, name, verbose) X char *fullname, *name; X unsigned int verbose; X{ ZFILE *zf; X char buf[BUFSIZ]; X char what[BUFSIZ]; X char *p; X char *imagetitle; X unsigned int value; X unsigned int format; /* image format */ X unsigned int w, h; /* image dimensions */ X unsigned int cpp; /* chars per pixel */ X unsigned int ncolors; /* number of colors */ X unsigned int depth; /* depth of image */ X char **ctable; /* color table */ X Image *image; X XColor xcolor; X unsigned int a, b, x, y; X int c; X byte *dptr; X X if (! (zf= zopen(fullname))) X return(NULL); X X /* read #defines until we have all that are necessary or until we X * get an error X */ X X format= w= h= ncolors= 0; X for (;;) { X if (! zgets(buf, BUFSIZ - 1, zf)) { X zclose(zf); X return(NULL); X } X if (!strncmp(buf, "#define", 7)) { X if (sscanf(buf, "#define %s %d", what, &value) != 2) { X zclose(zf); X return(NULL); X } X if (! (p= rindex(what, '_'))) X p= what; X else X p++; X if (!strcmp(p, "format")) X format= value; X else if (!strcmp(p, "width")) X w= value; X else if (!strcmp(p, "height")) X h= value; X else if (!strcmp(p, "ncolors")) X ncolors= value; X X /* this one is ugly X */ X X else if (!strcmp(p, "pixel")) { /* this isn't pretty but it works */ X if (p == what) X continue; X *(--p)= '\0'; X if (!(p= rindex(what, '_')) || (p == what) || strcmp(++p, "per")) X continue; X *(--p)= '\0'; X if (!(p= rindex(what, '_'))) X p= what; X if (strcmp(++p, "chars")) X continue; X cpp= value; X } X } X else if ((sscanf(buf, "static char * %s", what) == 1) && X (p= rindex(what, '_')) && !strcmp(++p, "colors[]")) X break; X } X X if ((format != XPM_FORMAT) || !w || !h || !ncolors || !cpp) { X zclose(zf); X return(NULL); X } X X if (p= rindex(what, '_')) { /* get the name in the image if there is */ X *p= '\0'; /* one */ X imagetitle= dupString(what); X } X else { X p= what; X imagetitle= dupString(name); X } X X if (verbose) X printf("%s is a %dx%d X Pixmap image with %d colors titled '%s'\n", X name, w, h, ncolors, imagetitle); X X for (depth= 1, value= 2; value < ncolors; value <<= 1, depth++) X ; X image= newRGBImage(w, h, depth); X image->rgb.used= ncolors; X image->title= dupString(imagetitle); X X /* read the colors array and build the image colormap X */ X X ctable= (char **)lmalloc(sizeof(char *) * ncolors); X xcolor.flags= DoRed | DoGreen | DoBlue; X for (a= 0; a < ncolors; a++) { X X /* read pixel value X */ X X *(ctable + a)= (char *)lmalloc(cpp); X while (((c= zgetc(zf)) != EOF) && (c != '"')) X ; X if (c == EOF) X corrupted(fullname, zf); X for (b= 0; b < cpp; b++) { X if ((c= zgetc(zf)) == '\\') X c= zgetc(zf); X if (c == EOF) X corrupted(fullname, zf); X *(*(ctable + a) + b)= (char)c; X } X if (((c= zgetc(zf)) == EOF) || (c != '"')) X corrupted(fullname, zf); X X /* read color definition and parse it X */ X X while (((c= zgetc(zf)) != EOF) && (c != '"')) X ; X if (c == EOF) X corrupted(fullname, zf); X for (b= 0; ((c= zgetc(zf)) != EOF) && (c != '"'); b++) { X if (c == '\\') X c= zgetc(zf); X if (c == EOF) X corrupted(fullname, zf); X buf[b]= (char)c; X } X buf[b]= '\0'; X X if (Disp) { X if (! XParseColor(Disp, DefaultColormap(Disp, Scrn), buf, &xcolor)) { X printf("%s: %s: Bad color name\n", fullname, buf); X exit(1); X } X *(image->rgb.red + a)= xcolor.red; X *(image->rgb.green + a)= xcolor.green; X *(image->rgb.blue + a)= xcolor.blue; X } X } X X for (;;) { X if (! zgets(buf, BUFSIZ - 1, zf)) X corrupted(fullname, zf); X if (sscanf(buf, "static char * %s", what) == 1) X break; X } X X if (p= rindex(what, '_')) X p++; X else X p= what; X if (strcmp(p, "pixels[]")) X corrupted(fullname, zf); X X /* read in image data X */ X X dptr= image->data; X for (y= 0; y < h; y++) { X while (((c= zgetc(zf)) != EOF) && (c != '"')) X ; X for (x= 0; x < w; x++) { X for (a= 0; a < cpp; a++) { X if ((c= zgetc(zf)) == '\\') X c= zgetc(zf); X if (c == EOF) X corrupted(fullname, zf); X buf[a]= (char)c; X } X for (a= 0; a < ncolors; a++) X if (!strncmp(*(ctable + a), buf, cpp)) X break; X if (a == ncolors) { /* major uncool */ X zclose(zf); X printf("%s: Pixel data doesn't match color data\n", fullname); X exit(1); X } X valToMem((unsigned long)a, dptr, image->pixlen); X dptr += image->pixlen; X } X if ((c= zgetc(zf)) != '"') X corrupted(fullname, zf); X } X zclose(zf); X return(image); X} X Xint xpixmapIdent(fullname, name) X char *fullname, *name; X{ Image *image; X X if (image= xpixmapLoad(fullname, name, (unsigned int)1)) { X freeImage(image); X return(1); X } X return(0); X} END_OF_FILE if test 5893 -ne `wc -c <'xpixmap.c'`; then echo shar: \"'xpixmap.c'\" unpacked with wrong size! fi # end of 'xpixmap.c' fi if test -f 'zoom.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'zoom.c'\" else echo shar: Extracting \"'zoom.c'\" \(4347 characters\) sed "s/^X//" >'zoom.c' <<'END_OF_FILE' X/* zoom.c: X * X * zoom an image X * X * jim frost 10.11.89 X * X * Copyright 1989 Jim Frost. See included file "copyright.h" for complete X * copyright information. X */ X X#include "copyright.h" X#include "image.h" X Xstatic unsigned int *buildIndex(width, zoom, rwidth) X unsigned int width; X unsigned int zoom; X unsigned int *rwidth; X{ float fzoom; X unsigned int *index; X unsigned int a; X X if (!zoom) { X fzoom= 100.0; X *rwidth= width; X } X else { X fzoom= (float)zoom / 100.0; X *rwidth= fzoom * width; X } X index= (unsigned int *)lmalloc(sizeof(unsigned int) * *rwidth); X for (a= 0; a < *rwidth; a++) X if (zoom) X *(index + a)= (float)a / fzoom; X else X *(index + a)= a; X return(index); X} X XImage *zoom(oimage, xzoom, yzoom, verbose) X Image *oimage; X unsigned int xzoom, yzoom; X{ char buf[BUFSIZ]; X Image *image; X unsigned int *xindex, *yindex; X unsigned int xwidth, ywidth; X unsigned int x, y, xsrc, ysrc; X unsigned int pixlen; X unsigned int srclinelen; X unsigned int destlinelen; X byte *srcline, *srcptr; X byte *destline, *destptr; X byte srcmask, destmask, bit; X Pixel value; X X goodImage(oimage, "zoom"); X X if (!xzoom && !yzoom) /* stupid user */ X return(NULL); X X if (!xzoom) { X if (verbose) X printf(" Zooming image Y axis by %d%%...", yzoom); X sprintf(buf, "%s (Y zoom %d%%)", oimage->title, yzoom); X } X else if (!yzoom) { X if (verbose) X printf(" Zooming image X axis by %d%%...", xzoom); X sprintf(buf, "%s (X zoom %d%%)", oimage->title, xzoom); X } X else if (xzoom == yzoom) { X if (verbose) X printf(" Zooming image by %d%%...", xzoom); X sprintf(buf, "%s (%d%% zoom)", oimage->title, xzoom); X } X else { X if (verbose) X printf(" Zooming image X axis by %d%% and Y axis by %d%%...", X xzoom, yzoom); X sprintf(buf, "%s (X zoom %d%% Y zoom %d%%)", oimage->title, X xzoom, yzoom); X } X if (verbose) X fflush(stdout); X X xindex= buildIndex(oimage->width, xzoom, &xwidth); X yindex= buildIndex(oimage->height, yzoom, &ywidth); X X switch (oimage->type) { X case IBITMAP: X image= newBitImage(xwidth, ywidth); X for (x= 0; x < oimage->rgb.used; x++) { X *(image->rgb.red + x)= *(oimage->rgb.red + x); X *(image->rgb.green + x)= *(oimage->rgb.green + x); X *(image->rgb.blue + x)= *(oimage->rgb.blue + x); X } X image->rgb.used= oimage->rgb.used; X destline= image->data; X destlinelen= (xwidth / 8) + (xwidth % 8 ? 1 : 0); X srcline= oimage->data; X srclinelen= (oimage->width / 8) + (oimage->width % 8 ? 1 : 0); X for (y= 0, ysrc= *(yindex + y); y < ywidth; y++) { X while (ysrc != *(yindex + y)) { X ysrc++; X srcline += srclinelen; X } X srcptr= srcline; X destptr= destline; X srcmask= 0x80; X destmask= 0x80; X bit= srcmask & *srcptr; X for (x= 0, xsrc= *(xindex + x); x < xwidth; x++) { X if (xsrc != *(xindex + x)) { X do { X xsrc++; X if (!(srcmask >>= 1)) { X srcmask= 0x80; X srcptr++; X } X } while (xsrc != *(xindex + x)); X bit= srcmask & *srcptr; X } X if (bit) X *destptr |= destmask; X if (!(destmask >>= 1)) { X destmask= 0x80; X destptr++; X } X } X destline += destlinelen; X } X break; X X case IRGB: X image= newRGBImage(xwidth, ywidth, oimage->depth); X for (x= 0; x < oimage->rgb.used; x++) { X *(image->rgb.red + x)= *(oimage->rgb.red + x); X *(image->rgb.green + x)= *(oimage->rgb.green + x); X *(image->rgb.blue + x)= *(oimage->rgb.blue + x); X } X image->rgb.used= oimage->rgb.used; X pixlen= oimage->pixlen; X destptr= image->data; X srcline= oimage->data; X srclinelen= oimage->width * pixlen; X for (y= 0, ysrc= *(yindex + y); y < ywidth; y++) { X while (ysrc != *(yindex + y)) { X ysrc++; X srcline += srclinelen; X } X X srcptr= srcline; X value= memToVal(srcptr, pixlen); X for (x= 0, xsrc= *(xindex + x); x < xwidth; x++) { X if (xsrc != *(xindex + x)) { X do { X xsrc++; X srcptr += image->pixlen; X } while (xsrc != *(xindex + x)); X value= memToVal(srcptr, pixlen); X } X valToMem(value, destptr++, pixlen); X } X } X break; X } X X image->title= dupString(buf); X lfree((byte *)xindex); X lfree((byte *)yindex); X if (verbose) X printf("done\n"); X return(image); X} END_OF_FILE if test 4347 -ne `wc -c <'zoom.c'`; then echo shar: \"'zoom.c'\" unpacked with wrong size! fi # end of 'zoom.c' fi echo shar: End of archive 8 \(of 9\). cp /dev/null ark8isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 9 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 dan ---------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com Opinions expressed reflect those of the author only.