v09i055: xloadimage, Part08/09
saber.com!jimf at saber.com
saber.com!jimf at saber.com
Fri Sep 28 11:56:07 AEST 1990
Submitted-by: saber.com!jimf at 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 at 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 at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.
More information about the Comp.sources.x
mailing list