home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Stars of Shareware: Programmierung
/
SOURCE.mdf
/
programm
/
msdos
/
c
/
xv221src
/
xv.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-24
|
73KB
|
2,485 lines
/*
* 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)
*
* 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 <X11/Xatom.h>
#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
#ifdef HAVE_JPEG
# define JFIF 7
#endif
#ifdef HAVE_TIFF
# ifdef HAVE_JPEG
# define TIFF 8
# else
# define TIFF 7
# endif
#endif
#ifdef HAVE_PDS
# if (defined(HAVE_TIFF) && defined(HAVE_JPEG))
# define PDSVICAR 9
# else
# if (defined(HAVE_TIFF) || defined(HAVE_JPEG))
# define PDSVICAR 8
# else
# define PDSVICAR 7
# 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<NISTR; i++) SetISTR(i,"");
/* init ctrl box variables */
ctrlUp = 0;
curname = 0;
formatStr[0] ='\0';
gamUp = 0;
Init24to8();
/*****************************************************/
/*** X Resource Initialization ***/
/*****************************************************/
/* once through the argument list to find the display name, if any */
for (i=1; i<argc; i++) {
if (!strncmp(argv[i],"-help",5)) { /* help */
Syntax();
exit(0);
}
else if (!argcmp(argv[i],"-display",4)) { /* display */
i++;
if (i<argc) display = argv[i];
break;
}
}
/* open the display */
if ( (theDisp=XOpenDisplay(display)) == NULL) {
fprintf(stderr, "%s: Can't open display\n",argv[0]);
exit(1);
}
if (rd_str ("aspect")) {
int n,d;
if (sscanf(def_str,"%d:%d",&n,&d)!=2 || n<1 || d<1)
fprintf(stderr,"%s: unable to parse 'aspect' resource\n",cmd);
else defaspect = (float) n / (float) d;
}
if (rd_flag("2xlimit")) limit2x = def_int;
if (rd_flag("autoClose")) autoclose = def_int;
if (rd_flag("autoCrop")) autocrop = def_int;
if (rd_flag("autoDither")) autodither = def_int;
if (rd_flag("autoSmooth")) autosmooth = def_int;
if (rd_str ("background")) bgstr = def_str;
if (rd_flag("best24") && def_int) conv24 = CONV24_BEST;
if (rd_str ("black")) blackstr = def_str;
if (rd_int ("borderWidth")) bwidth = def_int;
if (rd_flag("browseMode")) browseMode = def_int;
if (rd_str ("ctrlGeometry")) ctrlgeom = def_str;
if (rd_flag("ctrlMap")) ctrlmap = def_int;
if (rd_int ("cursor")) curstype = def_int;
if (rd_str ("expand")) expand = atof(def_str);
if (rd_flag("fixed")) fixedaspect = def_int;
if (rd_str ("foreground")) fgstr = def_str;
if (rd_str ("geometry")) maingeom = def_str;
if (rd_str ("ceditGeometry")) gamgeom = def_str;
if (rd_flag("ceditMap")) gmap = def_int;
if (rd_flag("ceditColorMap")) cmapInGam = def_int;
if (rd_flag("clearOnLoad")) clearonload = def_int;
if (rd_flag("hsvMode")) hsvmode = def_int;
if (rd_str ("highlight")) histr = def_str;
if (rd_str ("infoGeometry")) infogeom = def_str;
if (rd_flag("infoMap")) imap = def_int;
if (rd_flag("keepAround")) keeparound = def_int;
if (rd_str ("lowlight")) lostr = def_str;
if (rd_flag("mono")) mono = def_int;
if (rd_int ("ncols")) { ncols = def_int; if (ncols>=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; i<argc; i++) {
if (argv[i][0] != '-') { /* a file name. put it in list */
if (numnames<MAXNAMES) {
namelist[numnames++] = argv[i];
if (numnames==MAXNAMES) {
fprintf(stderr,"%s: too many filenames. Only using first %d.\n",
cmd, MAXNAMES);
}
}
}
else if (!strcmp(argv[i], "-")) /* stdin flag */
stdinflag++;
else if (!argcmp(argv[i],"-2xlimit",2)) /* 2xlimit */
limit2x = !limit2x;
else if (!argcmp(argv[i],"-aspect",2)) { /* default aspect */
int n,d;
if (++i<argc) {
if (sscanf(argv[i],"%d:%d",&n,&d)!=2 || n<1 || d<1)
fprintf(stderr,"%s: bad aspect ratio '%s'\n",cmd,argv[i]);
else defaspect = (float) n / (float) d;
}
}
else if (!argcmp(argv[i],"-best24",3)) /* ppmquant 24->8 conversion */
conv24 = CONV24_BEST;
else if (!argcmp(argv[i],"-bg",3)) /* background color */
{ if (++i<argc) bgstr = argv[i]; }
else if (!argcmp(argv[i],"-black",3)) /* black color */
{ if (++i<argc) blackstr = argv[i]; }
else if (!argcmp(argv[i],"-browse",3)) /* browse mode */
browseMode = !browseMode;
else if (!argcmp(argv[i],"-bw",3)) /* border width */
{ if (++i<argc) bwidth=atoi(argv[i]); }
else if (!argcmp(argv[i],"-cecmap",4)) /* cmapInGam */
cmapInGam = !cmapInGam;
else if (!argcmp(argv[i],"-cegeometry",4)) /* gammageom */
{ if (++i<argc) gamgeom = argv[i]; }
else if (!argcmp(argv[i],"-cemap",4)) /* gmap */
gmap++;
else if (!argcmp(argv[i],"-cgeometry",3)) /* ctrlgeom */
{ if (++i<argc) ctrlgeom = argv[i]; }
else if (!argcmp(argv[i],"-clear",4)) /* clear */
clrroot++;
else if (!argcmp(argv[i],"-close",4)) /* close */
autoclose = !autoclose;
else if (!argcmp(argv[i],"-cmap",3)) /* ctrlmap */
ctrlmap++;
else if (!argcmp(argv[i],"-crop",3)) /* autocrop */
autocrop = !autocrop;
else if (!argcmp(argv[i],"-cursor",3)) /* cursor */
{ if (++i<argc) curstype = atoi(argv[i]); }
else if (!argcmp(argv[i],"-DEBUG",2)) /* debug */
{ if (++i<argc) DEBUG = atoi(argv[i]); }
else if (!argcmp(argv[i],"-display",4)) /* display */
{ if (++i<argc) display = argv[i]; }
else if (!argcmp(argv[i],"-dither",4)) /* autodither */
autodither = !autodither;
else if (!argcmp(argv[i],"-expand",2)) /* expand factor */
{ if (++i<argc) expand=atof(argv[i]); }
else if (!argcmp(argv[i],"-fg",3)) /* foreground color */
{ if (++i<argc) fgstr = argv[i]; }
else if (!argcmp(argv[i],"-fixed",3)) /* fixed aspect ratio */
fixedaspect++;
else if (!argcmp(argv[i],"-geometry",2)) /* geometry */
{ if (++i<argc) maingeom = argv[i]; }
else if (!argcmp(argv[i],"-hi",3)) /* highlight */
{ if (++i<argc) histr = argv[i]; }
else if (!argcmp(argv[i],"-hsv",3)) /* hsvmode */
hsvmode = 1;
else if (!argcmp(argv[i],"-igeometry",3)) /* infogeom */
{ if (++i<argc) infogeom = argv[i]; }
else if (!argcmp(argv[i],"-imap",3)) /* imap */
imap++;
else if (!argcmp(argv[i],"-keeparound",2)) /* keeparound */
keeparound = !keeparound;
else if (!argcmp(argv[i],"-loadclear",4)) /* toggle clearonload */
clearonload = !clearonload;
else if (!argcmp(argv[i],"-lo",3)) /* lowlight */
{ if (++i<argc) lostr = argv[i]; }
else if (!argcmp(argv[i],"-max",4)) /* auto maximize */
automax++;
else if (!argcmp(argv[i],"-maxpect",5)) /* auto maximize */
{ automax++; fixedaspect++; }
else if (!argcmp(argv[i],"-mono",3)) /* mono */
mono++;
else if (!argcmp(argv[i],"-ncols",3)) /* ncols */
{ if (++i<argc) { ncols=abs(atoi(argv[i])); noglob++; } }
else if (!argcmp(argv[i],"-nglobal",3)) /* no global colors */
noglob++;
else if (!argcmp(argv[i],"-ninstall",3)) /* don't install colormaps */
ninstall=1;
else if (!argcmp(argv[i],"-nolimits",4)) /* nolimits */
nolimits = !nolimits;
else if (!argcmp(argv[i],"-nopos",4)) /* nopos */
nopos++;
else if (!argcmp(argv[i],"-noqcheck",4)) /* noqcheck */
noqcheck++;
else if (!argcmp(argv[i],"-nostat",4)) /* nostat */
nostat = !nostat;
else if (!argcmp(argv[i],"-owncmap",2)) /* own colormap */
owncmap++;
else if (!argcmp(argv[i],"-perfect",2)) /* perfect colors */
perfect++;
else if (!argcmp(argv[i],"-noresetroot",2)) /* reset root in window mode */
resetroot = !resetroot;
else if (!argcmp(argv[i],"-quick24",5)) /* quick 24-to-8 conversion */
conv24 = CONV24_FAST;
else if (!argcmp(argv[i],"-quit",2)) /* auto-quit if -root */
autoquit++;
else if (!argcmp(argv[i],"-rbg",3)) /* root background color */
{ if (++i<argc) rootbgstr = argv[i]; }
else if (!argcmp(argv[i],"-rfg",3)) /* root foreground color */
{ if (++i<argc) rootfgstr = argv[i]; }
else if (!argcmp(argv[i],"-rgb",4)) /* rgb mode */
hsvmode = 0;
else if (!argcmp(argv[i],"-rmode",3)) /* root pattern */
{ if (++i<argc) rootMode = abs(atoi(argv[i])); useroot++; }
else if (!argcmp(argv[i],"-root",3)) /* use root window */
useroot++;
else if (!argcmp(argv[i],"-rv",3)) /* reverse video */
revvideo = !revvideo;
else if (!argcmp(argv[i],"-rw",3)) /* use r/w color */
rwcolor = !rwcolor;
else if (!argcmp(argv[i],"-slow24",3)) /* slow 24-to-8 conversion */
conv24 = CONV24_SLOW;
else if (!argcmp(argv[i],"-smooth",3)) /* autosmooth */
autosmooth = !autosmooth;
else if (!argcmp(argv[i],"-visual",2)) /* visual */
{ if (++i<argc) visualstr = argv[i]; }
else if (!argcmp(argv[i],"-wait",3)) { /* secs to wait between pics */
if (++i<argc) {
waitsec = abs(atoi(argv[i]));
if (waitsec<0) waitsec = 0;
}
}
else if (!argcmp(argv[i],"-white",3)) /* white color */
{ if (++i<argc) whitestr = argv[i]; }
else if (!argcmp(argv[i],"-wloop",3)) /* waitloop */
waitloop++;
else if (!argcmp(argv[i],"-nolimits",3)) /* waitloop */
nolimits++;
else Syntax();
}
RANGE(curstype,0,254);
curstype = curstype & 0xfe; /* clear low bit to make curstype even */
if (expand == 0.0) Syntax();
if (rootMode < 0 || rootMode > 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<numvis; i++) {
if (vinfo[i].depth > 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,"\t0: tiling\n");
fprintf(stderr,"\t1: integer tiling\n");
fprintf(stderr,"\t2: mirrored tiling\n");
fprintf(stderr,"\t3: integer mirrored tiling\n");
fprintf(stderr,"\t4: centered tiling\n");
fprintf(stderr,"\t5: centered on a solid background\n");
fprintf(stderr,"\t6: centered on a 'warp' background\n");
fprintf(stderr,"\t7: centered on a 'brick' 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 '<stdin>')
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,WRITE_BINARY);
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,READ_BINARY);
#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;
#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;
#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)
? "<none>" : 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], (curname<numnames-1));
BTSetActive(&but[BPREV], (curname>0));
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;
}
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;
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 (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;
}
}
cpic = pic; cWIDE = pWIDE; cHIGH = pHIGH; cXOFF = cYOFF = 0;
SetCropString(but[BCROP].active);
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; i<numcols; i++) {
r[i] = 255 - r[i];
g[i] = 255 - g[i];
b[i] = 255 - b[i];
}
}
/* save the desired RGB colormap (before dicking with it) */
for (i=0; i<numcols; i++) {
rorg[i] = rcmap[i] = r[i];
gorg[i] = gcmap[i] = g[i];
borg[i] = bcmap[i] = b[i];
}
NewCMap();
GammifyColors();
WaitCursor();
if (rwcolor) AllocRWColors(); else AllocColors();
ChangeEC(0);
WaitCursor();
smoothResize(eWIDE, eHIGH);
WaitCursor();
HandleDispMode(); /* create root pic, or mainW, depending... */
if (LocalCmap) {
XSetWindowAttributes xswa;
if (!ninstall) XInstallColormap(theDisp,LocalCmap);
xswa.colormap = LocalCmap;
XChangeWindowAttributes(theDisp,mainW,CWColormap,&xswa);
if (cmapInGam) XChangeWindowAttributes(theDisp,gamW,CWColormap,&xswa);
}
tmp = GetISTR(ISTR_COLOR);
SetISTR(ISTR_INFO,"%s %s",formatStr, tmp);
SetInfoMode(INF_FULL);
if (freename) free(fullname);
if (autocrop) AutoCrop();
SetCursors(-1);
if (dirUp!=BLOAD) {
/* put current filename into the 'save-as' filename */
if (strcmp(filename,STDINSTR)==0) SetDirFName("stdin");
else if (frompipe || filenum == LOADPIC || filenum == GRABBED ||
filenum == DFLTPIC) {} /* leave it alone */
else SetDirFName(basefname);
}
/* since we're now using BitGravity to keep parts of the image window
valid when the window is resized, we have to force an expose event
on the *previous* size of the window, as this portion of the new
window will *not* be given an expose event
UNLESS the window hasn't changed size at all, in which case an
appropriate expose event will be generated by CreateMainWindow().
Yech! */
if (mainW && !useroot && !clearonload && oldeWIDE>0 && 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; i<numnames; i++) {
if (openPic(i)) return; /* success */
}
if (numnames>1) FatalError("couldn't open any pictures");
else Quit(-1);
}
/****************/
static void OpenNextPic()
/****************/
{
int i;
for (i=curname+1; i<numnames; i++) {
if (openPic(i)) return; /* success */
}
openPic(DFLTPIC);
}
/****************/
static void OpenNextQuit()
/****************/
{
int i;
for (i=curname+1; i<numnames; i++) {
if (openPic(i)) return; /* success */
}
Quit(0);
}
/****************/
static void OpenNextLoop()
/****************/
{
int i,j;
j = 0;
while (1) {
for (i=curname+1; i<numnames; i++) { /* load next picture */
if (openPic(i)) return;
}
curname = -1; /* back to first in list */
if (j) break; /* we're in a 'failure loop' */
j++;
}
openPic(DFLTPIC);
}
/****************/
static void OpenPrevPic()
/****************/
{
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 && curname<numnames-1) { closePic(); OpenNextPic(); }
else if (i==PREVPIC && curname>0) { 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<numnames; i++) {
if (strncmp(namelist[0], namelist[i], n)!=0) { done=1; break; }
}
if (!done) prelen = n;
}
for (i=0; i<numnames; i++)
dispnames[i] = namelist[i] + prelen;
}
/***********************************/
static void stickInList()
{
/* stick current name (from 'load' box) and current working directory
into 'namelist' */
char *name, *fullname;
char cwd[MAXPATHLEN];
if (numnames == MAXNAMES) return; /* full up */
name = GetDirFName();
if (name[0] != '/') { /* prepend current working path */
GETWD(cwd);
fullname = (char *) malloc(strlen(cwd) + strlen(name) + 2);
if (!fullname) FatalError("couldn't alloc 'fullname' in stickInList()\n");
sprintf(fullname, "%s/%s", cwd, name);
}
else { /* copy name to fullname */
fullname = (char *) malloc(strlen(name) + 1);
if (!fullname) FatalError("couldn't alloc 'fullname' in stickInList()\n");
strcpy(fullname, name);
}
namelist[numnames] = fullname;
/* figure out how much of name can be shown */
if (StringWidth(fullname) > (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], (curname<numnames-1));
BTSetActive(&but[BPREV], (curname>0));
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<mainargc && mainargv[i] != namelist[delnum]; i++) ;
if (i == mainargc) { /* not found. free it */
free(namelist[delnum]);
}
if (delnum != numnames-1) {
/* snip out of namelist and dispnames lists */
bcopy(&namelist[delnum+1], &namelist[delnum],
(numnames - delnum - 1) * sizeof(namelist[0]));
bcopy(&dispnames[delnum+1], &dispnames[delnum],
(numnames - delnum - 1) * sizeof(dispnames[0]));
}
numnames--;
if (numnames==0) BTSetActive(&but[BDELETE],0);
nList.nstr = numnames;
nList.selected = delnum;
if (nList.selected >= 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], (curname<numnames-1));
BTSetActive(&but[BPREV], (curname>0));
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);
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);
}