xv.c000644 002300 001754 00000214115 05233500565 012347 0ustar00sampurehons000000 000000 /* * xv.c - main section of xv. X setup, window creation, etc. * * Author: John Bradley, University of Pennsylvania * (bradley@cis.upenn.edu) * * Modified for VMS by: * David Jones, the Ohio State University * (jonesd@kcgl1.eng.ohio-state.edu) * and Rick Dyson, the University of Iowa * (dyson@IowaSP.Physics.UIowa.EDU) * * Modified: Sam Yates (syates@spam.maths.adelaide.edu.au) * Jul 92 to extend root image positioning options * * Contains: * int main(argc,argv) * static void Syntax() * static int openPic(filenum) * static void closePic() * static void OpenFirstPic() * static void OpenNextPic() * static void OpenNextQuit() * static void OpenNextLoop() * static void OpenPrevPic() * static void OpenNamedPic() * static void MainLoop() * static void CreateMainWindow(geom, name) * void FixAspect(grow, w, h) * static void MakeDispNames() * static void stickInList(); * void DeleteCmd(); * int rd_int(name) * int rd_str(name) * int rd_str_cl(name_str, class_str) * int rd_flag(name) */ /* * Copyright 1989, 1990, 1991, 1992 by John Bradley and * 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 expressed or implied warranty. * * The author may be contacted via: * US Mail: John Bradley * GRASP Lab, Room 301C * 3401 Walnut St. * Philadelphia, PA 19104 * * Phone: (215) 898-8813 * EMail: bradley@cis.upenn.edu */ #define MAIN #define NEEDSTIME #define NEEDSDIR /* for value of MAXPATHLEN */ #include "xv.h" #include "bitmaps.h" #include "sunras.h" #include #ifdef VMS extern Window pseudo_root(); #endif /* program needs one of the following fonts. Trys them in ascending order */ #define FONT1 "-*-lucida-medium-r-*-*-12-*" #define FONT2 "-*-helvetica-medium-r-*-*-12-*" #define FONT3 "-*-helvetica-medium-r-*-*-11-*" #define FONT4 "6x13" #define FONT5 "fixed" /* a mono-spaced font needed for the 'pixel value tracking' feature */ #define MFONT1 "-misc-fixed-medium-r-normal-*-13-*" #define MFONT2 "6x13" #define MFONT3 "-*-courier-medium-r-*-*-12-*" #define MFONT4 "fixed" /* file types that can be read */ #define UNKNOWN 0 #define GIF 1 #define PM 2 #define PBM 3 #define XBM 4 #define SUNRAS 5 #define UTAHRLE 6 #define XPM 7 #ifdef HAVE_JPEG # define JFIF 8 #endif #ifdef HAVE_TIFF # ifdef HAVE_JPEG # define TIFF 9 # else # define TIFF 8 # endif #endif #ifdef HAVE_PDS # if (defined(HAVE_TIFF) && defined(HAVE_JPEG)) # define PDSVICAR 10 # else # if (defined(HAVE_TIFF) || defined(HAVE_JPEG)) # define PDSVICAR 9 # else # define PDSVICAR 8 # endif # endif #endif /* yech! */ static int revvideo = 0; /* true if we should reverse video */ static int dfltkludge = 0; /* true if we're viewing dfltpic */ static int keeparound = 1; /* if true, don't quit after del. last image */ static int autoquit = 0; /* quit after loading first pic to rootW */ static int autosmooth = 0; /* smooth picture upon loading */ static int autodither = 0; /* colordither picture upon loading */ static int autocrop = 0; /* autocrop picture upon loading */ static int clearonload; /* clear window/root (on colormap visuals) */ static float expand = 1.0; /* '-expand' argument */ static char *maingeom = NULL; static char initpath[MAXPATHLEN]; static Atom __SWM_VROOT = None; /* used in DeleteCmd() */ static char **mainargv; static int mainargc; /* local function pre-definitions */ #ifdef __STDC__ static void Syntax(void); static void RmodeSyntax(void); static int openPic(int); static int readpipe(char *, char *); static void closePic(void); static void OpenFirstPic(void); static void OpenNextPic(void); static void OpenNextQuit(void); static void OpenNextLoop(void); static void OpenPrevPic(void); static void OpenNamedPic(void); static void MainLoop(void); static void CreateMainWindow(char *, char *); static void smoothResize(int, int); static void MakeDispNames(void); static void stickInList(void); static int argcmp(char *, char *, int); #else static void Syntax(), RmodeSyntax(), closePic(), OpenFirstPic(), OpenNextPic(); static void OpenNextQuit(), OpenNextLoop(), OpenPrevPic(), OpenNamedPic(); static void MainLoop(), CreateMainWindow(), MakeDispNames(), stickInList(); static int openPic(), argcmp(), readpipe(); static void smoothResize(); #endif /*******************************************/ int main(argc, argv) int argc; char *argv[]; /*******************************************/ { int i, imap, ctrlmap, gmap, clrroot, nopos, limit2x; char *display, *whitestr, *blackstr, *histr, *lostr, *infogeom, *fgstr, *bgstr, *ctrlgeom, *gamgeom; char *rootfgstr, *rootbgstr, *visualstr; int curstype, stdinflag, browseMode, savenorm, preview, pscomp; XColor ecdef; Window rootReturn, parentReturn, *children; unsigned int numChildren; #ifdef VMS /* convert VMS-style arguments to unix names and glob */ do_vms_wildcard(&argc, &argv); getredirection(&argc, &argv); #endif /*****************************************************/ /*** variable Initialization ***/ /*****************************************************/ GETWD(initpath); mainargv = argv; mainargc = argc; /* init internal variables */ display = NULL; fgstr = bgstr = rootfgstr = rootbgstr = NULL; histr = lostr = whitestr = blackstr = NULL; visualstr = NULL; pic = epic = cpic = NULL; theImage = NULL; LocalCmap = 0; stdinflag = 0; autoclose = 1; cmapInGam = 1; cmapinstalled = showzoomcursor = 0; /* init default colors */ fgstr = "#000000"; bgstr = "#B2C0DC"; histr = "#C6D5E2"; lostr = "#8B99B5"; cmd = rindex(argv[0],'/'); if (!cmd) cmd = argv[0]; else cmd++; tmpdir = (char *) getenv("TMPDIR"); if (!tmpdir) tmpdir = "/tmp"; /* init command-line options flags */ infogeom = DEFINFOGEOM; ctrlgeom = DEFCTRLGEOM; gamgeom = DEFGAMGEOM; ncols = -1; noglob = 0; mono = 0; perfect = 0; ninstall = 0; fixedaspect = 0; DEBUG = 0; bwidth = 2; nolimits = useroot = clrroot = noqcheck = rwcolor = owncmap = 0; waitsec = -1; waitloop = 0; automax = 0; rootMode = 0; hsvmode = 0; nopos = limit2x = 0; resetroot = 1; clearonload = 0; curstype = XC_crosshair; browseMode = savenorm = nostat = 0; preview = 0; pscomp = 0; conv24 = CONV24_SLOW; /* use 'slow' algorithm by default */ defaspect = normaspect = 1.0; mainW = dirW = infoW = ctrlW = gamW = psW = (Window) NULL; #ifdef HAVE_JPEG jpegW = (Window) NULL; #endif #ifdef HAVE_TIFF tiffW = (Window) NULL; #endif imap = ctrlmap = gmap = 0; ch_offx = ch_offy = p_offx = p_offy = 0; /* init info box variables */ infoUp = 0; infoMode = INF_STR; for (i=0; i=0) noglob = 1; } if (rd_flag("nglobal")) noglob = def_int; if (rd_flag("ninstall")) ninstall = def_int; if (rd_flag("nolimits")) nolimits = def_int; if (rd_flag("nopos")) nopos = def_int; if (rd_flag("noqcheck")) noqcheck = def_int; if (rd_flag("nostat")) nostat = def_int; if (rd_flag("ownCmap")) owncmap = def_int; if (rd_flag("perfect")) perfect = def_int; if (rd_flag("pscompress")) pscomp = def_int; if (rd_flag("pspreview")) preview = def_int; if (rd_flag("quick24") && def_int) conv24 = CONV24_FAST; if (rd_flag("resetroot")) resetroot = def_int; if (rd_flag("reverse")) revvideo = def_int; if (rd_str ("rootBackground")) rootbgstr = def_str; if (rd_str ("rootForeground")) rootfgstr = def_str; if (rd_int ("rootMode")) rootMode = def_int; if (rd_flag("rwColor")) rwcolor = def_int; if (rd_flag("saveNormal")) savenorm = def_int; if (rd_str ("visual")) visualstr = def_str; if (rd_str ("white")) whitestr = def_str; /*****************************************************/ /*** Command Line Options ***/ /*****************************************************/ for (i=1, numnames=0; i8 conversion */ conv24 = CONV24_BEST; else if (!argcmp(argv[i],"-bg",3)) /* background color */ { if (++i RM_MAX) RmodeSyntax(); if (DEBUG) XSynchronize(theDisp, True); /* if using root, generally gotta map ctrl window, 'cause there won't be any way to ask for it. (no kbd or mouse events from rootW) */ if (useroot && !autoquit) ctrlmap = -1; /* must not install colormaps on rootW */ if (useroot) { owncmap = perfect=0; noglob = 1; } if (owncmap) perfect = 1; if (nopos) { maingeom = infogeom = ctrlgeom = gamgeom = NULL; } /* if -root and -maxp, make sure we're using a 'centered' mode */ if (useroot && fixedaspect && automax && rootMode < RM_CENTER) rootMode = RM_CSOLID; /*****************************************************/ /*** X Setup ***/ /*****************************************************/ theScreen = DefaultScreen(theDisp); theCmap = DefaultColormap(theDisp, theScreen); rootW = RootWindow(theDisp,theScreen); theGC = DefaultGC(theDisp,theScreen); theVisual = DefaultVisual(theDisp,theScreen); ncells = DisplayCells(theDisp, theScreen); dispDEEP = DisplayPlanes(theDisp,theScreen); vrWIDE = dispWIDE = DisplayWidth(theDisp,theScreen); vrHIGH = dispHIGH = DisplayHeight(theDisp,theScreen); maxWIDE = dispWIDE; maxHIGH = dispHIGH; if (visualstr) { /* handle non-default visual */ int vclass = -1; lower_str(visualstr); if (!strcmp(visualstr,"staticgray")) vclass = StaticGray; else if (!strcmp(visualstr,"staticcolor")) vclass = StaticColor; else if (!strcmp(visualstr,"truecolor")) vclass = TrueColor; else if (!strcmp(visualstr,"grayscale")) vclass = GrayScale; else if (!strcmp(visualstr,"pseudocolor")) vclass = PseudoColor; else if (!strcmp(visualstr,"directcolor")) vclass = DirectColor; else { fprintf(stderr,"%s: Unrecognized visual type '%s'. %s\n", cmd, visualstr, "Using server default."); } if (vclass >= 0) { /* try to find asked-for visual type */ XVisualInfo *vinfo, rvinfo; int numvis, best; rvinfo.class = vclass; vinfo = XGetVisualInfo(theDisp, VisualClassMask, &rvinfo, &numvis); if (vinfo) { /* choose the 'best' one, if multiple */ for (i=0, best=0; i vinfo[best].depth) best = i; } theVisual = vinfo[best].visual; if (DEBUG) { fprintf(stderr,"%s: using %s visual, depth = %d, screen = %d\n", cmd, visualstr, vinfo[best].depth, vinfo[best].screen); fprintf(stderr,"\tmasks: (0x%x,0x%x,0x%x), bits_per_rgb=%d\n", vinfo[best].red_mask, vinfo[best].green_mask, vinfo[best].blue_mask, vinfo[best].bits_per_rgb); } dispDEEP = vinfo[best].depth; theScreen = vinfo[best].screen; rootW = RootWindow(theDisp, theScreen); ncells = vinfo[best].colormap_size; theGC = DefaultGC(theDisp, theScreen); vrWIDE = dispWIDE = DisplayWidth(theDisp,theScreen); vrHIGH = dispHIGH = DisplayHeight(theDisp,theScreen); maxWIDE = dispWIDE; maxHIGH = dispHIGH; theCmap = XCreateColormap(theDisp, rootW, theVisual, AllocNone); #ifdef FOO theCmap = DefaultColormap(theDisp, theScreen); #endif XFree((char *) vinfo); } else fprintf(stderr,"%s: Visual type '%s' not available. %s\n", cmd, visualstr, "Using server default."); } } if (!useroot && limit2x) { maxWIDE *= 2; maxHIGH *= 2; } if (nolimits) { maxWIDE = 65000; maxHIGH = 65000; } XSetErrorHandler(xvErrorHandler); /* always search for virtual root window */ vrootW = rootW; #ifndef VMS __SWM_VROOT = XInternAtom(theDisp, "__SWM_VROOT", False); XQueryTree(theDisp, rootW, &rootReturn, &parentReturn, &children, &numChildren); for (i = 0; i < numChildren; i++) { Atom actual_type; int actual_format; unsigned long nitems, bytesafter; Window *newRoot = NULL; XWindowAttributes xwa; if (XGetWindowProperty (theDisp, children[i], __SWM_VROOT, 0, 1, False, XA_WINDOW, &actual_type, &actual_format, &nitems, &bytesafter, (unsigned char **) &newRoot) == Success && newRoot) { vrootW = *newRoot; XGetWindowAttributes(theDisp, vrootW, &xwa); vrWIDE = xwa.width; vrHIGH = xwa.height; dispDEEP = xwa.depth; break; } } #else /* VMS */ vrootW = pseudo_root(theDisp, theScreen); #endif if (clrroot || useroot) { /* have enough info to do a '-clear' now */ KillOldRootInfo(); /* if any */ if (resetroot || clrroot) ClearRoot(); /* don't clear on '-noresetroot' */ if (clrroot) Quit(0); } arrow = XCreateFontCursor(theDisp,XC_top_left_arrow); cross = XCreateFontCursor(theDisp,curstype); tcross = XCreateFontCursor(theDisp,XC_tcross); zoom = XCreateFontCursor(theDisp,XC_sizing); { XColor fc, bc; fc.red = fc.green = fc.blue = 0xffff; bc.red = bc.green = bc.blue = 0x0000; XRecolorCursor(theDisp, zoom, &fc, &bc); } { /* create invisible cursor */ Pixmap pix; static char bits[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; XColor col; col.red = col.green = col.blue = 0; pix = XCreateBitmapFromData(theDisp, rootW, bits, 8, 8); inviso = XCreatePixmapCursor(theDisp, pix, pix, &col, &col, 0,0); XFreePixmap(theDisp, pix); } /* set up white,black colors */ white = WhitePixel(theDisp,theScreen); whtRGB = 0xffffff; black = BlackPixel(theDisp,theScreen); blkRGB = 0x000000; if (whitestr && XParseColor(theDisp, theCmap, whitestr, &ecdef) && xvAllocColor(theDisp, theCmap, &ecdef)) { white = ecdef.pixel; whtRGB = ((ecdef.red>>8)<<16) | (ecdef.green&0xff00) | (ecdef.blue>>8); } if (blackstr && XParseColor(theDisp, theCmap, blackstr, &ecdef) && xvAllocColor(theDisp, theCmap, &ecdef)) { black = ecdef.pixel; blkRGB = ((ecdef.red>>8)<<16) | (ecdef.green&0xff00) | (ecdef.blue>>8); } /* set up fg,bg colors */ fg = black; bg = white; if (fgstr && XParseColor(theDisp, theCmap, fgstr, &ecdef) && xvAllocColor(theDisp, theCmap, &ecdef)) { fg = ecdef.pixel; } if (bgstr && XParseColor(theDisp, theCmap, bgstr, &ecdef) && xvAllocColor(theDisp, theCmap, &ecdef)) { bg = ecdef.pixel; } /* set up root fg,bg colors */ rootfg = white; rootbg = black; if (rootfgstr && XParseColor(theDisp, theCmap, rootfgstr, &ecdef) && xvAllocColor(theDisp, theCmap, &ecdef)) rootfg = ecdef.pixel; if (rootbgstr && XParseColor(theDisp, theCmap, rootbgstr, &ecdef) && xvAllocColor(theDisp, theCmap, &ecdef)) rootbg = ecdef.pixel; /* set up hi/lo colors */ i=0; if (dispDEEP > 1) { /* only if we're on a reasonable display */ if (histr && XParseColor(theDisp, theCmap, histr, &ecdef) && xvAllocColor(theDisp, theCmap, &ecdef)) { hicol = ecdef.pixel; i|=1; } if (lostr && XParseColor(theDisp, theCmap, lostr, &ecdef) && xvAllocColor(theDisp, theCmap, &ecdef)) { locol = ecdef.pixel; i|=2; } } if (i==0) ctrlColor = 0; else if (i==3) ctrlColor = 1; else { /* only got some of them */ if (i&1) xvFreeColors(theDisp, theCmap, &hicol, 1, 0L); if (i&2) xvFreeColors(theDisp, theCmap, &locol, 1, 0L); ctrlColor = 0; } XSetForeground(theDisp,theGC,fg); XSetBackground(theDisp,theGC,bg); infofg = fg; infobg = bg; /* if '-mono' not forced, determine if we're on a grey or color monitor */ if (!mono) { if (DEBUG) fprintf(stderr,"%s: VisualClass = %d\n",cmd, theVisual->class); if (theVisual->class == StaticGray || theVisual->class == GrayScale) mono = 1; } iconPix = XCreatePixmapFromBitmapData(theDisp, rootW, icon_bits, icon_width, icon_height, 1, 0, 1); iconmask = XCreatePixmapFromBitmapData(theDisp, rootW, iconmask_bits, icon_width, icon_height, 1, 0, 1); /* try to load fonts */ if ( (mfinfo = XLoadQueryFont(theDisp,FONT1))==NULL && (mfinfo = XLoadQueryFont(theDisp,FONT2))==NULL && (mfinfo = XLoadQueryFont(theDisp,FONT3))==NULL && (mfinfo = XLoadQueryFont(theDisp,FONT4))==NULL && (mfinfo = XLoadQueryFont(theDisp,FONT5))==NULL) { sprintf(str, "couldn't open the following fonts:\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s", FONT1, FONT2, FONT3, FONT4, FONT5); FatalError(str); } mfont=mfinfo->fid; XSetFont(theDisp,theGC,mfont); if ( (monofinfo = XLoadQueryFont(theDisp,MFONT1))==NULL && (monofinfo = XLoadQueryFont(theDisp,MFONT2))==NULL && (monofinfo = XLoadQueryFont(theDisp,MFONT3))==NULL && (monofinfo = XLoadQueryFont(theDisp,MFONT4))==NULL) { sprintf(str,"couldn't open the following fonts:\n\t%s\n\t%s\n\t%s\n\t%s", MFONT1, MFONT2, MFONT3, MFONT4); FatalError(str); } monofont=monofinfo->fid; /* if ncols wasn't set, set it to 2^dispDEEP, unless dispDEEP=1, in which case ncols = 0; (ncols = max number of colors allocated. on 1-bit displays, no colors are allocated */ if (ncols == -1) { if (dispDEEP>1) ncols = 1 << ((dispDEEP>8) ? 8 : dispDEEP); else ncols = 0; } else if (ncols>256) ncols = 256; /* so program doesn't blow up */ /* no filenames. build one-name (stdio) list (if stdinflag) */ if (numnames==0) { if (stdinflag) { namelist[0] = STDINSTR; numnames = 1; } else { namelist[0] = NULL; numnames = 0; } } if (numnames) MakeDispNames(); /* create the info box window */ CreateInfo(infogeom); XSelectInput(theDisp, infoW, ExposureMask | ButtonPressMask | KeyPressMask | StructureNotifyMask); InfoBox(imap); /* map it (or not) */ if (imap) { RedrawInfo(0,0,INFOWIDE,INFOHIGH); /* explicit draw if mapped */ XFlush(theDisp); } /* create the control box window */ CreateCtrl(ctrlgeom); epicmode = EM_RAW; SetEpicMode(); XSelectInput(theDisp, ctrlW, ExposureMask | ButtonPressMask | KeyPressMask | StructureNotifyMask); if (ctrlmap < 0) { /* map iconified */ XWMHints xwmh; xwmh.initial_state = IconicState; xwmh.flags = StateHint; XSetWMHints(theDisp, ctrlW, &xwmh); ctrlmap = 1; } CtrlBox(ctrlmap); /* map it (or not) */ if (ctrlmap) { RedrawCtrl(0,0,CTRLWIDE,CTRLHIGH); /* explicit draw if mapped */ XFlush(theDisp); } /* create the directory window */ CreateDirW(NULL); XSelectInput(theDisp, dirW, ExposureMask | ButtonPressMask | KeyPressMask); browseCB.val = browseMode; savenormCB.val = savenorm; /* create the gamma window */ CreateGam(gamgeom); XSelectInput(theDisp, gamW, ExposureMask | ButtonPressMask | KeyPressMask | StructureNotifyMask | (cmapInGam ? ColormapChangeMask : 0)); GamBox(gmap); /* map it (or not) */ /* create the ps window */ CreatePSD(NULL); encapsCB.val = preview; pscompCB.val = pscomp; #ifdef HAVE_JPEG CreateJPEGW(); #endif #ifdef HAVE_TIFF CreateTIFFW(); #endif GenerateFSGamma(); LoadFishCursors(); SetCursors(-1); /* if we're not on a colormapped display, turn off rwcolor */ if (theVisual->class != PseudoColor && theVisual->class != GrayScale && rwcolor) { fprintf(stderr,"xv: not a colormapped display. 'rwcolor' turned off.\n"); rwcolor = 0; } XSelectInput(theDisp, rootW, ColormapChangeMask); /* Do The Thing... */ MainLoop(); Quit(0); return(0); } /***********************************/ static int cpos = 0; void printoption(st) char *st; { if (strlen(st) + cpos > 78) { fprintf(stderr,"\n "); cpos = 3; } fprintf(stderr,"%s ",st); cpos = cpos + strlen(st) + 1; } static void Syntax() { fprintf(stderr, "Usage:\n"); printoption(cmd); printoption("[-]"); printoption("[-2xlimit]"); printoption("[-aspect w:h]"); printoption("[-best24]"); printoption("[-bg color]"); printoption("[-black color]"); printoption("[-browse]"); printoption("[-bw width]"); printoption("[-cecmap]"); printoption("[-cegeometry geom]"); printoption("[-cemap]"); printoption("[-cgeometry geom]"); printoption("[-clear]"); printoption("[-close]"); printoption("[-cmap]"); printoption("[-crop]"); printoption("[-cursor char#]"); printoption("[-DEBUG level]"); printoption("[-display disp]"); printoption("[-dither]"); printoption("[-expand exp]"); printoption("[-fg color]"); printoption("[-fixed]"); printoption("[-geometry geom]"); printoption("[-help]"); printoption("[-hi color]"); printoption("[-hsv]"); printoption("[-igeometry geom]"); printoption("[-imap]"); printoption("[-keeparound]"); printoption("[-lo color]"); printoption("[-loadclear]"); printoption("[-max]"); printoption("[-maxpect]"); printoption("[-mono]"); printoption("[-ncols #]"); printoption("[-nglobal]"); printoption("[-ninstall]"); printoption("[-nolimits]"); printoption("[-nopos]"); printoption("[-noqcheck]"); printoption("[-noresetroot]"); printoption("[-nostat]"); printoption("[-owncmap]"); printoption("[-perfect]"); printoption("[-quick24]"); printoption("[-quit]"); printoption("[-rbg color]"); printoption("[-rfg color]"); printoption("[-rgb]"); printoption("[-rmode #]"); printoption("[-root]"); printoption("[-rv]"); printoption("[-rw]"); printoption("[-slow24]"); printoption("[-smooth]"); printoption("[-visual type]"); printoption("[-wait seconds]"); printoption("[-white color]"); printoption("[-wloop]"); printoption("[filename ...]"); fprintf(stderr,"\n\n"); Quit(1); } /***********************************/ static void RmodeSyntax() { fprintf(stderr,"%s: unknown root mode '%d'. Valid modes are:\n", cmd, rootMode); fprintf(stderr,"\t 0: tiling\n"); fprintf(stderr,"\t 1: integer tiling\n"); fprintf(stderr,"\t 2: mirrored tiling\n"); fprintf(stderr,"\t 3: integer mirrored tiling\n"); fprintf(stderr,"\t 4: centered tiling\n"); fprintf(stderr,"\t 5: centered on a solid background\n"); fprintf(stderr,"\t 6: centered on a 'warp' background\n"); fprintf(stderr,"\t 7: centered on a 'brick' background\n"); fprintf(stderr,"\t 8: centered left on a solid background\n"); fprintf(stderr,"\t 9: centered right on a solid background\n"); fprintf(stderr,"\t10: centered top on a solid background\n"); fprintf(stderr,"\t11: centered bottom on a solid background\n"); fprintf(stderr,"\t12: at geometry on a solid background\n"); fprintf(stderr,"\n"); Quit(1); } /***********************************/ static int argcmp(a1, a2, minlen) char *a1, *a2; int minlen; { /* does a string compare between a1 and a2. To return '0', a1 and a2 must match to the length of a2, and that length has to be at least 'minlen'. Otherwise, return non-zero */ if (strlen(a1) < minlen || strlen(a2) < minlen) return 1; if (strlen(a1) > strlen(a2)) return 1; return (strncmp(a1, a2, strlen(a1))); } /***********************************/ static int openPic(filenum) int filenum; { /* tries to load file #filenum (from 'namelist' list) * returns 0 on failure (cleans up after itself) * if successful, returns 1, creates mainW * * By the way, I'd just like to point out that this procedure has gotten * *way* out of hand... */ int i,filetype,freename, nw, nh, frompipe; int oldeWIDE, oldeHIGH; char *tmp; FILE *fp; char *fullname, /* full name of the original file */ filename[256], /* full name of the file to be loaded (could be /tmp) */ globnm[512]; /* globbed version of fullname of orig file */ byte magicno[8]; /* first 8 bytes of file */ normaspect = defaspect; freename = dfltkludge = frompipe = 0; oldeWIDE = eWIDE; oldeHIGH = eHIGH; WaitCursor(); if (filenum == DFLTPIC) { filename[0] = '\0'; basefname[0] = '\0'; fullname = ""; dfltkludge = 1; LoadDfltPic(); goto GOTIMAGE; } if (filenum == GRABBED) { filename[0] = '\0'; basefname[0] = '\0'; fullname = ""; LoadGrab(); goto GOTIMAGE; } if (filenum != LOADPIC) { if (filenum >= nList.nstr && filenum < 0) goto FAILED; curname = filenum; nList.selected = curname; ScrollToCurrent(&nList); /* have scrl/list show current */ XFlush(theDisp); /* update NOW */ } /* clear any old error messages */ formatStr[0] = '\0'; SetISTR(ISTR_INFO,""); SetISTR(ISTR_WARNING,""); infoMode = INF_STR; /* set up fullname and basefname */ if (filenum == LOADPIC) { fullname = GetDirFName(); if (fullname[0] == '~') { strcpy(globnm, fullname); Globify(globnm); fullname = globnm; } else if (ISPIPE(fullname[0])) { /* read from a pipe. */ strcpy(filename, fullname); if (readpipe(fullname, filename)) goto FAILED; frompipe = 1; } } else fullname = namelist[filenum]; /* compute basefname */ tmp = rindex(fullname,'/'); if (!tmp) tmp = fullname; else tmp++; strcpy(basefname,tmp); if (filenum == LOADPIC && ISPIPE(fullname[0])) { /* if we're reading from a pipe, 'filename' will have the /tmp/xvXXXXXX filename, and we can skip a lot of stuff: (such as dealing with compressed files, prepending 'initpath' to relative paths, dealing with reading from stdin */ /* at this point, fullname = "! do some commands", filename = "/tmp/xv123456", and basefname= "xv123456" */ } else { #ifndef VMS if (strlen(basefname)>2 && strcmp(basefname+strlen(basefname)-2,".Z")==0) basefname[strlen(basefname)-2]='\0'; /* chop off .Z, if any */ #endif /* if fullname doesn't start with a '/' (ie, it's a relative path), (and it's not LOADPIC and it's not the special case '') prepend 'initpath' to it */ if (filenum != LOADPIC && fullname[0] != '/' && strcmp(fullname,STDINSTR)!=0) { char *tmp; #ifndef VMS tmp = (char *) malloc(strlen(fullname) + strlen(initpath) + 2); if (!tmp) FatalError("malloc 'filename' failed"); sprintf(tmp,"%s/%s", initpath, fullname); #else /* it is VMS */ tmp = (char *) malloc(strlen(fullname) + 2); if (!tmp) FatalError("malloc 'filename' failed"); sprintf(tmp,"%s", fullname); #endif fullname = tmp; freename = 1; } /* uncompress if it's a .Z file */ i = strlen(fullname); #ifndef VMS if (i>2 && strcmp(fullname+i-2,".Z")==0) { sprintf(filename,"%s/xvXXXXXX",tmpdir); mktemp(filename); sprintf(str,"%s -c %s >%s",UNCOMPRESS,fullname,filename); SetISTR(ISTR_INFO,"Uncompressing '%s'...",basefname); if (system(str)) { SetISTR(ISTR_INFO,"Unable to uncompress '%s'.", basefname); Warning(); goto FAILED; } WaitCursor(); } else strcpy(filename,fullname); #else /* it is VMS */ tmp = strstr(basefname,".Z"); if (!tmp) tmp = strstr(basefname,".z"); #ifdef HAVE_LZW if (!tmp) tmp = strstr(basefname,"_Z"); if (!tmp) tmp = strstr(basefname,"_z"); #else if (tmp) *tmp = '\0'; #endif if (i>2 && tmp) { strcpy(filename,"Sys$Disk:[]xvXXXXXX"); mktemp(filename); #ifdef HAVE_LZW sprintf(str,"%s %s %s", UNCOMPRESS, basefname, filename); #else sprintf(str,"%s %s", UNCOMPRESS, basefname); #endif if (!system(str)) { SetISTR(ISTR_INFO,"Unable to uncompress '%s'.", basefname); Warning(); goto FAILED; } #ifndef HAVE_LZW sprintf(str,"Rename %s %s", basefname, filename); SetISTR(ISTR_INFO,"Renaming '%s'...",fullname); if (!system(str)) { SetISTR(ISTR_INFO,"Unable to rename '%s'.", fullname); Warning(); goto FAILED; } #endif /* HAVE_LZW */ WaitCursor(); } else strcpy(filename,fullname); #endif /* not VMS */ /* if the file is stdio, write it out to a temp file */ if (strcmp(filename,STDINSTR)==0) { FILE *fp; #ifndef VMS sprintf(filename,"%s/xvXXXXXX",tmpdir); #else /* it is VMS */ sprintf(filename, "Sys$Disk:[]xvXXXXXX"); #endif mktemp(filename); fp = fopen(filename,"w"); if (!fp) FatalError("openPic(): can't write temporary file"); while ( (i=getchar()) != EOF) putc(i,fp); fclose(fp); } } /* now, try to determine what type of file we've got by reading the first couple bytes and looking for a Magic Number */ #ifndef VMS fp=fopen(filename,"r"); #else /* it is VMS */ /* Open with optional arguments to force stream access in order to get around problems with stream_CR created by pathworks (mac) */ fp=fopen (filename,"rb","ctx=stm"); #endif if (!fp) { static char *foo[] = { "\nBummer!" }; char str[512]; sprintf(str,"Can't open file '%s'\n\n %s.",filename, #ifndef VMS sys_errlist[errno] #else strerror(errno, vaxc$errno) #endif ); PopUp(str, foo, 1); goto FAILED; } fread(magicno,8,1,fp); fclose(fp); filetype = UNKNOWN; if (strncmp((char *) magicno,"GIF87a",6)==0 || strncmp((char *) magicno,"GIF89a",6)==0) filetype = GIF; else if (strncmp((char *) magicno,"VIEW",4)==0 || strncmp((char *) magicno,"WEIV",4)==0) filetype = PM; else if (magicno[0] == 'P' && magicno[1]>='1' && magicno[1]<='6') filetype = PBM; else if (strncmp((char *) magicno,"#define",7)==0) filetype = XBM; else if (magicno[0]==0x59 && (magicno[1]&0x7f)==0x26 && magicno[2]==0x6a && (magicno[3]&0x7f)==0x15) filetype = SUNRAS; else if (magicno[0]==0x52 && magicno[1]==0xcc) filetype = UTAHRLE; else if (!strncmp((char *) magicno,"/* XPM */",8)) filetype = XPM; #ifdef HAVE_JPEG else if (magicno[0]==0xff && magicno[1]==0xd8 && magicno[2]==0xff) filetype = JFIF; #endif #ifdef HAVE_TIFF else if ((magicno[0]=='M' && magicno[1]=='M') || (magicno[0]=='I' && magicno[1]=='I')) filetype = TIFF; #endif #ifdef HAVE_PDS else if (strncmp((char *) magicno, "NJPL1I00",8)==0 || /* fixed-len pds */ strncmp((char *) magicno+2,"NJPL1I", 6)==0 || /* vger+other pds */ strncmp((char *) magicno, "CCSD3ZF", 7)==0 || /* vikng pds browse*/ strncmp((char *) magicno+2,"CCSD3Z", 6)==0 || /* vik. huffman pds*/ strncmp((char *) magicno, "LBLSIZE=",8)==0) /* vicar */ filetype = PDSVICAR; #endif if (filetype == UNKNOWN) { SetISTR(ISTR_INFO,"'%s' not in a recognized format.", basefname); Warning(); goto FAILED; } SetISTR(ISTR_INFO,"Loading..."); switch (filetype) { case GIF: i = LoadGIF(filename,ncols); break; case PM: i = LoadPM (filename,ncols); break; case PBM: i = LoadPBM(filename,ncols); break; case XBM: i = LoadXBM(filename,ncols); break; case SUNRAS: i = LoadSunRas(filename, ncols); break; case UTAHRLE: i = LoadRLE(filename, ncols); break; case XPM: i = LoadXPM(filename,ncols); break; #ifdef HAVE_JPEG case JFIF: i = LoadJFIF(filename, ncols); break; #endif #ifdef HAVE_TIFF case TIFF: i = LoadTIFF(filename, ncols); break; #endif #ifdef HAVE_PDS case PDSVICAR: i = LoadPDS(filename, ncols); break; #endif } WaitCursor(); if (i) { SetISTR(ISTR_INFO,"Couldn't load file '%s'.",filename); Warning(); goto FAILED; } if (pWIDE==0 || pHIGH==0) { /* shouldn't happen, but let's be safe */ SetISTR(ISTR_INFO,"Image size '0x0' not allowed."); Warning(); goto FAILED; } GOTIMAGE: /* successfully read this picture. No failures from here on out */ /* stick this file in the 'ctrlW' name list */ if (filenum == LOADPIC && !frompipe) stickInList(); /* clear old image WINDOW before we start dicking with colors... */ if (mainW && !useroot && clearonload && (theVisual->class == PseudoColor || theVisual->class == GrayScale)) { XClearArea(theDisp, mainW, 0, 0, eWIDE, eHIGH, True); XFlush(theDisp); } if (!browseCB.val && filenum == LOADPIC) DirBox(0); /* close the DirBox */ /* if we read a /tmp file, delete it. won't be needing it any more */ if (strcmp(fullname,filename)!=0) unlink(filename); SetISTR(ISTR_INFO,formatStr); SetInfoMode(INF_PART); SetISTR(ISTR_FILENAME, (filenum==DFLTPIC || filenum==GRABBED || frompipe) ? "" : basefname); SetISTR(ISTR_RES,"%d x %d",pWIDE,pHIGH); SetISTR(ISTR_COLOR,""); /* adjust button in/activity */ BTSetActive(&but[BCROP],0); /* new picture, draw no cropping rectangle */ BTSetActive(&but[BUNCROP], 0); BTSetActive(&but[BNEXT], (curname0)); normFact = 1; nw = pWIDE; nh = pHIGH; /* if pic is larger than screen, half picture until it fits on screen */ while (nw > maxWIDE || nh > maxHIGH) { nw = nw / 2; nh = nh / 2; normFact = normFact * 2; } if (normFact != 1) { char tstr[128]; tmp = GetISTR(ISTR_WARNING); if (strlen(tmp)>0) sprintf(tstr, "%s Shrunk %dX.", tmp, normFact); else sprintf(tstr, "Shrunk %dX.", normFact); SetISTR(ISTR_WARNING,tstr); } /* expand: if expansion is negative, treat it as a reciprocal */ if (expand < 0.0) { eWIDE=(int)(pWIDE/-expand); eHIGH=(int)(pHIGH/-expand); } else { eWIDE=(int)(pWIDE* expand); eHIGH=(int)(pHIGH* expand); } if (eWIDE>maxWIDE || eHIGH>maxHIGH) { eWIDE = eWIDE / normFact; eHIGH = eHIGH / normFact; } cpic = pic; cWIDE = pWIDE; cHIGH = pHIGH; cXOFF = cYOFF = 0; SetCropString(but[BCROP].active); if (useroot) { int i,x,y; unsigned int w,h; i = XParseGeometry(maingeom,&x,&y,&w,&h); if (i&WidthValue) eWIDE = w; if (i&HeightValue) eHIGH = h; geomXabs=(i&XValue)?abs(x):-1; geomYabs=(i&YValue)?abs(y):-1; geomXsgn=1-2*!!(i&XNegative); geomYsgn=1-2*!!(i&YNegative); RANGE(eWIDE,1,maxWIDE); RANGE(eHIGH,1,maxHIGH); /* handle case where they only specified width *or* height */ if (( i&WidthValue && ~i&HeightValue) || (~i&WidthValue && i&HeightValue)) { if (i&WidthValue) { eHIGH = (pHIGH * eWIDE) / pWIDE; } else { eWIDE = (pWIDE * eHIGH) / pHIGH; } RANGE(eWIDE,1,maxWIDE); RANGE(eHIGH,1,maxHIGH); } if (fixedaspect) FixAspect(0,&eWIDE,&eHIGH); if (rootMode == RM_TILE || rootMode == RM_IMIRROR) { /* make picture size a divisor of the rootW size. round down */ i = (dispWIDE + eWIDE-1) / eWIDE; eWIDE = (dispWIDE + i-1) / i; i = (dispHIGH + eHIGH-1) / eHIGH; eHIGH = (dispHIGH + i-1) / i; } } if (automax) { eWIDE = dispWIDE; eHIGH = dispHIGH; if (fixedaspect) FixAspect(0,&eWIDE,&eHIGH); } if (useroot) { mainW = vrootW; if ((theVisual->class == PseudoColor || theVisual->class == GrayScale) && clearonload) { /* clear old root pixmap before doing the 'alloc colors scene' to avoid annoying 'rainbow' effect as colors are realloced (unless we said '-noresetroot') */ ClearRoot(); } } SortColormap(); /* see if image is a b/w bitmap. If so, use '-black' and '-white' colors */ if (numcols == 2) { if ((r[0] == g[0] && r[0] == b[0] && r[0] == 255) && (r[1] == g[1] && r[1] == b[1] && r[1] == 0)) { /* 0=wht, 1=blk */ r[0] = (whtRGB>>16)&0xff; g[0] = (whtRGB>>8)&0xff; b[0] = whtRGB&0xff; r[1] = (blkRGB>>16)&0xff; g[1] = (blkRGB>>8)&0xff; b[1] = blkRGB&0xff; } else if ((r[0] == g[0] && r[0] == b[0] && r[0] == 0) && (r[1] == g[1] && r[1] == b[1] && r[1] == 255)) { /*0=blk, 1=wht*/ r[0] = (blkRGB>>16)&0xff; g[0] = (blkRGB>>8)&0xff; b[0] = blkRGB&0xff; r[1] = (whtRGB>>16)&0xff; g[1] = (whtRGB>>8)&0xff; b[1] = whtRGB&0xff; } } /* reverse image, if desired */ if (revvideo) { for (i=0; i0 && oldeHIGH>0 && (oldeWIDE != eWIDE || oldeHIGH != eHIGH) ) GenExpose(mainW, 0, 0, oldeWIDE, oldeHIGH); return 1; FAILED: SetCursors(-1); SetInfoMode(INF_STR); if (strcmp(fullname,filename)!=0) unlink(filename); /* kill /tmp file */ if (freename) free(fullname); return 0; } /***********************************/ static int readpipe(cmd, fname) char *cmd, *fname; { /* cmd is something like: "! bggen 100 0 0" * * runs command (with "> /tmp/xv******" appended). * returns "/tmp/xv******" in fname * returns '0' if everything's cool, '1' on error */ char fullcmd[512], tmpname[20], str[512]; int i; if (!cmd || strlen(cmd)<2) return 1; sprintf(tmpname,"%s/xvXXXXXX", tmpdir); mktemp(tmpname); if (tmpname[0] == '\0') { /* mktemp() blew up */ static char *foo[] = {"\nHow unlikely!"}; sprintf(str,"Unable to create temporary filename."); PopUp(str, foo, 1); return 1; } /* build command */ strcpy(fullcmd, cmd+1); /* skip the leading '!' character in cmd */ strcat(fullcmd, " > "); strcat(fullcmd, tmpname); /* execute the command */ sprintf(str, "Doing command: '%s'", fullcmd); OpenAlert(str); i = system(fullcmd); if (i) { static char *foo[] = { "\nThat Sucks!" }; sprintf(str, "Unable to complete command:\n %s\n\n exit status: %d", fullcmd, i); CloseAlert(); PopUp(str, foo, 1); unlink(tmpname); /* just in case it was created */ return 1; } CloseAlert(); strcpy(fname, tmpname); return 0; } /***********************************/ static void closePic() { /* kill all resources used for this picture. this would include the window, any allocated colors, pic, epic, theImage, etc. */ if (!useroot) { /* turn off configure events */ XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask | ButtonPressMask | KeyReleaseMask | EnterWindowMask | LeaveWindowMask); } FreeAllColors(); if (epic != cpic && epic != NULL) free(epic); if (cpic != pic && cpic != NULL) free(cpic); if (pic != NULL) free(pic); xvDestroyImage(theImage); theImage = NULL; pic = epic = cpic = NULL; SetInfoMode(INF_STR); } /****************/ static void OpenFirstPic() /****************/ { int i; if (!numnames) { openPic(DFLTPIC); return; } for (i=0; i1) FatalError("couldn't open any pictures"); else Quit(-1); } /****************/ static void OpenNextPic() /****************/ { int i; for (i=curname+1; i=0; i--) { if (openPic(i)) return; /* success */ } openPic(DFLTPIC); } /****************/ static void OpenNamedPic() /****************/ { if (!openPic(LOADPIC)) openPic(DFLTPIC); } /****************/ static void MainLoop() /****************/ { /* search forward until we manage to display a picture, then call EventLoop. EventLoop will eventually return NEXTPIC, PREVPIC, NEXTQUIT, QUIT, or, if >= 0, a filenum to GOTO */ int i; OpenFirstPic(); /* find first displayable picture, exit if none */ if (useroot && autoquit) Quit(0); while ((i=EventLoop()) != QUIT) { if (i==NEXTPIC && curname0) { closePic(); OpenPrevPic(); } else if (i==NEXTQUIT) { closePic(); OpenNextQuit(); } else if (i==NEXTLOOP) { closePic(); OpenNextLoop(); } else if (i==LOADPIC) { closePic(); OpenNamedPic(); } else if (i==DELETE) { closePic(); if (nList.nstr == 0 && !keeparound) Quit(0); if (curname >= 0 && curname < numnames) { /* there's a selection */ if (!openPic(curname)) openPic(DFLTPIC); } else openPic(DFLTPIC); } else if (i==GRABBED) { closePic(); if (!openPic(GRABBED)) openPic(DFLTPIC); } else if (i>=0) { closePic(); if (!openPic(i)) openPic(DFLTPIC); } } } /***********************************/ static void CreateMainWindow(geom,name) char *geom, *name; { XSetWindowAttributes xswa; unsigned int xswamask; XWindowAttributes xwa; XWMHints xwmh; XSizeHints hints; XClassHint classh; int i,x,y,ew,eh; unsigned int w,h; char winname[128], iconname[128]; /* * this function mainly deals with parsing the geometry spec correctly. * More trouble than it should be, and probably more trouble than * it has to be, but who can tell these days, what with all those * Widget-usin' Weenies out there... */ ew = eWIDE; eh = eHIGH; x = y = w = h = 1; i = XParseGeometry(geom,&x,&y,&w,&h); if (i&WidthValue) eWIDE = w; if (i&HeightValue) eHIGH = h; /* handle case where they only specified width *or* height */ if (( i&WidthValue && ~i&HeightValue) || (~i&WidthValue && i&HeightValue)) { if (i&WidthValue) { eHIGH = (pHIGH * eWIDE) / pWIDE; } else { eWIDE = (pWIDE * eHIGH) / pHIGH; } } if (eWIDE > maxWIDE || eHIGH > maxHIGH) { eWIDE = eWIDE / normFact; eHIGH = eHIGH / normFact; } if (eWIDE < 1) eWIDE = 1; if (eHIGH < 1) eHIGH = 1; if (fixedaspect && i&WidthValue && i&HeightValue) FixAspect(0,&eWIDE,&eHIGH); else if (i&WidthValue && i&HeightValue) { RANGE(eWIDE,1,maxWIDE); RANGE(eHIGH,1,maxHIGH); } else FixAspect(1,&eWIDE,&eHIGH); hints.flags = 0; if ((i&XValue || i&YValue)) hints.flags = USPosition; if (i&XValue && i&XNegative) x = vrWIDE - eWIDE - abs(x); if (i&YValue && i&YNegative) y = vrHIGH - eHIGH - abs(y); if (x+eWIDE > vrWIDE) x = vrWIDE - eWIDE; /* keep on screen */ if (y+eHIGH > vrHIGH) y = vrHIGH - eHIGH; if (eWIDE < 1) eWIDE = 1; if (eHIGH < 1) eHIGH = 1; #define VROOT_TRANS #ifdef VROOT_TRANS if (vrootW != rootW) { /* virtual window manager running */ int x1,y1; Window child; XTranslateCoordinates(theDisp, rootW, vrootW, x, y, &x1, &y1, &child); if (DEBUG) fprintf(stderr,"translate: %d,%d -> %d,%d\n",x,y,x1,y1); x = x1; y = y1; } #endif hints.x = x; hints.y = y; hints.width = eWIDE; hints.height = eHIGH; hints.max_width = maxWIDE; hints.max_height = maxHIGH; hints.flags |= USSize | PMaxSize; xswa.bit_gravity = StaticGravity; xswa.background_pixel = bg; xswa.border_pixel = fg; xswa.colormap = theCmap; xswamask = CWBackPixel | CWBorderPixel | CWColormap; if (!clearonload) xswamask |= CWBitGravity; if (mainW) { GetWindowPos(&xwa); /* generate an expose event if window hasn't changed size */ if (xwa.width == eWIDE && xwa.height == eHIGH) GenExpose(mainW, 0,0, eWIDE, eHIGH); xwa.width = eWIDE; xwa.height = eHIGH; SetWindowPos(&xwa); hints.flags = PSize | PMaxSize; } else { mainW = XCreateWindow(theDisp,rootW,x,y,eWIDE,eHIGH,bwidth,dispDEEP, InputOutput, theVisual, xswamask, &xswa); if (!mainW) FatalError("can't create window!"); XSetTransientForHint(theDisp, psW, mainW); #ifdef HAVE_JPEG XSetTransientForHint(theDisp, jpegW, mainW); #endif #ifdef HAVE_TIFF XSetTransientForHint(theDisp, tiffW, mainW); #endif } if (name[0] == '\0') { sprintf(winname, "xv"); sprintf(iconname,"xv"); } else { sprintf(winname,"xv %s",name); sprintf(iconname,"%s",name); } XSetStandardProperties(theDisp,mainW,winname,iconname,None,NULL,0,&hints); xwmh.input = True; xwmh.flags = InputHint; if (iconPix) { xwmh.icon_pixmap = iconPix; xwmh.icon_mask = iconmask; xwmh.flags |= ( IconPixmapHint | IconMaskHint) ; } XSetWMHints(theDisp, mainW, &xwmh); classh.res_name = "xv"; classh.res_class = "XVroot"; XSetClassHint(theDisp, mainW, &classh); } /***********************************/ void FixAspect(grow,w,h) int grow; int *w, *h; { /* computes new values of eWIDE and eHIGH which will have aspect ratio 'normaspect'. If 'grow' it will preserve aspect by enlarging, otherwise, it will shrink to preserve aspect ratio. Returns these values in 'w' and 'h' */ float xr,yr,curaspect,a,exp; *w = eWIDE; *h = eHIGH; /* xr,yr are expansion factors */ xr = ((float) eWIDE) / cWIDE; yr = ((float) eHIGH) / cHIGH; curaspect = xr / yr; /* if too narrow & shrink, shrink height. too wide and grow, grow height */ if ((curaspect < normaspect && !grow) || (curaspect > normaspect && grow)) { /* modify height */ exp = curaspect / normaspect; *h = (int) (eHIGH * exp + .5); } /* if too narrow & grow, grow width. too wide and shrink, shrink width */ if ((curaspect < normaspect && grow) || (curaspect > normaspect && !grow)) { /* modify width */ exp = normaspect / curaspect; *w = (int) (eWIDE * exp + .5); } /* shrink to fit screen without changing aspect ratio */ if (*w>maxWIDE) { int i; a = (float) *w / maxWIDE; *w = maxWIDE; i = (int) (*h / a + .5); /* avoid freaking some optimizers */ *h = i; } if (*h>maxHIGH) { a = (float) *h / maxHIGH; *h = maxHIGH; *w = (int) (*w / a + .5); } if (*w < 1) *w = 1; if (*h < 1) *h = 1; } /***********************************/ static void MakeDispNames() { int prelen, n, i, done; char *suffix; suffix = namelist[0]; prelen = 0; /* length of prefix to be removed */ n = i = 0; /* shut up pesky compiler warnings */ done = 0; while (!done) { suffix = (char *) strchr(suffix,'/'); /* find next '/' in file name */ if (!suffix) break; suffix++; /* go past it */ n = suffix - namelist[0]; for (i=1; i (CTRL_LISTW-10)) { /* has to be truncated */ char *tmp; int prelen = 0; tmp = fullname; while (1) { tmp = (char *) strchr(tmp,'/'); /* find next (forward) '/' in filename */ if (!tmp) break; tmp++; /* move to char following the '/' */ prelen = tmp - fullname; if (StringWidth(tmp) <= (CTRL_LISTW-10)) break; /* we're cool now */ } dispnames[numnames] = fullname + prelen; } else dispnames[numnames] = fullname; numnames++; if (numnames>0) BTSetActive(&but[BDELETE],1); LSNewData(&nList, dispnames, numnames); nList.selected = numnames-1; curname = numnames - 1; BTSetActive(&but[BNEXT], (curname0)); ScrollToCurrent(&nList); XClearArea(theDisp, ctrlW, 0, 0, 200, 40, True); /* redraw part of ctrlW */ } /***********************************/ int DeleteCmd() { /* 'delete' button was pressed. Pop up a dialog box to determine what should be deleted, then do it. returns '1' if THE CURRENTLY VIEWED entry was deleted from the list, in which case the 'selected' filename on the ctrl list is now different, and should be auto-loaded, or something */ static char *bnames[] = { "\004Disk File", "\nList Entry", "\033Cancel" }; char str[512]; int del, i, delnum, rv; /* failsafe */ delnum = nList.selected; if (delnum < 0 || delnum >= numnames) return 0; sprintf(str,"What do you wish to delete?\n\n%s%s", "'List Entry' deletes selection from list.\n", "'Disk File' deletes file associated with selection."); del = PopUp(str, bnames, 3); if (del == 2) return 0; /* cancel */ if (del == 0) { /* 'Disk File' */ char *name; if (namelist[delnum][0] != '/') { /* prepend 'initpath' */ name = (char *) malloc(strlen(namelist[delnum]) + strlen(initpath) + 2); if (!name) FatalError("malloc in DeleteCmd failed\n"); sprintf(name,"%s/%s", initpath, namelist[delnum]); } else name = namelist[delnum]; i = unlink(name); if (i) { static char *foo[] = { "\nPity!" }; sprintf(str,"Can't delete file '%s'\n\n %s.", name, sys_errlist[errno]); PopUp(str, foo, 1); return 0; } LoadCurrentDirectory(); /* just in case we deleted a file in the cwd */ } /* remove from list on either 'List Entry' or (successful) 'Disk File' */ /* determine if namelist[delnum] needs to be freed or not */ for (i=0; i= numnames) nList.selected = numnames-1; if (nList.selected < 0) nList.selected = 0; SCSetRange(&nList.scrl, 0, numnames - nList.nlines, nList.scrl.val, nList.nlines-1); ScrollToCurrent(&nList); XClearArea(theDisp, ctrlW, 0, 0, 200, 40, True); /* redraw part of ctrlW */ rv = 0; if (delnum == curname) { /* deleted the viewed file */ curname = nList.selected; rv = 1; /* auto-load currently 'selected' filename */ } else if (delnum < curname) curname = (curname > 0) ? curname-1 : 0; else if (delnum > curname); BTSetActive(&but[BNEXT], (curname0)); return rv; } /***********************************/ static void smoothResize(w,h) { if (autosmooth || normFact != 1) { eWIDE = w; eHIGH = h; Smooth(); } else Resize(w,h); if ((autodither || dfltkludge) && !autosmooth && ncols>0) ColorDither(NULL, w,h); } /***********************************/ void HandleDispMode() { /* handles a change in the display mode (windowed/root). Also, called to do the 'right' thing when opening a picture displays epic, in current size, UNLESS we've selected an 'integer' root tiling thingy, in which case we resize epic appropriately */ static int haveoldinfo = 0; static Window oldMainW; static int oldPerfect, oldNoglob, oldOwnCmap; static int hadLocalCmap; static XSizeHints oldHints; static XWindowAttributes oldXwa; int i; char wnam[128], inam[128]; if (dispMB.selected == 0) { /* windowed */ if (useroot && resetroot) ClearRoot(); if (mainW == (Window) NULL || useroot) { /* window not visible */ useroot = 0; if (haveoldinfo) { /* just remap mainW and resize it */ mainW = oldMainW; perfect = oldPerfect; noglob = oldNoglob; owncmap = oldOwnCmap; if (hadLocalCmap) { /* use 'perfect' again */ FreeAllColors(); if (rwcolor) AllocRWColors(); else AllocColors(); CreateXImage(); } sprintf(wnam,"xv %s",basefname); sprintf(inam,"%s",basefname); XSetStandardProperties(theDisp,mainW,wnam,inam,None,NULL,0,&oldHints); oldXwa.width = eWIDE; oldXwa.height = eHIGH; SetWindowPos(&oldXwa); XMapWindow(theDisp, mainW); } else { /* first time. need to create mainW */ int ew, eh; mainW = (Window) NULL; ew = eWIDE; eh = eHIGH; CreateMainWindow(maingeom, basefname); XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask | StructureNotifyMask | ButtonPressMask | KeyReleaseMask | ColormapChangeMask | EnterWindowMask | LeaveWindowMask ); StoreDeleteWindowProp(mainW); XMapWindow(theDisp,mainW); if (ew != eWIDE || eh != eHIGH) smoothResize(ew, eh); } } else { /* mainW already visible */ int ew, eh; ew = eWIDE; eh = eHIGH; CreateMainWindow(maingeom, basefname); XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask | StructureNotifyMask | ButtonPressMask | KeyReleaseMask | ColormapChangeMask | EnterWindowMask | LeaveWindowMask ); if (LocalCmap) { /* AllocColors created local colormap */ XSetWindowColormap(theDisp, mainW, LocalCmap); } if (ew != eWIDE || eh != eHIGH) smoothResize(ew, eh); } useroot = 0; } else if (dispMB.selected > 0 && (dispMB.selected <= RM_MAX+1)) { /* a 'root' mode */ int ew, eh, regen; regen = 0; if (!useroot) { /* have to kill mainW, etc. */ /* save current window position */ haveoldinfo = 1; oldMainW = mainW; oldPerfect = perfect; oldNoglob = noglob; oldOwnCmap = owncmap; hadLocalCmap = LocalCmap; GetWindowPos(&oldXwa); geomXsgn=1; geomYsgn=1; geomXabs=oldXwa.x; geomYabs=oldXwa.y; if (!XGetNormalHints(theDisp, mainW, &oldHints)) oldHints.flags = 0; oldHints.x=oldXwa.x; oldHints.y=oldXwa.y; oldHints.flags|=USPosition; perfect = owncmap = 0; /* can't do -perfect on a root window */ noglob = 1; /* Phase 3 color alloc's a bad idea too */ XUnmapWindow(theDisp, mainW); mainW = vrootW; if (!ctrlUp) { /* make sure ctrl is up when going to 'root' mode */ XWMHints xwmh; xwmh.initial_state = IconicState; xwmh.flags = StateHint; XSetWMHints(theDisp, ctrlW, &xwmh); CtrlBox(1); } } if (LocalCmap) { /* we *were* using -perfect */ FreeAllColors(); if (rwcolor) AllocRWColors(); else AllocColors(); regen = 1; } useroot = 1; rootMode = dispMB.selected - 1; ew = eWIDE; eh = eHIGH; RANGE(ew,1,maxWIDE); RANGE(eh,1,maxHIGH); if (rootMode == RM_TILE || rootMode == RM_IMIRROR) { /* make picture size a divisor of the rootW size. round down */ i = (dispWIDE + ew-1) / ew; ew = (dispWIDE + i-1) / i; i = (dispHIGH + eh-1) / eh; eh = (dispHIGH + i-1) / i; } if (ew != eWIDE || eh != eHIGH) smoothResize(ew, eh); /* changed size */ else { /* didn't regen XImage. If we were using LocalCmap we have to */ if (regen) CreateXImage(); } KillOldRootInfo(); MakeRootPic(); SetCursors(-1); } else { fprintf(stderr,"%s: unknown dispMB value '%d' in HandleDispMode()\n", dispMB.selected); } } /************************************************************************/ /* following three rd_* functions swiped from xgraph, by David Harrison */ /************************************************************************/ /***********************************/ /* weikart, Mon Sep 2 18:26:36 1991; convert to lower-care for comparisons: */ char *lower_str(string) char *string; { char *p; for (p = string; *p != '\0'; p++) if (isupper(*p)) *p = tolower(*p); return string; } /*********************************** * If XGetDefault finds a DECW$XDEFAULTS.DAT file, it reads it once and saves * the contents for subsequent calls. It doesn't remember when a lookup * fails, however, and will try to lookup the file again for every XGetDefault * call. Replace the XGetDefault calls with rd_getdefault, which is more * intelligent about handling missing DECW$XDEFAULTS.DAT (i.e. most users). */ static XrmDatabase def_resource; static int xrm_initted = 0; char *rd_getdefault ( name ) char *name; { #ifndef VMS return XGetDefault (theDisp, PROGNAME, name); #else /* it is VMS */ char namelist[512], *type; XrmValue value; if ( !xrm_initted ) { xrm_initted = 1; XrmInitialize(); def_resource = XrmGetFileDatabase ( "SYS$LOGIN:DECW$XDEFAULTS.DAT" ); } if ( def_resource != NULL ) { sprintf ( namelist, "%s.%s", PROGNAME, name ); XrmGetResource ( def_resource, namelist, "", &type, &value ); return value.addr; } else return NULL; /* no database */ #endif } /***********************************/ int rd_int(name) char *name; { /* returns '1' if successful. result in def_int */ def_str = rd_getdefault(name); if (def_str) { if (sscanf(def_str, "%ld", &def_int) == 1) return 1; else { fprintf(stderr, "%s: couldn't read integer value for %s resource\n", cmd,name); return 0; } } else return 0; } /***********************************/ int rd_str(name) char *name; { /* returns '1' if successful. result in def_str */ def_str = rd_getdefault(name); if (def_str) return 1; else return 0; } /***********************************/ int rd_flag(name) char *name; { /* returns '1' if successful. result in def_int */ char buf[256]; def_str = rd_getdefault(name); if (def_str) { strcpy(buf, def_str); lower_str(buf); def_int = (strcmp(buf, "on")==0) || (strcmp(buf, "1")==0) || (strcmp(buf, "true")==0) || (strcmp(buf, "yes")==0); return 1; } else return 0; } /************************************************************************/ /* rd_str_cl() written by Dean Elhard (elhard@system-m.az05.bull.com) */ /************************************************************************/ /* Author's note: * * I build another routine to go along with rd_str, rd_int, and rd_flag, called * rd_str_cl which takes a name and a class string and works with multi-part * names. The code is not really great because it depends on the resource * database field in the display structure (which is the one XGetResource uses * in X11R5 at least). It also depends on XGetResource being called first to * initialize the database. I should have probably rewritten rd_str, rd_int, * and rd_flag to all call XrmGetResource, but I wanted to keep the change as * minimal as possible. If you want to implement a better fix, I leave that * to you. Context diffs for the two changed files (xv.c and xvgam.c) follow. */ int rd_str_cl (name_str, class_str) char *name_str; char *class_str; { char q_name[BUFSIZ]; char q_class[BUFSIZ]; char *type; XrmValue result; strcpy (q_name, PROGNAME); strcat (q_name, "."); strcat (q_name, name_str); strcpy (q_class, "Program"); strcat (q_class, "."); strcat (q_class, class_str); (void) XrmGetResource(theDisp->db, q_name, q_class, &type, &result); def_str = result.addr; if (def_str) return (1); else return (0); } case we deleted a file in the cwd */ } /* remove from list on either 'List Entry' or (successful) 'Disk File' */ /* determine if namelist[delnum] needs to be freed or not */ for (i=0; i /* Get bsd fast file system params*/ #endif #ifndef VMS /* VMS doesn't like multi-line '#if's */ /* AIX and SysV r4 (but not sgi or UMAXV) use dirent */ # if (defined(SVR4) && !defined(sgi) && !defined(__UMAXV__)) \ || defined(_IBMR2) || defined(sco) # ifndef DIRENT # define DIRENT # endif # endif #endif /* !VMS */ /* include files */ #include #include #include /* include the appropriate string header file */ #if defined(SVR4) || defined(__convex__) || defined(VMS) #include #define index strchr #define rindex strrchr #else #include #endif #if defined(SVR4) || defined(hpux) #define GETWD(x) getcwd(x, sizeof(x)) #else #define GETWD(x) getwd(x) #endif #if defined(apollo) || defined(pyr) /* DomainOS 10.2 BSD4.3 version of str[r]chr is broken ([r]index works) */ /* pyramid bsd doesn't have str[r]chr */ #define strchr index #define strrchr rindex #endif #ifndef VMS extern int errno; /* this SHOULD be in errno.h */ extern char *sys_errlist[]; /* this SHOULD be in errno.h */ #endif #ifndef VMS /* VMS hates multi-line '#if's */ /* lots of machines don't have */ # if !defined(__convex__) && \ !defined(__UMAXV__) && \ !defined(pyr) && \ !defined(sequent) # include /* for 'memset()' prototype */ # endif #endif /* !VMS */ #ifdef VMS /* VMS config, hacks & kludges */ #define DIRENT 1 #define MAXPATHLEN 512 #define popUp xv_popup #define qsort xv_qsort #define bzero(s,size) memset(s,0,size) #define bcmp(s1,s2,size) xv_bcmp((char *)s1,(char *)s2,size) #define random rand #define cols xv_cols typedef unsigned long u_long; #include /* in VMS they *are* in errno.h */ #include /* and perror.h */ #endif #ifndef VMS /* VMS still hates multi-line '#if's */ /* lots of things don't have */ /* A/UX systems include it from stdlib, from Xos.h */ # if !defined(ibm032) && \ !defined(__convex__) && \ !(defined(vax) && !defined(ultrix)) && \ !defined(mips) && \ !defined(apollo) && \ !defined(pyr) && \ !defined(__UMAXV__) && \ !defined(bsd43) && \ !defined(macII) && \ !defined(sequent) # if defined(hp300) || defined(hp800) # include /* it's in 'sys' on HPs*/ # else # include # endif # endif #endif /* !VMS */ #if defined(NEED_MEMROUTINES) #define memcpy(d,s,l) bcopy(s,d,l) #endif #include #include #include #include #include #include #include #include #if defined(NEEDSTIME) || defined(NEEDSDIR) #include /* only include once */ #endif #ifdef NEEDSTIME #if defined(SVR4) || defined(macII) #include #else /* not SVR4 */ #if !defined(sgi) && !defined(__UMAXV__) /* sgi & UMAX don't have timeb.h */ #include #endif /* not sgi */ #endif /* not SVR4 */ #undef SIGCHLD /* defined in both the Xos.h and signal.h */ #include #if defined(sco) && !defined(NOTIMER) #include #endif #ifndef sigmask #define sigmask(m) (1 << ((m)-1)) #endif #endif /* NEEDSTIME */ #ifdef NEEDSDIR # ifdef VMS # include # include # include "dirent.h" # else # ifdef sco # include /* sco has sys/ndir.h */ # else # ifndef ATT # include /* everybody else (except ATT) has sys/dir.h */ # endif /* ATT */ # endif /* sco */ # include # include # ifdef DIRENT # include # endif # endif /* !VMS */ #endif /* NEEDSDIR */ #ifdef NEEDSARGS #if defined(__STDC__) && !defined(NOSTDHDRS) #include #else #include #endif #endif /* signal macros */ #if defined(SVR4) && !defined(HPUX7) && !(defined(_AUX_SOURCE)) #define HOLD_SIG sighold(SIGALRM) /* block ALRM sig from occurring */ #define RELEASE_SIG sigrelse(SIGALRM) #define PAUSE_SIG sigpause(SIGALRM) /* sleep until ALRM signal */ #else #define HOLD_SIG sigblock(sigmask(SIGALRM)) #define RELEASE_SIG sigblock(0) #define PAUSE_SIG sigpause(0) #endif #ifdef __UMAXV__ #undef PAUSE_SIG #define PAUSE_SIG sigpause(SIGALRM) #endif /* default for most folks */ #define UNCOMPRESS "/usr/ucb/uncompress" /* for uncompressing .Z files */ #if defined(hpux) || defined (SVR4) #undef UNCOMPRESS #define UNCOMPRESS "/usr/bin/uncompress" /* for uncompressing .Z files */ #endif #ifdef VMS /* you WILL have to personalize for your own DECUS VMS version of the Martin Minow LZDCMP for this to work properly... */ # undef UNCOMPRESS # ifdef HAVE_LZW # define UNCOMPRESS "LZDCMP /Export = Unix /Mode = Binary" # else # define UNCOMPRESS "DECOMPRESS" # endif /* HAVE_LZW */ #endif /* VMS */ #if defined(i386) && !defined(sequent) && !defined(sun386) && !defined(_AIX) #define MAXPATHLEN 500 #undef UNCOMPRESS #define UNCOMPRESS "/usr/local/bin/uncompress" /* uncompress program */ #undef HOLD_SIG #define HOLD_SIG /* don't know how to handle signals MWS 10/18/90 */ #undef RELEASE_SIG #define RELEASE_SIG /* */ #undef PAUSE_SIG #define PAUSE_SIG /* */ #endif #ifndef MAXPATHLEN #define MAXPATHLEN 1024 #endif #ifdef NO_RANDOM #define random rand #endif /*****************************/ /* END OF CONFIGURATION INFO */ /*****************************/ #define PROGNAME "xv" /* used in resource database */ #define DEFINFOGEOM "-10+10" /* default position of info window */ #define DEFCTRLGEOM "+400+400" /* default position of ctrl window */ #define DEFGAMGEOM "+10-10" /* default position of gamma window */ #define INFOWIDE 500 /* (fixed) size of info window */ #define INFOHIGH 250 #define CTRLWIDE 440 /* (fixed) size of control window */ #define CTRLHIGH 345 #define CTRL_LISTW (330-70) #define DIRWIDE 300 /* (fixed) size of directory window */ #define DIRHIGH 440 #define MAXNAMES 4096 /* max # of files in ctrlW list */ /* strings in the INFOBOX (used in SetISTR and GetISTR) */ #define NISTR 9 /* number of ISTRs */ #define ISTR_INFO 0 #define ISTR_WARNING 1 #define ISTR_FILENAME 2 #define ISTR_FORMAT 3 #define ISTR_RES 4 #define ISTR_CROP 5 #define ISTR_EXPAND 6 #define ISTR_COLOR 7 #define ISTR_COLOR2 8 /* potential values of 'infomode', used in info box drawing routines */ #define INF_NONE 0 /* empty box */ #define INF_STR 1 /* just ISTR_INFO */ #define INF_PART 2 /* filename, format, size and infostr */ #define INF_FULL 3 /* INF_PART + clipping, expansion, colorinfo */ /* buttons in the ctrl window */ #define NBUTTS 28 #define BNEXT 0 #define BPREV 1 #define BCROP 2 #define BUNCROP 3 #define BNORM 4 #define BMAX 5 #define BUP2 6 #define BDN2 7 #define BUP10 8 #define BDN10 9 #define BQUIT 10 #define B4BY3 11 #define BSAVE 12 #define BROTL 13 #define BINFO 14 #define BGAMMA 15 #define BASPECT 16 #define BROTR 17 #define BMAXPECT 18 #define BACROP 19 #define BSMOOTH 20 #define BDITH 21 #define BRAW 22 #define BLOAD 23 #define BDELETE 24 #define BFLIPH 25 #define BFLIPV 26 #define BGRAB 27 /* buttons in the 'save' window */ #define S_NBUTTS 3 #define S_BOK 0 #define S_BCANC 1 #define S_BRESCAN 2 /* buttons in the 'gamma' window */ #define G_NBUTTS 24 #define G_BAPPLY 0 #define G_BNOGAM 1 #define G_BRESET 2 #define G_BCLOSE 3 #define G_BUP_BR 4 #define G_BDN_BR 5 #define G_BUP_CN 6 #define G_BDN_CN 7 #define G_B1 8 #define G_B2 9 #define G_B3 10 #define G_B4 11 #define G_BSET 12 #define G_BUNDO 13 #define G_BREDO 14 #define G_BCOLREV 15 #define G_BRNDCOL 16 #define G_BHSVRGB 17 #define G_BCOLUNDO 18 #define G_BRV 19 #define G_BMONO 20 #define G_BMAXCONT 21 #define G_BGETRES 22 #define G_BHISTEQ 23 /* constants for setting radio buttons in dirW */ #define F_COLORS 0 #define F_FORMAT 1 #define F_FULLCOLOR 0 #define F_GREYSCALE 1 #define F_BWDITHER 2 #define F_REDUCED 3 #define F_GIF 0 #define F_PM 1 #define F_PBMRAW 2 #define F_PBMASCII 3 #define F_XBM 4 #define F_SUNRAS 5 #define F_PS 6 #define F_XPM 7 #ifdef HAVE_JPEG #define F_JPEG 8 #endif #ifdef HAVE_TIFF #ifdef HAVE_JPEG #define F_TIFF 9 #else #define F_TIFF 8 #endif #endif /* definitions for page up/down, arrow up/down list control */ #define LS_PAGEUP 0 #define LS_PAGEDOWN 1 #define LS_LINEUP 2 #define LS_LINEDOWN 3 #define LS_HOME 4 #define LS_END 5 /* values 'epicmode' can take */ #define EM_RAW 0 #define EM_DITH 1 #define EM_SMOOTH 2 /* things EventLoop() can return (0 and above reserved for 'goto pic#') */ #define QUIT -1 /* exit immediately */ #define NEXTPIC -2 /* goto next picture */ #define PREVPIC -3 /* goto prev picture */ #define NEXTQUIT -4 /* goto next picture, quit if none (used by 'wait') */ #define LOADPIC -5 /* load 'named' pic (from directory box) */ #define NEXTLOOP -6 /* load next pic, loop if we're at end */ #define DFLTPIC -7 /* load the default image */ #define DELETE -8 /* just deleted pic. load 'right' thing */ #define GRABBED -9 /* just grabbed a pic. 'load' it up */ /* possible values of 'rootMode' */ #define RM_NORMAL 0 /* default X tiling */ #define RM_TILE 1 /* integer tiling */ #define RM_MIRROR 2 /* mirror tiling */ #define RM_IMIRROR 3 /* integer mirror tiling */ #define RM_CENTER 4 /* modes >= RM_CENTER centered on some sort of bg */ #define RM_CENTILE 4 /* centered and tiled. NOTE: equals RM_CENTER */ #define RM_CSOLID 5 /* centered on a solid bg */ #define RM_CWARP 6 /* centered on a 'warp-effect' bg */ #define RM_CBRICK 7 /* centered on a 'brick' bg */ #define RM_CLEFT 8 /* centered left on solid bg */ #define RM_CRIGHT 9 /* centered right on solid bg */ #define RM_CTOP 10 /* centered top on solid bg */ #define RM_CBOTTOM 11 /* centered bottom on solid bg */ #define RM_GEOM 12 /* placed at geom spec on solid bg */ #define RM_MAX RM_GEOM /* types of 24-to-8 conversion */ #define CONV24_FAST 0 #define CONV24_SLOW 1 #define CONV24_BEST 2 /* definitions of first char of dirnames[i] (filetype) */ #define C_FIFO 'f' /* FIFO special file */ #define C_CHR 'c' /* character special file */ #define C_DIR 'd' /* directory */ #define C_BLK 'b' /* block special file */ #define C_LNK 'l' /* symbolic link */ #define C_SOCK 's' /* socket */ #define C_REG ' ' /* regular file */ /* random string-placing definitions */ #define SPACING 3 /* vertical space between strings */ #define ASCENT (mfinfo->ascent) #define DESCENT (mfinfo->descent) #define CHIGH (ASCENT + DESCENT) #define LINEHIGH (CHIGH + SPACING) #define STDINSTR "" #ifndef MAIN #define WHERE extern #else #define WHERE #endif typedef unsigned char byte; typedef struct { Window win; /* window ID */ int len; /* length of major axis */ int vert; /* true if vertical, else horizontal */ int active; /* true if scroll bar can do anything*/ int min,max; /* min/max values 'pos' can take */ int val; /* 'value' of scrollbar */ int page; /* amt val change on pageup/pagedown */ int tpos; /* thumb pos. (pixels from tmin) */ int tmin,tmax; /* min/max thumb offsets (from 0,0) */ int tsize; /* size of thumb (in pixels) */ unsigned long fg,bg; /* colors */ void (*drawobj)(); /* redraws obj controlled by scrl*/ int uplit, dnlit; /* true if up&down arrows are lit */ } SCRL; typedef struct { Window win; /* window ID */ int w,h; /* size of window */ int active; /* true if can do anything*/ int min,max; /* min/max values 'pos' can take */ int val; /* 'value' of dial */ int page; /* amt val change on pageup/pagedown */ char *title; /* title for this guage */ char *units; /* string appended to value */ unsigned long fg,bg; /* colors */ int rad, cx, cy; /* internals */ int bx[4], by[4]; /* more internals */ void (*drawobj)(); /* redraws obj controlled by dial */ } DIAL; typedef struct { Window win; /* parent window */ int x,y,w,h; /* size of button rectangle */ int lit; /* if true, invert colors */ int active; /* if false, stipple gray */ int toggle; /* if true, clicking toggles state */ unsigned long fg,bg; /* colors */ char *str; /* string in button */ Pixmap pix; /* use pixmap instead of string */ int pw,ph; /* size of pixmap */ int style; /* ... */ int fwidth; /* width of frame */ } BUTT; typedef struct rbutt { Window win; /* parent window */ int x,y; /* position in parent */ char *str; /* the message string */ int selected; /* selected or not */ int active; /* selectable? */ struct rbutt *next; /* pointer to next in group */ unsigned long fg,bg; /* colors */ } RBUTT; typedef struct cbutt { Window win; /* parent window */ int x,y; /* position in parent */ char *str; /* the message string */ int val; /* 1=selected, 0=not */ int active; /* selectable? */ unsigned long fg,bg; /* colors */ } CBUTT; typedef struct mbutt { Window win; /* parent window */ int x,y,w,h; /* position in parent */ char *title; /* title string in norm state */ int selected; /* item# selected, or -1 */ int active; /* selectable? */ char **list; /* list of strings in menu */ int nlist; /* # of strings in menu */ Pixmap pix; /* use pixmap instd of string */ int pw,ph; /* size of pixmap */ unsigned long fg,bg; /* colors */ Window mwin; /* popup menu window */ } MBUTT; typedef struct { Window win; /* window */ int x,y,w,h; /* size of window */ unsigned long fg,bg; /* colors */ char **str; /* ptr to list of strings */ int nstr; /* number of strings */ int selected; /* number of 'selected' string */ int nlines; /* number of lines shown at once */ SCRL scrl; /* scrollbar that controls list */ int filetypes; /* true if filetype icons to be drawn*/ int dirsonly; /* if true, only dirs selectable */ } LIST; #define MAX_GHANDS 16 /* maximum # of GRAF handles */ #define N_GFB 6 #define GFB_SPLINE 0 #define GFB_LINE 1 #define GFB_ADDH 2 #define GFB_DELH 3 #define GFB_RESET 4 #define GFB_GAMMA 5 #define GVMAX 8 typedef struct { Window win; /* window ID */ Window gwin; /* graph subwindow */ int spline; /* spline curve or lines? */ int entergamma; /* currently entering gamma value */ int gammamode; /* currently using gamma function */ double gamma; /* gamma value (if gammamode) */ int nhands; /* current # of handles */ XPoint hands[MAX_GHANDS]; /* positions of handles */ byte func[256]; /* output function of GRAF */ BUTT butts[N_GFB]; /* control buttons */ u_long fg,bg; /* colors */ char *str; /* title string */ char gvstr[GVMAX+1]; /* gamma value input string */ } GRAF; typedef struct { int spline; int entergamma; int gammamode; double gamma; int nhands; XPoint hands[MAX_GHANDS]; char gvstr[GVMAX+1]; } GRAF_STATE; /* MACROS */ #define CENTERX(f,x,str) ((x)-XTextWidth(f,str,strlen(str))/2) #define CENTERY(f,y) ((y)-((f->ascent+f->descent)/2)+f->ascent) /* RANGE forces a to be in the range b..c (inclusive) */ #define RANGE(a,b,c) { if (a < b) a = b; if (a > c) a = c; } /* PTINRECT returns '1' if x,y is in rect (inclusive) */ #define PTINRECT(x,y,rx,ry,rw,rh) \ ((x)>=(rx) && (y)>=(ry) && (x)<=(rx)+(rw) && (y)<=(ry)+(rh)) /* MONO returns total intensity of r,g,b components */ #define MONO(rd,gn,bl) (((rd)*11 + (gn)*16 + (bl)*5) >> 5) /*.33R+ .5G+ .17B*/ /* ISPIPE returns true if the passed in character is considered the start of a 'load-from-pipe' or 'save-to-pipe' string */ #define ISPIPE(c) ((c)=='!' || (c)=='|') /* X stuff */ WHERE Display *theDisp; WHERE int theScreen; WHERE unsigned int ncells, dispWIDE, dispHIGH, dispDEEP; WHERE unsigned int vrWIDE, vrHIGH, maxWIDE, maxHIGH; WHERE Colormap theCmap, LocalCmap; WHERE Window rootW, mainW, vrootW; WHERE GC theGC; WHERE unsigned long black, white, fg, bg, infofg, infobg; WHERE unsigned long hicol, locol; WHERE unsigned long blkRGB, whtRGB; WHERE Font mfont, monofont; WHERE XFontStruct *mfinfo, *monofinfo; WHERE Visual *theVisual; WHERE Cursor arrow, cross, tcross, zoom, inviso; WHERE Pixmap iconPix, iconmask; WHERE int cmapinstalled, showzoomcursor; /* global vars used by LOAD routines */ WHERE byte *pic; /* ptr to loaded picture */ WHERE int pWIDE,pHIGH; /* size of 'pic' */ WHERE byte r[256],g[256],b[256]; /* colormap */ WHERE char *cmd; /* program name for printf's */ WHERE int DEBUG; /* print debugging info */ WHERE int mono; /* true if displaying grayscale */ WHERE char formatStr[80]; /* short-form 'file format' */ /* more global variables, used by xv and xvmisc */ WHERE byte *cpic; /* cropped version of pic */ WHERE int cWIDE, cHIGH, /* size of cropped region */ cXOFF, cYOFF; /* offset of region from 0,0 of pic */ WHERE byte *epic; /* expanded version of cpic */ /* points to pic when at 1:1 expansion */ /* this is converted to 'theImage' */ WHERE int eWIDE, eHIGH; /* size of epic */ WHERE unsigned int normFact; /* factor to shrink picture by for 'norm' */ WHERE int p_offx, p_offy; /* offset of reparented windows */ WHERE int ch_offx,ch_offy; /* ChngAttr ofst for reparented windows */ WHERE int geomXabs,geomXsgn, /* geometry spec for new root modes */ geomYabs,geomYsgn; WHERE byte rorg[256], gorg[256], borg[256]; /* ORIGINAL colormap */ WHERE byte rcmap[256], gcmap[256], bcmap[256]; /*post-cmap-editing*/ WHERE byte rdisp[256],gdisp[256],bdisp[256]; /* DISPLAYED colors */ WHERE byte colAllocOrder[256]; /* order to allocate cols */ WHERE unsigned long freecols[256]; /* list of pixel values to free */ WHERE byte rwpc2pc[256]; /* mapping of shared pixels in -rw mode */ WHERE int nfcols; /* number of colors to free */ WHERE unsigned long cols[256]; /* maps pic pixel values to X pixel vals */ WHERE int fc2pcol[256]; /* maps freecols into pic pixel values */ WHERE int numcols; /* # of desired colors in picture */ WHERE byte fsgamcr[256]; /* gamma correction curve (for FS dither) */ WHERE XImage *theImage; /* X version of epic */ WHERE int ncols; /* max # of (different) colors to alloc */ WHERE char str[128], /* dummy string used for error messages */ basefname[128]; /* 'nice' part of current filename */ WHERE int bwidth, /* border width of created windows */ noglob, /* force to only use colors it alloced */ perfect, /* perfect color. install own colormap */ fixedaspect, /* fixed aspect ratio */ conv24, /* 24to8 algorithm to use (CONV24_*) */ ninstall, /* true if using icccm-complaint WM (a WM that will does install CMaps */ useroot, /* true if we should draw in rootW */ nolimits, /* No limits on picture size */ resetroot, /* true if we should clear in window mode */ noqcheck, /* true if we should NOT do QuickCheck */ rwcolor, /* true if we should use R/W color cells */ rwthistime, /* true if we DID use R/W color cells */ owncmap, /* true if we should always create cmap */ epicmode, /* either SMOOTH, DITH, or RAW */ autoclose, /* if true, autoclose when iconifying */ xerrcode; /* errorcode of last X error */ WHERE float defaspect, /* default aspect ratio to use */ normaspect; /* normal aspect ratio of this picture */ WHERE int crx1, cry1, /* dimensions of cropping rectangle */ crx2, cry2; WHERE unsigned long rootbg, rootfg; /* fg/bg for root border */ WHERE int waitsec; /* secs btwn pics. -1=wait for event */ WHERE int waitloop; /* loop at end of slide show? */ WHERE int automax; /* maximize pic on open */ WHERE int rootMode; /* mode used for -root images */ WHERE int nostat; /* if true, don't stat() in LdCurDir */ WHERE int ctrlColor; /* whether or not to use colored butts */ WHERE char *def_str; /* used by rd_*() routines */ WHERE int def_int; WHERE char *tmpdir; /* equal to "/tmp" or $TMPDIR env var */ /* stuff used for 'info' box */ WHERE Window infoW; WHERE int infoUp; /* boolean: whether infobox is visible */ WHERE int infoMode; /* stuff used for 'ctrl' box */ WHERE Window ctrlW; WHERE int ctrlUp; /* boolean: whether ctrlbox is visible */ WHERE char *namelist[MAXNAMES]; /* list of file names from argv */ WHERE char *dispnames[MAXNAMES]; /* truncated names shown in listbox */ WHERE int numnames, curname; WHERE LIST nList; WHERE BUTT but[NBUTTS]; /* command buttons in ctrl window */ WHERE Pixmap grayTile, grayStip; /* for drawing dim things */ WHERE MBUTT dispMB; /* display mode menu button */ WHERE MBUTT conv24MB; /* 24-to-8 conversion mode mbutt */ /* stuff used for 'directory' box */ WHERE Window dirW, dnamW; WHERE int dirUp; /* is dirW mapped or not */ WHERE LIST dList; /* list of filenames in current directory */ WHERE BUTT dbut[S_NBUTTS]; WHERE CBUTT browseCB; WHERE CBUTT savenormCB; /* stuff used for 'gamma' box */ WHERE Window gamW; WHERE int gamUp; /* is gamW mapped or not */ WHERE BUTT gbut[G_NBUTTS]; WHERE int editColor; /* currently selected color # */ WHERE int hsvmode; /* true if in HSVmode */ WHERE int cellgroup[256], curgroup, maxgroup; /* grouped colorcell stuff */ WHERE int cmapInGam; /* stuff used for 'ps' box */ WHERE Window psW; WHERE int psUp; /* is psW mapped, or what? */ WHERE CBUTT encapsCB, pscompCB; #ifdef HAVE_JPEG /* stuff used for 'jpeg' box */ WHERE Window jpegW; WHERE int jpegUp; /* is jpegW mapped, or what? */ #endif #ifdef HAVE_TIFF /* stuff used for 'tiff' box */ WHERE Window tiffW; WHERE int tiffUp; /* is tiffW mapped, or what? */ #endif #undef WHERE /* function declarations for externally-callable functions */ #ifdef __STDC__ /****************************** XV.C ****************************/ void FixAspect(int, int *, int *); int DeleteCmd(void); void HandleDispMode(void); char *lower_str(char *); int rd_int(char *); int rd_str(char *); int rd_flag(char *); int rd_str_cl(char *, char *); /****************************** XVEVENT.C ****************************/ int EventLoop(void); int HandleEvent(XEvent *, int *); void DrawWindow(int,int,int,int); void WResize(int, int); void WRotate(void); void WCrop(int, int); void WUnCrop(void); void GetWindowPos(XWindowAttributes *); void SetWindowPos(XWindowAttributes *); void InvCropRect(void); void SetEpicMode(void); int xvErrorHandler(Display *, XErrorEvent *); /****************************** XVROOT.C ****************************/ void MakeRootPic(void); void ClearRoot(void); void SaverootInfo(void); void KillOldRootInfo(void); /*************************** XVMISC.C ***************************/ void StoreDeleteWindowProp(Window); Window CreateWindow(char *, char *, unsigned int, unsigned int, unsigned long, unsigned long); void CenterString(Window, char *, int, int); void ULineString(Window, char *, int, int); int StringWidth(char *); void FakeButtonPress(BUTT *); void GenExpose(Window, int, int, int, int); void DimRect(Window, int, int, int, int, u_long); void xvDestroyImage(XImage *); void SetCropString(int); void Warning(void); void FatalError(char *); void Quit(int); void LoadFishCursors(void); void WaitCursor(void); void SetCursors(int); void Timer(int); /*************************** XVCOLOR.C ***************************/ void SortColormap(void); void AllocColors(void); void AllocRWColors(void); Status xvAllocColor(Display *, Colormap, XColor *); void xvFreeColors(Display *, Colormap, unsigned long *, int, unsigned long); void FreeAllColors(void); void ApplyEditColor(int); /*************************** XVIMAGE.C ***************************/ void Resize(int, int); void DoZoom(int, int, int); void DoCrop(void); void UnCrop(void); void AutoCrop(void); void Rotate(int); void Flip(int); void FlipPic(byte *, int, int, int); void FSDither(byte *, int, int, byte *); void CreateXImage(void); /*************************** XVSMOOTH.C ***************************/ void Smooth(void); byte *Smooth24(void); void ColorDither(byte *, int, int); /*************************** XV24TO8.C **************************/ void Init24to8(void); int Conv24to8(byte *, int, int, int); /**************************** XVCTRL.C **************************/ void CreateCtrl(char *); void CtrlBox(int); void RedrawCtrl(int, int, int, int); int ClickCtrl(int, int); void DrawCtrlStr(void); void ScrollToCurrent(LIST *); void LSCreate(LIST *, Window, int, int, int, int, int, char **, int, unsigned long, unsigned long, void (*)(void), int, int); void LSRedraw(LIST *); int LSClick (LIST *, XButtonEvent *); void LSNewData(LIST *, char **, int); void LSKey(LIST *, int); /*************************** XVINFO.C ***************************/ void CreateInfo(char *); void InfoBox(int); void RedrawInfo(int, int, int, int); void SetInfoMode(int); #if defined(__STDC__) && !defined(NOSTDHDRS) void SetISTR(int, ...); #else void SetISTR(); #endif char *GetISTR(int); /**************************** XVDIR.C ***************************/ void CreateDirW(char *); void DirBox(int); void RedrawDirW(int,int,int,int); int ClickDirW(int, int); void LoadCurrentDirectory(void); void RedrawDDirW(void); void RedrawDNamW(void); void SelectDir(int); void TrackDDirW(int,int); int DirKey(int); int DoSave(void); void SetDirFName(char *); char *GetDirFName(void); void SetDirRButt(int, int); int Globify(char *); FILE *OpenOutFile(char *); int CloseOutFile(FILE *, char *, int); byte *HandleBWandReduced(int, int *, byte **, byte **, byte **); /**************************** XVGAM.C **************************/ void CreateGam(char *); int GamCheckEvent(XEvent *); void GamBox(int); void NewCMap(); void RedrawCMap(); void ChangeEC(int); void ApplyECctrls(void); void GenerateFSGamma(void); void GammifyColors(void); void Gammify1(int); void rgb2hsv(int, int, int, double *, double *, double *); void hsv2rgb(double, double, double, int *, int *, int *); /*************************** XVSCRL.C ***************************/ void SCCreate (SCRL *, Window, int, int, int, int, int, int, int, int, unsigned long, unsigned long, void (*)(void)); void SCSetRange(SCRL *, int, int, int, int); int SCSetVal (SCRL *, int); void SCRedraw (SCRL *); void SCTrack (SCRL *, int, int); /*************************** XVDIAL.C ***************************/ void DCreate (DIAL *, Window, int, int, int, int, int, int, int, int, unsigned long, unsigned long, char *, char *); void DSetRange(DIAL *, int, int, int, int); void DSetVal (DIAL *, int); void DSetActive(DIAL *, int); void DRedraw (DIAL *); int DTrack (DIAL *, int, int); /**************************** XVBUTT.C ***************************/ void BTCreate(BUTT *, Window, int, int, int, int, char *, unsigned long, unsigned long); void BTSetActive(BUTT *, int); void BTRedraw(BUTT *); int BTTrack (BUTT *); RBUTT *RBCreate(RBUTT *, Window, int, int, char*, unsigned long, unsigned long); void RBRedraw(RBUTT *, int); void RBSelect(RBUTT *, int); int RBWhich(RBUTT *); int RBCount(RBUTT *); void RBSetActive(RBUTT *, int, int); int RBClick(RBUTT *, int, int); int RBTrack(RBUTT *, int); void CBCreate(CBUTT *, Window, int, int, char *, u_long, u_long); void CBRedraw(CBUTT *); void CBSetActive(CBUTT *, int); int CBClick(CBUTT *,int,int); int CBTrack(CBUTT *); void MBCreate(MBUTT *, Window, int, int, int, int, char *, char **, int, u_long, u_long); void MBRedraw(MBUTT *); void MBSetActive(MBUTT *, int); int MBClick(MBUTT *, int, int); int MBTrack(MBUTT *); /**************************** XVGRAF.C ***************************/ void CreateGraf(GRAF *, Window, int, int, u_long, u_long, char *); void InitGraf (GRAF *); void RedrawGraf(GRAF *, int, int, int, int); int ClickGraf (GRAF *, Window, int, int); int GrafKey (GRAF *, char *); void GenerateGrafFunc(GRAF *, int); void Graf2Str (GRAF_STATE *, char *); int Str2Graf (GRAF_STATE *, char *); void GetGrafState (GRAF *, GRAF_STATE *); int SetGrafState (GRAF *, GRAF_STATE *); void InitSpline(int *, int *, int, double *); double EvalSpline(int *, int *, double *, int, double); /**************************** XVGIF.C ***************************/ int LoadGIF(char *, int); /*************************** XVGIFWR.C **************************/ int WriteGIF(FILE *, byte *, int, int, byte *, byte *, byte *, int, int); /**************************** XVPM.C ****************************/ int LoadPM(char *, int); int WritePM(FILE *, byte *, int, int, byte *, byte *, byte *, int, int); /**************************** XVPBM.C ***************************/ int LoadPBM(char *, int); int WritePBM(FILE *, byte *, int, int, byte *, byte *, byte *, int, int, int); /**************************** XVXBM.C ***************************/ int LoadXBM(char *, int); int WriteXBM(FILE *, byte *, int, int, char *); /**************************** XVSUNRAS.C ***************************/ int LoadSunRas(char *, int); int WriteSunRas(FILE *, byte *, int, int, byte *, byte *, byte*, int, int, int); /**************************** XVJPEG.C ***************************/ int LoadJFIF(char *, int); void CreateJPEGW(void); void JPEGDialog(int); int JPEGCheckEvent(XEvent *); void JPEGSaveParams(char *, int); /**************************** XVTIFF.C ***************************/ int LoadTIFF(char *, int); void CreateTIFFW(); void TIFFDialog(int); int TIFFCheckEvent(XEvent *); void TIFFSaveParams(char *, int); /*************************** XVPS.C ***************************/ void CreatePSD(char *); void PSDialog(int); int PSCheckEvent(XEvent *); void PSSaveParams(char *, int); void PSResize(void); /*************************** XVPOPUP.C ***************************/ void CenterMapWindow(Window, int, int, int, int); int PopUp(char *, char **, int); void OpenAlert(char *); void CloseAlert(); int PSCheckEvent(XEvent *); void TextRect(Window, char *, int, int, int, int, u_long); /*************************** XVDFLT.C ***************************/ void LoadDfltPic(); void xbm2pic(char *, int, int, byte *, int, int, int, int, int); /**************************** XVGRAB.C ***************************/ int Grab(void); int LoadGrab(void); /**************************** XVRLE.C ***************************/ int LoadRLE(char *, int); #else /* using non-ANSI cc. Function defs, but no params */ /****************************** XV.C ****************************/ void FixAspect(), HandleDispMode(); int DeleteCmd(), rd_int(), rd_str(), rd_flag(), rd_str_cl(); char *lower_str(); /****************************** XVEVENT.C ****************************/ int EventLoop(), HandleEvent(); void DrawWindow(), WResize(), WRotate(), WCrop(), WUnCrop(); void GetWindowPos(), SetWindowPos(), InvCropRect(), SetEpicMode(); int xvErrorHandler(); /****************************** XVROOT.C ****************************/ void MakeRootPic(), ClearRoot(), KillOldRootInfo(), SaveRootInfo(); /*************************** XVMISC.C ***************************/ void StoreDeleteWindowProp(); Window CreateWindow(); int StringWidth(); void CenterString(), ULineString(), FakeButtonPress(), GenExpose(); void DimRect(), SetCropString(), Warning(), FatalError(), Quit(); void LoadFishCursors(), WaitCursor(), SetCursors(), Timer(); void xvDestroyImage(); /*************************** XVCOLOR.C ***************************/ Status xvAllocColor(); void SortColormap(), AllocColors(), AllocRWColors(); void xvFreeColors(), FreeAllColors(), ApplyEditColor(); /*************************** XVIMAGE.C ***************************/ void Resize(), DoZoom(), DoCrop(), UnCrop(), AutoCrop(), Rotate(), Flip(); void FlipPic(), FSDither(), CreateXImage(); /*************************** XVSMOOTH.C ***************************/ void Smooth(), ColorDither(); byte *Smooth24(); /*************************** XV24TO8.C **************************/ void Init24to8(); int Conv24to8(); /**************************** XVCTRL.C **************************/ void CreateCtrl(), CtrlBox(), RedrawCtrl(), DrawCtrlStr(), ScrollToCurrent(); int ClickCtrl(); void LSCreate(), LSRedraw(), LSNewData(), LSKey(); int LSClick(); /*************************** XVINFO.C ***************************/ void CreateInfo(), InfoBox(), RedrawInfo(), SetInfoMode(), SetISTR(); char *GetISTR(); /**************************** XVDIR.C ***************************/ void CreateDirW(), DirBox(), RedrawDirW(), LoadCurrentDirectory(); int ClickDirW(), DoSave(), DirKey(); void RedrawDDirW(), RedrawDNamW(), SelectDir(), TrackDDirW(); void SetDirFName(), SetDirRButt(); char *GetDirFName(); int Globify(), CloseOutFile(); FILE *OpenOutFile(); byte *HandleBWandReduced(); /**************************** XVGAM.C **************************/ void CreateGam(); int GamCheckEvent(); void GamBox(), NewCMap(), RedrawCMap(); void ChangeEC(), ApplyECctrls(); void GenerateFSGamma(), GammifyColors(); void Gammify1(), rgb2hsv(), hsv2rgb(); /*************************** XVSCRL.C ***************************/ void SCCreate(), SCSetRange(), SCRedraw(), SCTrack(); int SCSetVal(); /*************************** XVDIAL.C ***************************/ void DCreate(), DSetRange(), DSetVal(), DRedraw(), DSetActive(); int DTrack(); /**************************** XVBUTT.C ***************************/ void BTCreate(), BTSetActive(), BTRedraw(); int BTTrack(); RBUTT *RBCreate(); void RBRedraw(), RBSelect(), RBSetActive(); int RBWhich(), RBCount(), RBClick(), RBTrack(); void CBCreate(), CBRedraw(), CBSetActive(); int CBClick(), CBTrack(); void MBCreate(), MBRedraw(), MBSetActive(); int MBClick(), MBTrack(); /*************************** XVGRAF.C ***************************/ void CreateGraf(), InitGraf(), RedrawGraf(), GenerateGrafFunc(); void Graf2Str(), GetGrafState(), InitSpline(); int ClickGraf(), GrafKey(), Str2Graf(), SetGrafState(); double EvalSpline(); /**************************** XVGIF.C ***************************/ int LoadGIF(); /*************************** XVGIFWR.C **************************/ int WriteGIF(); /**************************** XVPM.C ****************************/ int LoadPM(), WritePM(); /**************************** XVPBM.C ***************************/ int LoadPBM(), WritePBM(); /**************************** XVXBM.C ***************************/ int LoadXBM(), WriteXBM(); /**************************** XVSUNRAS.C ***************************/ int LoadSunRas(), WriteSunRas(); /**************************** XVJPEG.C ***************************/ int LoadJFIF(), JPEGCheckEvent(); void CreateJPEGW(), JPEGDialog(), JPEGSaveParams(); /**************************** XVTIFF.C ***************************/ int LoadTIFF(); void CreateTIFFW(), TIFFDialog(), TIFFSaveParams(); int TIFFCheckEvent(); /*************************** XVPS.C ***************************/ void CreatePSD(), PSDialog(), PSSaveParams(), PSResize(); int PSCheckEvent(); /*************************** XVPOPUP.C ***************************/ void CenterMapWindow(), OpenAlert(), CloseAlert(); int PopUp(), PUCheckEvent(); void TextRect(); /*************************** XVDFLT.C ***************************/ void LoadDfltPic(), xbm2pic(); /**************************** XVGRAB.C ***************************/ int Grab(), LoadGrab(); /**************************** XVRLE.C ***************************/ int LoadRLE(); #endif DNamW(void); void SelectDir(int); void TrackDDirW(int,int); int DirKey(int); int DoSave(void); void SetDirFName(char *); char *GetDirFName(void); void SetDirRButt(int, int); int Globify(char *); FILE *OpenOutFile(char *); int CloseOutFile(FILE *, char *, int); byte *HandleBWandReduced(int, int *, byte **, byte **, byte **); /**************************** XVGAM.C **************************/ void CreateGam(char *); int GamCheckxvctrl.c000644 002300 001754 00000047043 05233406765 013247 0ustar00sampurehons000000 000000 /* * xvctrl.c - Control box handling functions * * callable functions: * * CreateCtrl(geom) - creates the ctrlW window. Doesn't map it. * CtrlBox(vis) - random processing based on value of 'vis' * maps/unmaps window, etc. * RedrawCtrl(x,y,w,h) - called by 'expose' events * ClickCtrl(x,y) * DrawCtrlStr() - called to redraw 'ISTR_INFO' string in ctrlW * ScrollToCurrent() - called when 'curname' is changed * * LSCreate() - creates a listbox * LSRedraw() - redraws 'namelist' box * LSClick() - operates list box * LSNewData() - called when strings or number of them change * LSKey() - called to handle page up/down, arrows * */ /* * Modified: Sam Yates (syates@spam.maths.adelaide.edu.au) * Jul 92 to extend root image positioning options */ /* * Copyright 1989, 1990, 1991, 1992 by John Bradley and * 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 expressed or implied warranty. * * The author may be contacted via: * US Mail: John Bradley * GRASP Lab, Room 301C * 3401 Walnut St. * Philadelphia, PA 19104 * * Phone: (215) 898-8813 * EMail: bradley@cis.upenn.edu */ #include "xv.h" #include "bitmaps.h" #define DBLCLKTIME 500 /* double-click speed in milliseconds */ #define INACTIVE(lptr, item) ((lptr)->filetypes && (lptr)->dirsonly && \ (item) >= 0 && (item) < (lptr)->nstr && \ (lptr)->str[(item)][0] != C_DIR && \ (lptr)->str[(item)][0] != C_LNK) #define NLINES 11 /* # of lines in list control (keep odd) */ #define LISTW CTRL_LISTW #define BUTTW 71 /* must be odd for 'half' buttons to work out */ #define BUTTH 24 static int listh; /* height of list/scrl controls */ static int ptop; /* y-coord of top of button area in ctrlW */ static Pixmap fifoPix, chrPix, dirPix, blkPix, lnkPix, sockPix, regPix; static Pixmap rotlPix, rotrPix, fliphPix, flipvPix; static XRectangle butrect; static char *dispMList[] = { "Window", "Root: tiled", "Root: integer tiled", "Root: mirrored", "Root: integer mirrored", "Root: center tiled", "Root: centered", "Root: centered, warp", "Root: centered, brick", "Root: centered, left", "Root: centered, right", "Root: centered, top", "Root: centered, bottom", "Root: (at geom spec)" }; static char *conv24MList[] = { "quick (fastest)", "slower (default)", "best (non-dithered)" }; #ifdef __STDC__ static void drawSel(LIST *, int); static void RedrawNList(void); #else static void drawSel(), RedrawNList(); #endif /***************************************************/ void CreateCtrl(geom) char *geom; { int i; double skip; XClassHint classh; ctrlW = CreateWindow("xv controls", geom, CTRLWIDE,CTRLHIGH,infofg,infobg); if (!ctrlW) FatalError("can't create controls window!"); classh.res_name = "xv"; classh.res_class = "XVcontrols"; XSetClassHint(theDisp, ctrlW, &classh); StoreDeleteWindowProp(ctrlW); grayTile = XCreatePixmapFromBitmapData(theDisp, ctrlW, gray25_bits, gray25_width, gray25_height, infofg, infobg, dispDEEP); grayStip = XCreatePixmapFromBitmapData(theDisp, ctrlW, gray50_bits, gray50_width, gray50_height, 1, 0, 1); fifoPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_fifo_bits, i_fifo_width, i_fifo_height, 1, 0, 1); chrPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_chr_bits, i_chr_width, i_chr_height, 1,0,1); dirPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_dir_bits, i_dir_width, i_dir_height, 1,0,1); blkPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_blk_bits, i_blk_width, i_blk_height, 1,0,1); lnkPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_lnk_bits, i_lnk_width, i_lnk_height, 1,0,1); sockPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_sock_bits, i_sock_width, i_sock_height, 1,0,1); regPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_reg_bits, i_reg_width, i_reg_height, 1,0,1); rotlPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, h_rotl_bits, h_rotl_width, h_rotl_height, 1, 0, 1); rotrPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, h_rotr_bits, h_rotr_width, h_rotr_height, 1, 0, 1); fliphPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, fliph_bits, fliph_width, fliph_height, 1, 0, 1); flipvPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, flipv_bits, flipv_width, flipv_height, 1, 0, 1); if (ctrlColor) XSetWindowBackground(theDisp, ctrlW, locol); else XSetWindowBackgroundPixmap(theDisp, ctrlW, grayTile); /* create doo-wahs */ listh = LINEHIGH * NLINES; LSCreate(&nList, ctrlW, 10, 10+CHIGH+1, LISTW, listh, NLINES, dispnames, numnames, infofg, infobg, RedrawNList, 0, 0); nList.selected = 0; /* default to first name selected */ i = listh-BUTTH; skip = ((double) (listh - 2*19 - 4*BUTTH)) / 5.0; BTCreate(&but[BNEXT], ctrlW, 298, nList.y + 2*19 + (int)(2*skip), 60, BUTTH, "Next", infofg, infobg); BTCreate(&but[BPREV], ctrlW, 298, nList.y + 2*19 + BUTTH + (int)(3*skip), 60, BUTTH, "Previous", infofg, infobg); BTCreate(&but[BINFO], ctrlW, 298, nList.y + 2*19 + 2*BUTTH + (int)(4*skip), 60, BUTTH, "Info", infofg, infobg); BTCreate(&but[BGAMMA], ctrlW,298, nList.y + 2*19 + 3*BUTTH + (int)(5*skip), 60, BUTTH, "ColEdit", infofg, infobg); BTCreate(&but[BLOAD], ctrlW, 368, but[BNEXT].y, 60, BUTTH, "Load", infofg, infobg); BTCreate(&but[BSAVE], ctrlW, 368, but[BPREV].y, 60, BUTTH, "Save", infofg, infobg); BTCreate(&but[BDELETE], ctrlW, 368, but[BINFO].y, 60, BUTTH, "Delete", infofg, infobg); BTCreate(&but[BQUIT], ctrlW, 368, but[BGAMMA].y, 60, BUTTH, "Quit", infofg, infobg); #define BXSPACE (BUTTW+1) #define BYSPACE (BUTTH+1) ptop = CTRLHIGH - (3*BYSPACE + 5 + 4); #define BX0 ((CTRLWIDE - (BXSPACE*6))/2) #define BX1 (BX0 + BXSPACE) #define BX2 (BX0 + BXSPACE*2) #define BX3 (BX0 + BXSPACE*3) #define BX4 (BX0 + BXSPACE*4) #define BX5 (BX0 + BXSPACE*5) #define BY0 (ptop+5) #define BY1 (BY0 + BYSPACE) #define BY2 (BY0 + BYSPACE*2) butrect.x = BX0-1; butrect.y = BY0-1; butrect.width = 6*BXSPACE + 1; butrect.height = 3*BYSPACE + 1; BTCreate(&but[BCROP], ctrlW,BX0,BY0,BUTTW,BUTTH,"Crop", infofg,infobg); BTCreate(&but[BUNCROP], ctrlW,BX0,BY1,BUTTW,BUTTH,"UnCrop", infofg,infobg); BTCreate(&but[BACROP], ctrlW,BX0,BY2,BUTTW,BUTTH,"AutoCrop", infofg,infobg); BTCreate(&but[BNORM], ctrlW,BX1,BY0,BUTTW,BUTTH,"Normal", infofg,infobg); BTCreate(&but[BMAX], ctrlW,BX1,BY1,BUTTW,BUTTH,"Max Size", infofg,infobg); BTCreate(&but[BMAXPECT],ctrlW,BX1,BY2,BUTTW,BUTTH,"Maxpect", infofg,infobg); BTCreate(&but[BUP2], ctrlW,BX2,BY0,BUTTW,BUTTH,"Dbl Size", infofg,infobg); BTCreate(&but[BDN2], ctrlW,BX2,BY1,BUTTW,BUTTH,"Half Size",infofg,infobg); BTCreate(&but[B4BY3], ctrlW,BX2,BY2,BUTTW,BUTTH,"4x3", infofg,infobg); BTCreate(&but[BUP10], ctrlW,BX3,BY0,BUTTW,BUTTH,"+10%", infofg,infobg); BTCreate(&but[BDN10], ctrlW,BX3,BY1,BUTTW,BUTTH,"-10%", infofg,infobg); BTCreate(&but[BASPECT], ctrlW,BX3,BY2,BUTTW,BUTTH,"Aspect", infofg,infobg); BTCreate(&but[BRAW], ctrlW,BX4,BY0,BUTTW,BUTTH,"Raw", infofg,infobg); BTCreate(&but[BDITH], ctrlW,BX4,BY1,BUTTW,BUTTH,"Dither", infofg,infobg); BTCreate(&but[BSMOOTH], ctrlW,BX4,BY2,BUTTW,BUTTH,"Smooth", infofg,infobg); BTCreate(&but[BROTL], ctrlW,BX5,BY0,BUTTW/2,BUTTH, "", infofg,infobg); BTCreate(&but[BROTR], ctrlW,BX5+BUTTW/2 + 1,BY0,BUTTW/2,BUTTH, "", infofg,infobg); BTCreate(&but[BFLIPH], ctrlW,BX5,BY1,BUTTW/2,BUTTH, "", infofg,infobg); BTCreate(&but[BFLIPV], ctrlW,BX5+BUTTW/2 + 1,BY1,BUTTW/2,BUTTH, "", infofg,infobg); BTCreate(&but[BGRAB], ctrlW,BX5,BY2,BUTTW,BUTTH,"Grab",infofg,infobg); but[BROTL].pix = rotlPix; but[BROTL].pw = h_rotl_width; but[BROTL].ph = h_rotl_height; but[BROTR].pix = rotrPix; but[BROTR].pw = h_rotr_width; but[BROTR].ph = h_rotr_height; but[BFLIPH].pix = fliphPix; but[BFLIPH].pw = fliph_width; but[BFLIPH].ph = fliph_height; but[BFLIPV].pix = flipvPix; but[BFLIPV].pw = flipv_width; but[BFLIPV].ph = flipv_height; if (numnames<1) BTSetActive(&but[BDELETE],0); XMapSubwindows(theDisp, ctrlW); /* have to create dispMB after XMapSubWindows, as we *don't* want the popup mapped */ MBCreate(&dispMB, ctrlW, 298, nList.y, 128, 19, "Display Modes", dispMList, RM_MAX+2, infofg, infobg); if (!useroot) dispMB.selected = 0; else dispMB.selected = rootMode + 1; MBCreate(&conv24MB, ctrlW, 298, nList.y + 19 + (int) skip, 128, 19, "24-bit Conversion", conv24MList, 3, infofg, infobg); conv24MB.selected = conv24; } /***************************************************/ void CtrlBox(vis) int vis; { if (vis) XMapRaised(theDisp, ctrlW); else XUnmapWindow(theDisp, ctrlW); ctrlUp = vis; } /***************************************************/ void RedrawCtrl(x,y,w,h) int x,y,w,h; { char foo[40]; int i; XRectangle xr; xr.x = x; xr.y = y; xr.width = w; xr.height = h; XSetClipRectangles(theDisp, theGC, 0,0, &xr, 1, Unsorted); XSetForeground(theDisp, theGC, infofg); XSetBackground(theDisp, theGC, infobg); XDrawLine(theDisp, ctrlW, theGC, 0, ptop, CTRLWIDE, ptop); if (numnames != 1) sprintf(foo,"%d files",numnames); else strcpy(foo,"1 file"); XSetForeground(theDisp, theGC, infobg); XFillRectangle(theDisp,ctrlW, theGC, 10+1,5+1,StringWidth(foo)+4,CHIGH+2); XSetForeground(theDisp,theGC,infofg); XDrawRectangle(theDisp,ctrlW, theGC, 10,5,StringWidth(foo)+5,CHIGH+3); XDrawString(theDisp, ctrlW, theGC, 10+3, 5+ASCENT+2, foo, strlen(foo)); XSetForeground(theDisp,theGC,infofg); XDrawRectangles(theDisp, ctrlW, theGC, &butrect, 1); for (i=0; ix, bp->y, bp->w, bp->h)) break; } if (iselected > lst->scrl.val && lst->selected < lst->scrl.val + lst->nlines-1) LSRedraw(lst); else { halfway = (lst->nlines)/2; /* offset to the halfway pt. of the list */ if (!SCSetVal(&lst->scrl, lst->selected - halfway)) LSRedraw(lst); } } /***************************************************/ static void RedrawNList() { LSRedraw(&nList); } /***************** LIST STUFF *********************/ /***************************************************/ void LSCreate(lp, win, x, y, w, h, nlines, strlist, nstr, fg, bg, fptr, typ, donly) LIST *lp; Window win; int x,y,w,h,nlines,nstr,typ,donly; unsigned long fg, bg; char **strlist; /* a pointer to a list of strings */ void (*fptr)(); { lp->win = XCreateSimpleWindow(theDisp,win,x,y,w,h,1,infofg,infobg); if (!lp->win) FatalError("can't create list window!"); lp->x = x; lp->y = y; lp->w = w; lp->h = h; lp->fg = fg; lp->bg = bg; lp->str = strlist; lp->nstr = nstr; lp->selected = -1; /* no initial selection */ lp->nlines = nlines; lp->filetypes= typ; lp->dirsonly = donly; XSelectInput(theDisp, lp->win, ExposureMask | ButtonPressMask); SCCreate(&lp->scrl, win, x+w, y, 1, h, 0, nstr-nlines, curname, nlines-1, fg, bg, fptr); } /***************************************************/ void LSNewData(lp, strlist, nstr) LIST *lp; char **strlist; int nstr; { lp->str = strlist; lp->nstr = nstr; lp->selected = -1; /* no initial selection */ SCSetRange(&lp->scrl, 0, nstr - lp->nlines, 0, lp->nlines-1); } /***************************************************/ static void drawSel(lp,j) LIST *lp; int j; { int i, inactive; unsigned long fg, bg; inactive = INACTIVE(lp,j); i = j - lp->scrl.val; if (i<0 || i>=lp->nlines) return; /* off screen */ if (j == lp->selected && !inactive && jnstr) { fg = lp->bg; bg = lp->fg; } /* invert */ else { fg = lp->fg; bg = lp->bg; } XSetForeground(theDisp, theGC, bg); XFillRectangle(theDisp, lp->win, theGC, 0,i*LINEHIGH, lp->w, LINEHIGH); if (j>=0 && jnstr) { /* only draw string if valid */ /* make non-dirs inactive, if dirsonly and filetypes */ XSetForeground(theDisp, theGC, fg); XSetBackground(theDisp, theGC, bg); if (!lp->filetypes) XDrawString(theDisp, lp->win, theGC, 3, i*LINEHIGH + ASCENT + 1, lp->str[j], strlen(lp->str[j])); else { int ypos = i*LINEHIGH + (LINEHIGH - i_fifo_height)/2; if (lp->str[j][0] == C_FIFO) XCopyPlane(theDisp, fifoPix, lp->win, theGC, 0, 0, i_fifo_width, i_fifo_height, 3, ypos, 1L); else if (lp->str[j][0] == C_CHR) XCopyPlane(theDisp, chrPix, lp->win, theGC, 0, 0, i_chr_width, i_chr_height, 3, ypos, 1L); else if (lp->str[j][0] == C_DIR) XCopyPlane(theDisp, dirPix, lp->win, theGC, 0, 0, i_dir_width, i_dir_height, 3, ypos, 1L); else if (lp->str[j][0] == C_BLK) XCopyPlane(theDisp, blkPix, lp->win, theGC, 0, 0, i_blk_width, i_blk_height, 3, ypos, 1L); else if (lp->str[j][0] == C_LNK) XCopyPlane(theDisp, lnkPix, lp->win, theGC, 0, 0, i_lnk_width, i_lnk_height, 3, ypos, 1L); else if (lp->str[j][0] == C_SOCK) XCopyPlane(theDisp, sockPix, lp->win, theGC, 0, 0, i_sock_width, i_sock_height, 3, ypos, 1L); else /* lp->str[j][0] == C_REG */ XCopyPlane(theDisp, regPix, lp->win, theGC, 0, 0, i_reg_width, i_reg_height, 3, ypos, 1L); XDrawString(theDisp, lp->win, theGC, 3 + i_fifo_width + 3, i*LINEHIGH + ASCENT + 1, lp->str[j]+1, strlen(lp->str[j]+1)); } } } /***************************************************/ void LSRedraw(lp) LIST *lp; { int i; for (i = lp->scrl.val; i < lp->scrl.val + lp->nlines; i++) drawSel(lp,i); } /***************************************************/ int LSClick(lp,ev) LIST *lp; XButtonEvent *ev; { /* returns '-1' normally. returns 0 -> numnames-1 for a goto */ Window rW, cW; int rx, ry, x, y, sel, oldsel; unsigned int mask; static Time lasttime=0; static int lastsel = -1; x = ev->x; y = ev->y; sel = lp->scrl.val + y/LINEHIGH; if (sel >= lp->nstr) sel = lp->selected; /* see if it's a double click */ if (ev->time - lasttime < DBLCLKTIME && sel==lastsel && (lp->scrl.val + y/LINEHIGH) < lp->nstr && !INACTIVE(lp,sel)) { return (sel); } lasttime = ev->time; lastsel = sel; /* if not clicked on selected, turn off selected and select new one */ if (sel != lp->selected) { oldsel = lp->selected; lp->selected = sel; drawSel(lp,sel); drawSel(lp,oldsel); XFlush(theDisp); } while (XQueryPointer(theDisp,lp->win,&rW,&cW,&rx,&ry,&x,&y,&mask)) { if (!(mask & Button1Mask)) break; /* button released */ if (y<0) { /* scroll up in list */ if (lp->scrl.val > lp->scrl.min) { lp->selected = lp->scrl.val - 1; SCSetVal(&lp->scrl, lp->scrl.val - 1); Timer(100); } } else if (y > lp->h) { /* scroll down in list */ if (lp->scrl.val < lp->scrl.max) { lp->selected = lp->scrl.val + lp->nlines; if (lp->selected >= lp->nstr) lp->selected = lp->nstr - 1; SCSetVal(&lp->scrl, lp->scrl.val + 1); Timer(100); } } else { sel = lp->scrl.val + y/LINEHIGH; if (sel >= lp->nstr) sel = lp->nstr - 1; if (sel != lp->selected && sel >= lp->scrl.val && sel < lp->scrl.val + lp->nlines) { /* dragged to another on current page */ oldsel = lp->selected; lp->selected = sel; drawSel(lp, sel); drawSel(lp, oldsel); XFlush(theDisp); } } } return(-1); } /***************************************************/ void LSKey(lp, key) LIST *lp; int key; { if (key==LS_PAGEUP) SCSetVal(&lp->scrl,lp->scrl.val - (lp->nlines-1)); else if (key==LS_PAGEDOWN) SCSetVal(&lp->scrl,lp->scrl.val + (lp->nlines-1)); else if (key==LS_HOME) SCSetVal(&lp->scrl,lp->scrl.min); else if (key==LS_END) SCSetVal(&lp->scrl,lp->scrl.max); else if (key==LS_LINEUP) { /* if the selected item visible, but not the top line */ if (lp->selected > lp->scrl.val && lp->selected <= lp->scrl.val + lp->nlines - 1) { /* then just move it */ lp->selected--; drawSel(lp, lp->selected); drawSel(lp, lp->selected+1); } /* if it's the top line... */ else if (lp->selected == lp->scrl.val) { if (lp->selected > 0) { lp->selected--; SCSetVal(&lp->scrl, lp->selected); } } /* if it's not visible, put it on the bottom line */ else { lp->selected = lp->scrl.val + lp->nlines - 1; if (lp->selected >= lp->nstr) lp->selected = lp->nstr - 1; drawSel(lp, lp->selected); } } else if (key==LS_LINEDOWN) { /* if the selected item visible, but not the bottom line */ if (lp->selected >= lp->scrl.val && lp->selected < lp->scrl.val + lp->nlines - 1) { if (lp->selected < lp->nstr-1) { /* then just move it */ lp->selected++; drawSel(lp, lp->selected); drawSel(lp, lp->selected-1); } } /* if it's the bottom line... */ else if (lp->selected == lp->scrl.val + lp->nlines - 1) { if (lp->selected < lp->nstr-1) { lp->selected++; SCSetVal(&lp->scrl, lp->scrl.val+1); } } /* if it's not visible, put it on the top line */ else { lp->selected = lp->scrl.val; drawSel(lp, lp->selected); } } } d(theDisp, ctrlW); else XUnmapWindow(theDisp, ctrlW); ctrlUp = vis; } /***************************************************/ void RedrawCtrl(x,y,w,h) int x,y,w,h; { char foo[40]; int i; XRectangle xr; xr.x = x; xr.y = y; xr.width = w; xr.height = h; XSetClipRectangles(theDisp, theGC, 0,0, &xr, 1, Unsorted); XSetForeground(theDisp, theGC, infofg); XSetBackground(theDisp, theGC, infobg); XDrawLine(theDisp, ctrlW, theGC, 0, ptop, CTRLWIDE, ptxvroot.c000644 002300 001754 00000023332 05233446344 013256 0ustar00sampurehons000000 000000 /* * xvroot.c - '-root' related code for XV * * Author: John Bradley, University of Pennsylvania * (bradley@cis.upenn.edu) * * Contains: * MakeRootPic() * ClearRoot() * SaveRootInfo() * KillOldRootInfo() */ /* * Modified 20th Jul 92 by Sam Yates to allow different root image * positioning options * */ /* * Copyright 1989, 1990, 1991, 1992 by John Bradley and * 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 expressed or implied warranty. * * The author may be contacted via: * US Mail: John Bradley * GRASP Lab, Room 301C * 3401 Walnut St. * Philadelphia, PA 19104 * * Phone: (215) 898-8813 * EMail: bradley@cis.upenn.edu */ #include "xv.h" #include "bitmaps.h" /* local function pre-definitions */ #ifdef __STDC__ static void killRootPix(void); #else static void killRootPix(); #endif /***********************************/ void MakeRootPic() { /* called after 'epic' has been generated (if we're using root). creates the XImage and the pixmap, sets the root to the new pixmap, and refreshes the display */ Pixmap tmpPix; int i, j, k, rpixw, rpixh, rmode; killRootPix(); rmode = rootMode; /* if eWIDE,eHIGH == dispWIDE,dispHIGH just use 'normal' mode to save mem */ if (rmode>=RM_CENTER && eWIDE==dispWIDE && eHIGH==dispHIGH) rmode=RM_NORMAL; /* determine how big tmpPix should be based on rootMode */ switch (rmode) { case RM_NORMAL: case RM_CENTILE: case RM_TILE: rpixw = eWIDE; rpixh = eHIGH; break; case RM_MIRROR: case RM_IMIRROR: rpixw = 2*eWIDE; rpixh = 2*eHIGH; break; case RM_CSOLID: case RM_CWARP: case RM_CLEFT: case RM_CRIGHT: case RM_CTOP: case RM_CBOTTOM: case RM_CBRICK: case RM_GEOM: rpixw = dispWIDE; rpixh = dispHIGH; break; default: rpixw = eWIDE; rpixh = eHIGH; break; } if (nolimits) { RANGE(rpixw, 1, maxWIDE); RANGE(rpixh, 1, maxHIGH); } else { RANGE(rpixw, 1, dispWIDE); RANGE(rpixh, 1, dispHIGH); } /* create tmpPix */ xerrcode = 0; tmpPix = XCreatePixmap(theDisp, mainW, rpixw, rpixh, dispDEEP); XSync(theDisp, False); if (xerrcode || !tmpPix) { static char *foo[] = { "\nDarn!" }; char str[128]; sprintf(str, "Insufficient memory in X server to build root pixmap."); PopUp(str, foo, 1); return; } if (rmode == RM_NORMAL || rmode == RM_TILE) { XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, 0,0, eWIDE, eHIGH); } else if (rmode == RM_MIRROR || rmode == RM_IMIRROR) { /* quadrant 2 */ XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, 0,0, eWIDE, eHIGH); if (epic == NULL) FatalError("epic == NULL in RM_MIRROR code...\n"); /* quadrant 1 */ FlipPic(epic, eWIDE, eHIGH, 0); /* flip horizontally */ CreateXImage(); XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, eWIDE,0, eWIDE, eHIGH); /* quadrant 4 */ FlipPic(epic, eWIDE, eHIGH, 1); /* flip vertically */ CreateXImage(); XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, eWIDE,eHIGH, eWIDE,eHIGH); /* quadrant 3 */ FlipPic(epic, eWIDE, eHIGH, 0); /* flip horizontally */ CreateXImage(); XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, 0,eHIGH, eWIDE,eHIGH); FlipPic(epic, eWIDE, eHIGH, 1); /* flip vertically (back to orig) */ CreateXImage(); /* put back to original state */ } else if (rmode >= RM_CENTER) { /* do some stuff to set up the border around the picture */ if (rmode != RM_CENTILE) { XSetForeground(theDisp, theGC, rootbg); XFillRectangle(theDisp, tmpPix, theGC, 0,0, dispWIDE, dispHIGH); } if (rmode == RM_CENTILE) { /* hagan-style tiling */ int x, y, w, h, ax, ay, w1, h1, offx, offy; w = eWIDE; h = eHIGH; /* compute anchor pt (top-left coords of top-left-most pic) */ ax = (dispWIDE-w)/2; ay = (dispHIGH-h)/2; while (ax>0) ax = ax - w; while (ay>0) ay = ay - h; for (i=ay; i < (int) eHIGH; i+=h) { for (j=ax; j < (int) eWIDE; j+=w) { /* if image goes off tmpPix, only draw subimage */ x = j; y = i; w1 = w; h1 = h; offx = offy = 0; if (x<0) { offx = -x; w1 -= offx; x = 0; } if (x+w1>eWIDE) { w1 = (eWIDE-x); } if (y<0) { offy = -y; h1 -= offy; y = 0; } if (y+h1>eHIGH) { h1 = (eHIGH-y); } XPutImage(theDisp, tmpPix, theGC, theImage, offx, offy, x, y, w1, h1); } } } else if (rmode == RM_CSOLID || rmode == RM_CLEFT || rmode == RM_CRIGHT || rmode == RM_CTOP || rmode == RM_CBOTTOM || rmode == RM_GEOM) { } else if (rmode == RM_CWARP) { /* warp effect */ XSetForeground(theDisp, theGC, rootfg); for (i=0; i<=dispWIDE; i+=8) XDrawLine(theDisp, tmpPix, theGC, i, 0, dispWIDE-i, dispHIGH); for (i=0; i<=dispHIGH; i+=8) XDrawLine(theDisp, tmpPix, theGC, 0, i, dispWIDE, dispHIGH-i); } else if (rmode == RM_CBRICK) { /* brick effect */ XSetForeground(theDisp, theGC, rootfg); for (i=k=0; iclass & 1)) return; /* no colormap to worry about */ if (riPix) return; /* it's already been saved once */ riPix = XCreatePixmap(theDisp, vrootW, 1, 1, 1); if (!riPix) return; /* unable to save. thankfully, unlikely to happen */ prop = XInternAtom(theDisp, "_XSETROOT_ID", False); if (!prop) FatalError("couldn't create _XSETROOT_ID atom"); XChangeProperty(theDisp, vrootW, prop, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &riPix, 1); XSetCloseDownMode(theDisp, RetainPermanent); } /***********************************/ void KillOldRootInfo() { /* get the pixmap ID from the _XSETROOT_ID property, and kill it */ Atom prop, type; int format; unsigned long length, after; unsigned char *data; prop = XInternAtom(theDisp, "_XSETROOT_ID", True); if (prop == None) return; /* no old pixmap to kill */ if (XGetWindowProperty(theDisp, vrootW, prop, 0L, 1L, True, AnyPropertyType, &type, &format, &length, &after, &data) == Success) { if (type==XA_PIXMAP && format==32 && length==1 && after==0 && data) { XKillClient(theDisp, *((Pixmap *)data)); XDeleteProperty(theDisp, vrootW, prop); } XFree((char *) data); } } ,dispHIGH just use 'normal' mode to save mem */ if (rmode>=RM_CENTER && eWIDE==dispWIDE && eHIGH==dispHIGH) rmode=RM_NORMAL; /* determine how big tmpPix should be based on rootMode */ switch (rmode) { case RM_NORMAL: case RM_CENTILE: case RM_TILE: rpixw = eWIDE; rpixh = eHIGxvxpm.c000600 002300 001754 00000010604 05233770753 013071 0ustar00sampurehons000000 000000 /* * xvxpm.c - load routine for X11 XPM v3 format pictures * * LoadXPM(fname,nc) * WriteXPM(fp,pic,w,h,rp,gp,bp,nc,cs,n) */ /* * Written by Sam Yates (syates@spam.maths.adelaide.edu.au) * to support xpm v3 format. * * Uses hcreate etc. caus' I'm lazy :) */ #include #include "xv.h" static int XPMError(); unsigned char htoc(); int LoadXPM(fname,nc) char *fname; int nc; { FILE *fp; char inlin[256]; char c; int stage,instr,so,i,xwidth,ywidth,yw,cpp,nce; char *pix,*pic24,*pvla,*line,*lp,*plp,*cp; ENTRY item,*hp; XColor col1,col2; fp=fopen(fname,"r"); if (!fp) return 1; /* Read in strings one at a time and parse. Stop when get to expected end or unexpected EOF */ SetDirRButt(F_FORMAT, F_XPM); SetISTR(ISTR_FORMAT,"XPM v3"); stage=0; /* searching for value string */ instr=0; /* not inside a string */ while (stage<3&&(c=getc(fp))) { if (!instr&&c!='"') continue; if (!instr) instr=1,so=0; else if (c=='"'||(so==255&&stage==0)||(so==xwidth*(cpp+1)&&stage==2)) { while (c!='"'&&(c=getc(fp))) ; instr=0; switch (stage) { case 0: inlin[so]=0; sscanf(inlin,"%d%d%d%d",&xwidth,&ywidth,&nce,&cpp); yw=ywidth; stage++; if (nce<=0||cpp<=0) return(XPMError("No colours in XPM?")); hdestroy(); if (!hcreate(nce)) return(XPMError("Insufficient memory for colour table")); if (!(line=malloc(xwidth*(cpp+1)))||!(pvla=malloc(nce*(cpp+5)))|| !(pic24=malloc(xwidth*ywidth*3))) return(XPMError("Insufficient memory for X pixmap")); pix=pic24; break; case 1: inlin[so]=0; memcpy(pvla,inlin,cpp); memcpy(pvla+cpp,"\0\0\0\0\0",5); if (so>cpp+1) { cp=strtok(inlin+cpp+1,"\t "); plp=0; do { if (*cp=='s') {strtok(0,"\t "); continue;} lp=strtok(0,"\t "); if (*cp=='c') plp=lp; } while (cp=strtok(0,"\t ")); if (plp) lp=plp; if (lp) { if (*lp=='#') { pvla[cpp+1]=htoc(lp+1); pvla[cpp+2]=htoc(lp+3); pvla[cpp+3]=htoc(lp+5); } else if (XLookupColor(theDisp,theCmap,lp,&col1,&col2)) { pvla[cpp+1]=col1.red>>8; pvla[cpp+2]=col1.green>>8; pvla[cpp+3]=col1.blue>>8; } } } hsearch((item.key=pvla,item.data=pvla+cpp+1,item),ENTER); pvla+=cpp+5; if (--nce<=0) stage++; break; case 2: for (i=0;idata,3),pix+=3; } if (--yw<=0) stage++; default : ; } } else { if (stage<2) inlin[so++]=c; else { line[so++]=c; if (!((so+1)%(cpp+1))) line[so++]=0; } } } if (Conv24to8(pic24,xwidth,ywidth,nc)) return(XPMError("Couldn't convert to 8 bit")); hdestroy(); free(pic24); free(line); free(pvla); if (fp!=stdin) fclose(fp); return 0; } static int XPMError(st) char *st; { SetISTR(ISTR_WARNING,st); return 1; } unsigned char htoc(s) char *s; { unsigned char i; if ('0'<=*s&&*s<='9') i=(*s-'0')<<4; else if ('a'<=*s&&*s<='f') i=(*s-'a'+10)<<4; else if ('A'<=*s&&*s<='F') i=(*s-'A'+10)<<4; s++; if ('0'<=*s&&*s<='9') return i+*s-'0'; else if ('a'<=*s&&*s<='f') return i+*s-'a'+10; else if ('A'<=*s&&*s<='F') return i+*s-'A'+10; return i; } WriteXPM(fp,pic,w,h,rp,gp,bp,nc,cs,n) FILE *fp; byte *pic; int w,h; byte *rp,*gp,*bp; int nc,cs; char *n; { int i,j; byte c,*pix=pic; char name[256]; strncpy(name,n,255); name[255]=0; i=strspn(name,"_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); if (!i||'9'>=*name) strcpy(name,"xpm"); else name[i]=0; fprintf(fp,"/* XPM */\nstatic char* %s = {\n\"%d %d %d 2\",\n",name,w,h,nc); if (cs!=F_GREYSCALE) for (i=0;i>5),'_'+(i%32),rp[i],gp[i],bp[i]); else for (i=0;i>5),'_'+(i%32),c,c,c); } for (i=0;i++>5),fp),fputc('_'+(*pix%32),fp); fputs("\",\n",fp); } if (fputs("} ;\n",fp)==EOF) return 1; else return 0; } y = ay - h; for (i=ay; i < (int) eHIGH; i+=h) { for (j=ax; j < (int) eWIDE; j+=w) { /* if image goes off tmpPix, Makefile000644 002300 001754 00000020065 05233473573 013215 0ustar00sampurehons000000 000000 # Makefile for xv # your C compiler (and options) of choice # # if compiling on a Mips machine, try this: # CCOPTS = -Olimit 600 -systype bsd43 # if you want to use gcc, use this line, or something like it. # CC = gcc -g -traditional CC = cc CCOPTS = -O # if you're using a Sun running OpenWindows, you may want to add these two # options to the CCOPTS line, so it finds the libs and include files # -L/usr/openwin/lib -I/usr/openwin/include ################ CONFIGURATION OPTIONS ################# # if, for whatever reason, you're unable to get the JPEG library to compile # on your machine, *COMMENT OUT* the following lines # # Also, comment out the LIBJPEG dependancy at the end of this Makefile # JPEG = -DHAVE_JPEG JPEGDIR = jpeg LIBJPEG = $(JPEGDIR)/libjpeg.a JPEGINCLUDE = -I$(JPEGDIR) # if, for whatever reason, you're unable to get the TIFF library to compile # on your machine, *COMMENT OUT* the following lines # # Also, comment out the LIBJPEG dependancy at the end of this Makefile # TIFF = -DHAVE_TIFF TIFFDIR = tiff LIBTIFF = $(TIFFDIR)/libtiff.a TIFFINCLUDE = -I$(TIFFDIR) # if, for whatever reason, you're unable to get the PDS/VICAR support # to compile (xvpds.c, and vdcomp.c), *COMMENT OUT* the following line, # and also remove 'vdcomp' from the 'all:' dependancy PDS = -DHAVE_PDS # if, for whatever reason, you don't wish to use the fsQuick software # (which currently only affects xv's performance on a 1-bit display) # you should comment out the following line # (fsQuick.c contains some huge macro definitions which could break your # C preprocessor... FSQUICK = -DHAVE_FSQUICK # if you are running under DXWM, I pity you. XV doesn't work correctly # under DXWM. You should probably be running MWM. However, if such is # not a valid option for you, try uncommenting the following line. The # behavior won't be 'right', but it will be less 'wrong'. #DXWM = -DDXWM # if you are running on a SysV-based machine, such as HP, Silicon Graphics, # etc, uncomment the following line to get you most of the way there. # #UNIX = -DSVR4 # If you are running on a POSIX-compatible machine, such as an # IBM RS/6000, you MAY need to uncomment the 'NEED_DIRENT' line. # To determine if such is the case, do a 'man readdir' on your machine. If # readdir() returns a pointer to 'struct direct', you will not have # to change anything. If, however, readdir() returns a pointer to # 'struct dirent', you will have to add the '-DDIRENT' to CFLAGS # # One note: folks using an IBM RS/6000 don't have to touch this line. # I check for '6000'-hood in xv.h # NEED_DIRENT = -DDIRENT # # for UMAX V by Encore Computers uncomment the following line for # the portable c compiler, system specific definitions and # location of local X11 library(if site specific, modify -L option) # No other switches should be necessary # #UMAX = -q extensions=pcc_c -D__UMAXV__ -L/usr2/usr/lib/X11 -DSVR4 -DDIRENT # If your machine doesn't have the 'strchr', 'memset' and 'memcpy' functions, # but does have 'bcopy', uncomment the following line. (And get a better # operating system!) # #USEMEM = -DNEED_MEMROUTINES # if your machine doesn't have 'random()', but does have 'rand(), # uncomment the following line: # #RAND = -DNO_RANDOM # IF YOUR MACHINE DOESN'T HAVE 'vprintf()' OR 'vsprintf()' # # Vax BSD and IBM AOS don't have vprintf or vsprintf. # Note that our local library versions of sprintf have been updated # to return int, the number of characters in the formatted string, # whereas the versions in stock 4.3BSD do not so return. You may # have to remove the "-DINTSPRINTF" below if you're compiling for # stock 4.3BSD or for some other Vax or RT library package where # sprintf returns char *. # # Also, I define NOVOID on the Vax because I'm using pcc to compile. # If you use gcc or some other better compiler, this should not be # necessary. I define NOSTDHDRS on the RT because we don't have # standard ANSI header files installed for the RT, even though the RT # compiler claims to be ANSI-compliant. # # (for BSD 4.3 VAX, uncomment the following line) #VPRINTF = -DNEED_VPRINTF -DINTSPRINTF -DLONGINT -DNOVOID # (for (stock) IBM RT AOS 4.3, uncomment the following line) #VPRINTF = -DNEED_VPRINTF -DLONGINT -DNOSTDHDRS # (for Sequent running DYNIX 3.1.4, uncomment the following line) #VPRINTF = -DNEED_VPRINTF -DLONGINT -DNOSTDHDRS # If your machine does not have the 'setitimer()' call, but does # have the 'usleep()' call, uncomment the following line: # #TIMERS = -DUSLEEP # # alternately, if your machine does not have EITHER the 'setitimer()' or # the 'usleep()' call, uncomment the following line: # #TIMERS = -DNOTIMER # If you are using an AT&T machine, uncomment the following line # If you have problems compiling xv.c and xvdir.c because of the DIR # reference in dirent.h, append '-DATT' to the following line: # #ATT = -DDIRENT -DUSLEEP -DATT # If you are using an HP running HPUX 7.0, uncomment the following line # #HPUX7 = -DSVR4 -DATT +Ns4000 -DHPUX7 # For SCO and ODT machines, uncomment the following: # #SCO = -Dsco -DPOSIX -DNOTIMER # # Itimers will be in 3.2v3 (yeah!) but that won't be out in the public's # hands for a while. # # Also, you'll want to change LIBS to # # -lX11 -lm -lsocket -lmalloc -lc -lx # # -lx must be after -lc so you get the right directory routines. # CFLAGS = $(CCOPTS) $(NEED_DIRENT) $(VPRINTF) $(TIMERS) $(ATT) \ $(SCO) $(UNIX) $(USEMEM) $(HPUX7) $(JPEG) $(JPEGINCLUDE) \ $(DXWM) $(UMAX) $(FSQUICK) $(RAND) $(TIFF) $(TIFFINCLUDE) $(PDS) LIBS = -lX11 $(LIBJPEG) $(LIBTIFF) -lm BITMAPS = bitmaps/grasp bitmaps/penn bitmaps/down bitmaps/down1 \ bitmaps/up bitmaps/up1 bitmaps/scrlgray bitmaps/gray50 \ bitmaps/gray25 bitmaps/i_fifo bitmaps/i_chr bitmaps/i_dir \ bitmaps/i_blk bitmaps/i_lnk bitmaps/i_sock bitmaps/i_reg \ bitmaps/rb_off bitmaps/rb_on bitmaps/rb_off1 bitmaps/rb_on1 \ bitmaps/fc_left bitmaps/fc_leftm bitmaps/fc_mid bitmaps/fc_midm \ bitmaps/fc_right bitmaps/fc_rightm bitmaps/fc_left1 \ bitmaps/fc_left1m bitmaps/fc_right1 bitmaps/fc_right1m \ bitmaps/icon bitmaps/dial_cw1 bitmaps/dial_cw2 bitmaps/dial_ccw1 \ bitmaps/dial_ccw2 bitmaps/iconmask bitmaps/gf1_addh \ bitmaps/gf1_delh bitmaps/gf1_line bitmaps/gf1_rst \ bitmaps/gf1_spln bitmaps/gf1_gamma \ bitmaps/h_rotl bitmaps/h_rotr bitmaps/h_sinc bitmaps/h_sdec \ bitmaps/h_flip bitmaps/cb_off bitmaps/cb_on bitmaps/cb_off1 \ bitmaps/cb_on1 bitmaps/h_sat bitmaps/h_desat bitmaps/root_weave \ bitmaps/cboard50 bitmaps/mb_chk bitmaps/fliph bitmaps/flipv OBJS = xv.o xvevent.o xvroot.o xvmisc.o xvimage.o xvcolor.o xvsmooth.o \ xv24to8.o xvgif.o xvpm.o xvinfo.o xvctrl.o xvscrl.o xvxpm.o \ xvgifwr.o xvdir.o xvbutt.o xvpbm.o xvxbm.o xvgam.o \ xvdial.o xvgraf.o xvsunras.o xvjpeg.o xvps.o xvpopup.o xvdflt.o \ xvtiff.o xvtiffwr.o xvpds.o xvrle.o xvgrab.o vprintf.o fsQuick.o MISC = README CHANGELOG IDEAS .c.o: ; $(CC) -c $(CFLAGS) -o $@ $*.c all: $(LIBJPEG) $(LIBTIFF) xv bggen vdcomp xv: $(OBJS) $(LIBJPEG) $(LIBTIFF) $(CC) $(CFLAGS) -o xv $(OBJS) $(LIBS) bggen: bggen.c $(CC) $(CFLAGS) -o bggen bggen.c vdcomp: vdcomp.c $(CC) $(CFLAGS) -o vdcomp vdcomp.c clean: rm -f $(OBJS) xv bggen vdcomp # comment out one or both of the following if you aren't using the JPEG and # TIFF libraries ( cd $(JPEGDIR) ; make clean ) ( cd $(TIFFDIR) ; make clean ) tar: tar cf xv.tar Makefile* Imakefile *.c *.h bitmaps \ docs unsupt $(JPEGDIR) $(TIFFDIR) $(MISC) $(OBJS): xv.h xv.o: bitmaps.h xvbutt.o: bitmaps.h xvctrl.o: bitmaps.h xvdial.o: bitmaps.h xvinfo.o: bitmaps.h xvmisc.o: bitmaps.h xvscrl.o: bitmaps.h xvgraf.o: bitmaps.h xvdflt.o: bitmaps/xvpic_logo bitmaps/xvpic_rev bitmaps/xvpic_jhb xvdflt.o: bitmaps/xf_left bitmaps/xf_right bitmaps.h: $(BITMAPS) cat $(BITMAPS) > bitmaps.h # if, for whatever reason, you're unable to get the JPEG library to compile # on your machine, *COMMENT OUT* the following lines # $(LIBJPEG): ( cd $(JPEGDIR) ; make CC='$(CC)' libjpeg.a ) # if, for whatever reason, you're unable to get the TIFF library to compile # on your machine, *COMMENT OUT* the following lines # $(LIBTIFF): ( cd $(TIFFDIR) ; make CC='$(CC)') =(k&1) * 20 + 10; j