home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Astrolog (Version 4.00) File: xdriver.c
- **
- ** IMPORTANT NOTICE: the graphics database and chart display routines
- ** used in this program are Copyright (C) 1991-1993 by Walter D. Pullen
- ** (cruiser1@stein.u.washington.edu). Permission is granted to freely
- ** use and distribute these routines provided one doesn't sell,
- ** restrict, or profit from them in any way. Modification is allowed
- ** provided these notices remain with any altered or edited versions of
- ** the program.
- **
- ** The main planetary calculation routines used in this program have
- ** been Copyrighted and the core of this program is basically a
- ** conversion to C of the routines created by James Neely as listed in
- ** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
- ** available from Matrix Software. The copyright gives us permission to
- ** use the routines for personal use but not to sell them or profit from
- ** them in any way.
- **
- ** The PostScript code within the core graphics routines are programmed
- ** and Copyright (C) 1992-1993 by Brian D. Willoughby
- ** (brianw@sounds.wa.com). Conditions are identical to those above.
- **
- ** The extended accurate ephemeris databases and formulas are from the
- ** calculation routines in the program "Placalc" and are programmed and
- ** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
- ** (alois@azur.ch). The use of that source code is subject to
- ** regulations made by Astrodienst Zurich, and the code is not in the
- ** public domain. This copyright notice must not be changed or removed
- ** by any user of this program.
- **
- ** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
- ** X Window graphics initially programmed 10/23-29/1991.
- ** PostScript graphics initially programmed 11/29-30/1992.
- ** Last code change made 12/31/1993.
- */
-
- #include "astrolog.h"
-
- #ifdef GRAPH
-
- #ifdef X11
- /* Size of the Astrolog X11 icon. These values are defined in xdata.c too. */
-
- #define icon_width 63
- #define icon_height 32
- #endif
-
- #ifdef MSG
- /* PC specific global variables. */
-
- int hiresmode = DEFHIRESMODE; /* 'High-resolution' graphics mode. */
- int loresmode = DEFLORESMODE; /* 'Flicker-free' graphics mode. */
- int xscreen = -1000; /* Current graphics mode. */
- struct videoconfig config; /* State of current graphics mode. */
- #endif
-
-
- /*
- ******************************************************************************
- ** Interactive Screen Graphics Routines.
- ******************************************************************************
- */
-
- #ifdef X11
- /* Allocate a color from the present colormap. Given a string like "red" or */
- /* "blue" allocate this color and return a value specifying it. */
-
- colrgb XMakeColor(name)
- char *name;
- {
- XColor col;
- XParseColor(disp, cmap, name, &col);
- XAllocColor(disp, cmap, &col);
- return col.pixel;
- }
- #endif
-
-
- /* Set up all the colors used by the program, i.e. the foreground and */
- /* background colors, and all the colors in the object arrays, based on */
- /* whether or not we are in monochrome and/or reverse video mode. */
-
- void XColorInit()
- {
- int i;
-
- #ifdef X11
- if (!xfile) {
- cmap = XDefaultColormap(disp, screen);
- for (i = 0; i < 16; i++)
- rgbind[i] = XMakeColor(rgbname[i]);
- }
- #endif
- on = mainansi[!xreverse];
- off = mainansi[xreverse];
- hilite = xcolor ? mainansi[2+xreverse] : on;
- gray = xcolor ? mainansi[3-xreverse] : on;
- for (i = 0; i <= 6; i++)
- maincolor[i] = xcolor ? mainansi[i] : on;
- for (i = 0; i <= 7; i++)
- rainbowcolor[i] = xcolor ? rainbowansi[i] : on;
- for (i = 0; i < 4; i++)
- elemcolor[i] = xcolor ? elemansi[i] : on;
- for (i = 0; i <= ASPECTS; i++)
- aspectcolor[i] = xcolor ? aspectansi[i] : on;
- for (i = 0; i <= total; i++)
- objectcolor[i] = xcolor ? objectansi[i] : on;
- #ifdef X11
- if (!xfile) {
- XSetBackground(disp, gc, rgbind[off]); /* Initialize X window colors. */
- XSetForeground(disp, pmgc, rgbind[off]);
- }
- #endif
- }
-
-
- #ifdef ISG
- /* This routine opens up and initializes a window and prepares it to be */
- /* drawn upon, and gets various information about the display, too. */
-
- void XBegin()
- {
- #ifdef X11
- disp = XOpenDisplay(dispname);
- if (!disp) {
- PrintError("Can't open display.");
- Terminate(_FATAL);
- }
- screen = DefaultScreen(disp);
- bg = BlackPixel(disp, screen);
- fg = WhitePixel(disp, screen);
- hint.x = offsetx; hint.y = offsety;
- hint.width = chartx; hint.height = charty;
- hint.min_width = BITMAPX1; hint.min_height = BITMAPY1;
- hint.max_width = BITMAPX; hint.max_height = BITMAPY;
- hint.flags = PPosition | PSize | PMaxSize | PMinSize;
- #if FALSE
- wmhint = XGetWMHints(disp, window);
- wmhint->input = True;
- XSetWMHints(disp, window, wmhint);
- #endif
- depth = DefaultDepth(disp, screen);
- if (depth < 5) {
- xmono = TRUE; /* Is this a monochrome monitor? */
- xcolor = FALSE;
- }
- root = RootWindow(disp, screen);
- if (xroot)
- window = root; /* If -XB in effect, we'll use the root window. */
- else
- window = XCreateSimpleWindow(disp, DefaultRootWindow(disp),
- hint.x, hint.y, hint.width, hint.height, 5, fg, bg);
- pixmap = XCreatePixmap(disp, window, chartx, charty, depth);
- icon = XCreateBitmapFromData(disp, DefaultRootWindow(disp),
- icon_bits, icon_width, icon_height);
- if (!xroot)
- XSetStandardProperties(disp, window, appname, appname, icon,
- (char PTR PTR)xkey, 0, &hint);
-
- /* We have two graphics workareas. One is what the user currently sees in */
- /* the window, and the other is what we are currently drawing on. When */
- /* done, we can quickly copy this to the viewport for a smooth look. */
-
- gc = XCreateGC(disp, window, 0, 0);
- XSetGraphicsExposures(disp, gc, 0);
- pmgc = XCreateGC(disp, window, 0, 0);
- XColorInit(); /* Go set up colors. */
- if (!xroot)
- XSelectInput(disp, window, KeyPressMask | StructureNotifyMask |
- ExposureMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask);
- XMapRaised(disp, window);
- XSync(disp, 0);
- XFillRectangle(disp, pixmap, pmgc, 0, 0, chartx, charty);
-
- #else /* MSG */
-
- if (!IsValidResmode(xscreen)) /* Initialize graphics mode to hi-res. */
- xscreen = hiresmode;
- _setvideomode(xscreen);
- if (_grstatus()) {
- PrintError("Can't enter graphics mode.");
- Terminate(_FATAL);
- }
- _getvideoconfig((struct videoconfig far *) &config);
- if (config.numcolors < 16) {
- xmono = TRUE;
- xcolor = FALSE;
- }
- _remapallpalette((long FAR *) rgb);
- _setactivepage(0);
- _setvisualpage(0);
- XColorInit();
- #ifdef MOUSE
- if (MouseInit() > 0)
- SetPtrVis(SHOW);
- #endif
- textrows = abs(textrows); /* Make sure we reset textrows upon restart. */
- #endif /* MSG */
- }
-
-
- /* Add a certain amount of time to the current hour/day/month/year quantity */
- /* defining the present chart. This is used by the chart animation feature. */
- /* We can add or subtract anywhere from 1 to 9 seconds, minutes, hours, */
- /* days, months, years, decades, centuries, or millenia in any one call. */
- /* This is mainly just addition to the appropriate quantity, but we have */
- /* to check for overflows, e.g. Dec 30 + 3 days = Jan 2 of Current year + 1 */
-
- void AddTime(mode, toadd)
- int mode, toadd;
- {
- int d;
- real h, m;
-
- h = floor(TT);
- m = FRACT(TT)*100.0;
- if (mode == 1)
- m += 1.0/60.0*(real)toadd; /* Add seconds. */
- else if (mode == 2)
- m += (real)toadd; /* add minutes. */
-
- /* Add hours, either naturally or if minute value overflowed. */
-
- if (m < 0.0 || m >= 60.0 || mode == 3) {
- if (m >= 60.0) {
- m -= 60.0; toadd = SGN(toadd);
- } else if (m < 0.0) {
- m += 60.0; toadd = SGN(toadd);
- }
- h += (real)toadd;
- }
-
- /* Add days, either naturally or if hour value overflowed. */
-
- if (h >= 24.0 || h < 0.0 || mode == 4) {
- if (h >= 24.0) {
- h -= 24.0; toadd = SGN(toadd);
- } else if (h < 0.0) {
- h += 24.0; toadd = SGN(toadd);
- }
- DD += toadd;
- }
-
- /* Add months, either naturally or if day value overflowed. */
-
- if (DD > (d = DayInMonth(MM, YY)) || DD < 1 || mode == 5) {
- if (DD > d) {
- DD -= d; toadd = SGN(toadd);
- } else if (DD < 1) {
- DD += DayInMonth(Mod12(MM - 1), YY);
- toadd = SGN(toadd);
- }
- MM += toadd;
- }
-
- /* Add years, either naturally or if month value overflowed. */
-
- if (MM > 12 || MM < 1 || mode == 6) {
- if (MM > 12) {
- MM -= 12; toadd = SGN(toadd);
- } else if (MM < 1) {
- MM += 12; toadd = SGN(toadd);
- }
- YY += toadd;
- }
- if (mode == 7)
- YY += 10 * toadd; /* Add decades. */
- else if (mode == 8)
- YY += 100 * toadd; /* Add centuries. */
- else if (mode == 9)
- YY += 1000 * toadd; /* Add millenia. */
- TT = h+m/100.0; /* Recalibrate hour time. */
- }
-
-
- /* Animate the current chart based on the given values indicating how much */
- /* to update by. We update and recast the current chart info appropriately. */
-
- void Animate(mode, toadd)
- int mode, toadd;
- {
- if (modex == MODEW || modex == MODEG || modex == MODEP) {
- degree += toadd;
- if (degree >= DEGR) /* For animating globe display, add */
- degree -= DEGR; /* in appropriate degree value. */
- else if (degree < 0)
- degree += DEGR;
- } else {
- if (mode == 10) {
- #ifdef TIME
- /* For the continuous chart update to present moment */
- /* animation mode, go get whatever time it is now. */
- InputData("now");
- #else
- SetCore(Mon, Day, Yea, Tim, Zon, Lon, Lat);
- AddTime(1, toadd);
- #endif
- } else { /* Otherwise add on appropriate time vector to chart info. */
- SetCore(Mon, Day, Yea, Tim, Zon, Lon, Lat);
- AddTime(mode, toadd);
- }
- SetMain(MM, DD, YY, TT, ZZ, OO, AA);
- if (relation)
- CastRelation(FALSE);
- else
- CastChart(TRUE);
- }
- }
-
-
- /* Print a list of every key that one can press in an X window to do a */
- /* certain function, and a description of what it does. This list gets */
- /* displayed whenever one presses the 'H' or '?' key in the window. */
-
- void XDisplayKeys()
- {
- char string[STRING];
-
- sprintf(string, "\n%s window keypress options (version %s):", appname,
- VERSION);
- Prints(string);
- Prints(" Press 'H' or '?' to display this list of key options.");
- Prints(" Press 'p' to toggle pause status on or off.");
- Prints(" Press 'x' to toggle fg/bg colors on screen.");
- Prints(" Press 'm' to toggle color/monochrome display on screen.");
- Prints(" Press 'i' to toggle status of the minor chart modification.");
- Prints(" Press 'T' to toggle header info on current chart on screen.");
- Prints(" Press 'b' to toggle drawing of a border around the chart.");
- Prints(" Press 'l' to toggle labeling of object points in chart.");
- Prints(" Press 'v' to display current chart positions on text screen.");
- Prints(" Press 'R', 'C', 'u', 'U' to toggle restriction status of minor");
- Prints(" objects, minor house cusps, uranian planets, and stars.");
- Prints(" Press 'c' to toggle relationship comparison chart mode.");
- Prints(" Press 's', 'h', 'f', 'F' to toggle status of sidereal zodiac,");
- Prints(" heliocentric charts, domal charts, and decan charts.");
- Prints(" Press 'O' and 'o' to recall/store a previous chart from memory.");
- #ifdef X11
- Prints(" Press 'B' to dump current window contents to root background.");
- #else
- Prints(" Press 'B' to resize chart display to full size of screen.");
- #endif
- Prints(" Press 'Q' to resize chart display to a square.");
- Prints(" Press '<' and '>' to decrease/increase the scale size of the");
- Prints(" glyphs and the size of world map.");
- Prints(" Press '[' and ']' to decrease/increase tilt in globe display.");
- Prints(" Press '+' and '-' to add/subtract a day from current chart.");
- #ifdef TIME
- Prints(" Press 'n' to set chart information to current time now.");
- #endif
- Prints(" Press 'N' to toggle animation status on or off. Charts will");
- Prints(" be updated to current status and globe will rotate.");
- Prints(" Press '!'-'(' to begin updating current chart by adding times.");
- Prints(" !: seconds, @: minutes, #: hours, $: days, %: months,");
- Prints(" ^: years, &: years*10, *: years*100, (: years*1000.");
- Prints(" Press 'r' to reverse direction of time-lapse or animation.");
- Prints(" Press '1'-'9' to set rate of animation to 'n' degrees, etc.");
- #ifdef MSG
- Prints(" Press '1'-'9' to determine section of chart to show if clipped.");
- #endif
- Prints(
- " Press 'V','L','A','Z','S','E','W','G','P' to switch to normal (_v),");
- Prints(
- " astro-graph (_L), grid (_g), local (_Z), space (_S), ephemeris");
- Prints(" (_E), world map (_XW), globe (_XG), and polar (_XP) modes.");
- Prints(" Press '0' to toggle between _Z,_Z0 & _XW,_XW0 & _E,_Ey modes.");
- Prints(" Press 'space' to force update of current graphics display.");
- #ifdef MSG
- Prints(" Press 'tab' to toggle between graphics resolutions.");
- #endif
- Prints(" Press 'q' to terminate the window and program.");
- #ifdef MOUSE
- printl();
- #ifdef X11
- Prints(" Left mouse button: Draw line strokes on chart in window.");
- Prints(" Middle mouse button: Print coordinates of pointer on world map.");
- Prints(" Right mouse button: Terminate the window and program.");
- #endif
- #ifdef MSG
- Prints(" Left mouse button: Draw line strokes on chart in screen.");
- Prints(" Right mouse button: Set coordinates to pointer on world map.");
- #endif
- #endif /* MOUSE */
- }
-
-
- /* This routine gets called after an X window is brought up and displayed */
- /* on the screen. It loops, processing key presses, mouse clicks, etc, that */
- /* the window receives, until the user specifies they want to exit program. */
-
- void XSpin()
- {
- #ifdef X11
- XEvent event;
- int xresize = FALSE, xredraw = TRUE;
- #else
- #ifdef MOUSE
- EVENT event;
- #endif
- int xresize = TRUE, xredraw = FALSE;
- #endif
- int xbreak = FALSE, xpause = FALSE, xcast = FALSE, xcorner = 7,
- buttonx = -1, buttony = -1, dir = 1, length, i;
- colpal coldrw = hilite;
-
- xnow = -xnow;
- while (!xbreak) {
-
- /* Some chart windows, like the world maps and aspect grids, should */
- /* always be a certian size, so correct if a resize was attempted. */
-
- if (modex == MODEL || modex == MODEW) {
- length = DEGR*SCALE+2;
- if (chartx != length) {
- chartx = length;
- xresize = TRUE;
- }
- length = (90*2+1)*SCALE+2;
- if (charty != length) {
- charty = length;
- xresize = TRUE;
- }
- } else if (modex == MODEg) {
- if (chartx !=
- (length = (gridobjects + (relation <= DASHr0))*CELLSIZE*SCALE+1)) {
- chartx = length;
- xresize = TRUE;
- } if (charty != length) {
- charty = length;
- xresize = TRUE;
- }
-
- /* Make sure the window isn't too large or too small. */
-
- } else {
- if (chartx < BITMAPX1) {
- chartx = BITMAPX1;
- xresize = TRUE;
- } else if (chartx > BITMAPX) {
- chartx = BITMAPX;
- xresize = TRUE;
- }
- if (charty < BITMAPY1) {
- charty = BITMAPY1;
- xresize = TRUE;
- } else if (charty > BITMAPY) {
- charty = BITMAPY;
- xresize = TRUE;
- }
- }
-
- /* If in animation mode, ensure we are in the flicker free resolution. */
-
- if (xnow < 0) {
- xnow = -xnow;
- #ifdef MSG
- if (xscreen == hiresmode) {
- xscreen = loresmode;
- XBegin();
- chartx = config.numxpixels;
- charty = config.numypixels;
- if (chartx > charty)
- chartx = charty;
- if (ISEGA(xscreen))
- chartx = EGATOVGA(chartx);
- else if (ISCGA(xscreen))
- chartx = CGATOVGA(chartx);
- if ((modex == MODEv || modex == MODEw) && xtext &&
- !(exdisplay & DASHv0))
- chartx += SIDET;
- xresize = TRUE;
- }
- #endif
- }
-
- /* Physically resize window if we've changed the size parameters. */
-
- if (xresize) {
- xresize = FALSE;
- #ifdef X11
- XResizeWindow(disp, window, chartx, charty);
- XFreePixmap(disp, pixmap);
- pixmap = XCreatePixmap(disp, window, chartx, charty, depth);
- #else
- if (config.numxpixels > chartx)
- offsetx = (config.numxpixels - chartx) >> 1;
- else {
- if (xcorner % 3 == 1)
- offsetx = 0;
- else if (xcorner % 3 == 0)
- offsetx = -chartx + config.numxpixels;
- else
- offsetx = -(chartx - config.numxpixels) / 2;
- }
- if (config.numypixels > charty)
- offsety = (config.numypixels - charty) >> 1;
- else {
- if (xcorner > 6)
- offsety = 0;
- else if (xcorner < 4)
- offsety = -charty + config.numypixels;
- else
- offsety = -(charty - config.numypixels) / 2;
- }
- #endif
- xredraw = TRUE;
- }
-
- /* Recast chart if the chart information has changed any. */
-
- if (xcast) {
- xcast = FALSE;
- SetCore(Mon, Day, Yea, Tim, Zon, Lon, Lat);
- if (relation)
- CastRelation(FALSE);
- else
- CastChart(TRUE);
- xredraw = TRUE;
- }
- if (xnow && !xpause)
- xredraw = TRUE;
-
- /* Update the screen if anything has changed since last time around. */
-
- if (xredraw) {
- xredraw = FALSE;
-
- /* If we're in animation mode, change the chart info appropriately. */
-
- if (xnow)
- Animate(xnow, dir);
- #ifdef X11
- XFillRectangle(disp, pixmap, pmgc, 0, 0, chartx, charty);
- #else /* MSG */
- #ifdef MOUSE
- SetPtrVis(HIDE);
- #endif
- if (config.numvideopages > 1)
- _setactivepage(_getactivepage() == 0);
- #endif /* MSG */
- XChart();
- #ifdef X11
- XSync(disp, 0);
- XCopyArea(disp, pixmap, window, gc, 0, 0, chartx, charty, 0, 0);
- #else /* MSG */
- if (config.numvideopages > 1)
- _setvisualpage(_getactivepage());
- #ifdef MOUSE
- if (!xnow)
- SetPtrVis(SHOW);
- #endif
- #endif /* MSG */
- } /* if */
-
- /* Now process what's on the event queue, i.e. any keys pressed, etc. */
-
- #ifdef X11
- if (XEventsQueued(disp, QueuedAfterFlush /*QueuedAfterReading*/ )) {
- XNextEvent(disp, &event);
-
- /* Restore what's on window if a part of it gets uncovered. */
-
- if (event.type == Expose && event.xexpose.count == 0) {
- XSync(disp, 0);
- XCopyArea(disp, pixmap, window, gc, 0, 0, chartx, charty, 0, 0);
- }
- switch (event.type) {
-
- /* Check for a manual resize of window by user. */
-
- case ConfigureNotify:
- chartx = event.xconfigure.width;
- charty = event.xconfigure.height;
- XFreePixmap(disp, pixmap);
- pixmap = XCreatePixmap(disp, window, chartx, charty, depth);
- xredraw = TRUE;
- break;
- case MappingNotify:
- XRefreshKeyboardMapping((XMappingEvent PTR)&event);
- break;
-
- #ifdef MOUSE
- /* Process any mouse buttons the user pressed. */
-
- case ButtonPress:
- buttonx = event.xbutton.x; buttony = event.xbutton.y;
- if (event.xbutton.button == Button1) {
- DrawColor(hilite);
- DrawPoint(buttonx, buttony);
- XSync(disp, 0);
- XCopyArea(disp, pixmap, window, gc, 0, 0, chartx, charty, 0, 0);
- } else if (event.xbutton.button == Button2 &&
- (modex == MODEL || modex == MODEW) && degree == 0) {
- Lon = DEGHALF-(real)(event.xbutton.x-1)/(real)(chartx-2)*DEGREES;
- Lat = DEGQUAD-(real)(event.xbutton.y-1)/(real)(charty-2)*181.0;
- fprintf(S, "Mouse is at %s.\n", CharLocation(Lon, Lat, 60.0));
- } else if (event.xbutton.button == Button3)
- xbreak = TRUE;
- break;
-
- /* Check for user dragging any of the mouse buttons across window. */
-
- case MotionNotify:
- DrawColor(coldrw);
- DrawLine(buttonx, buttony, event.xbutton.x, event.xbutton.y);
- XSync(disp, 0);
- XCopyArea(disp, pixmap, window, gc, 0, 0, chartx, charty, 0, 0);
- buttonx = event.xbutton.x; buttony = event.xbutton.y;
- break;
- #endif
-
- /* Process any keys user pressed in window. */
-
- case KeyPress:
- length = XLookupString((XKeyEvent PTR)&event, xkey, 10, &key, 0);
- if (length == 1) {
- i = xkey[0];
- #else /* MSG */
- #ifdef MOUSE
- if (!xnow && GetMouseEvent((EVENT *)&event)) {
- if (event.fsBtn == LEFT_DOWN && buttonx >= 0) {
- SetPtrVis(HIDE);
- DrawColor(coldrw);
- _moveto(buttonx, buttony);
- buttonx = event.x; buttony = event.y;
- _lineto(buttonx, buttony);
- } else if (event.fsBtn == RIGHT_DOWN &&
- (modex == MODEL || modex == MODEW) && degree == 0) {
- Lon = DEGHALF-(real)(event.x-offsetx)/(real)(chartx-2)*DEGREES;
- if (Lon < -DEGHALF)
- Lon = -DEGHALF;
- else if (Lon > DEGHALF)
- Lon = DEGHALF;
- Lat = DEGQUAD-(real)(event.y-offsety)/(real)(charty-2)*181.0;
- if (Lat < -DEGQUAD)
- Lat = -DEGQUAD;
- else if (Lat > DEGQUAD)
- Lat = DEGQUAD;
- xcast = TRUE;
- } else if (event.fsBtn == MIDDLE_DOWN)
- xbreak = TRUE;
- else {
- buttonx = event.x; buttony = event.y;
- }
- SetPtrVis(SHOW);
- } else
- #endif
- if (kbhit()) {
- i = getch();
- #endif /* MSG */
- switch (i) {
- case ' ':
- xredraw = TRUE;
- break;
- case 'p':
- xpause = !xpause;
- break;
- case 'r':
- dir = -dir;
- break;
- case 'x':
- xreverse = !xreverse;
- XColorInit();
- xredraw = TRUE;
- break;
- case 'm':
- if (!xmono) {
- xcolor = !xcolor;
- #ifdef MSG
- _getvideoconfig((struct videoconfig far *) &config);
- #endif
- XColorInit();
- xredraw = TRUE;
- }
- break;
- case 'B':
- #ifdef X11
- XSetWindowBackgroundPixmap(disp, root, pixmap);
- XClearWindow(disp, root);
- #else
- chartx = config.numxpixels;
- charty = config.numypixels;
- if (modex == MODEv || modex == MODEw || modex == MODEg ||
- (modex == MODEZ && (exdisplay & DASHZ0) > 0) ||
- modex == MODES || modex == MODEG || modex == MODEP) {
- if (chartx > charty)
- chartx = charty;
- if (ISEGA(xscreen))
- chartx = EGATOVGA(chartx);
- else if (ISCGA(xscreen))
- chartx = CGATOVGA(chartx);
- if ((modex == MODEv || modex == MODEw) && xtext &&
- !(exdisplay & DASHv0))
- chartx += SIDET;
- }
- xresize = TRUE;
- #endif
- break;
- case 'T':
- xtext = !xtext;
- xredraw = TRUE;
- break;
- case 'i':
- xbonus = !xbonus;
- xredraw = TRUE;
- break;
- case 'b':
- xborder = !xborder;
- xredraw = TRUE;
- break;
- case 'l':
- xlabel = !xlabel;
- xredraw = TRUE;
- break;
- case '<':
- if (scale > 100) {
- scale -= 100;
- xresize = TRUE;
- }
- break;
- case '>':
- if (scale < 300) {
- scale += 100;
- xresize = TRUE;
- }
- break;
- case '[':
- if (modex == MODEG) {
- tilt = tilt > -DEGQUAD ? tilt-11.25 : -DEGQUAD;
- xredraw = TRUE;
- }
- break;
- case ']':
- if (modex == MODEG) {
- tilt = tilt < DEGQUAD ? tilt+11.25 : DEGQUAD;
- xredraw = TRUE;
- }
- break;
- case 'Q':
- if (chartx > charty)
- chartx = charty;
- else
- charty = chartx;
- #ifdef MSG
- if (ISEGA(xscreen))
- chartx = EGATOVGA(chartx);
- else if (ISCGA(xscreen))
- chartx = CGATOVGA(chartx);
- #endif
- xresize = TRUE;
- break;
- case 'R':
- for (i = 11; i <= 15; i++)
- ignore[i] = !ignore[i];
- ignore[_FOR] = !ignore[_FOR]; ignore[_VTX] = !ignore[_VTX];
- xredraw = TRUE;
- break;
- case 'C':
- operation ^= DASHC;
- for (i = C_LO; i <= C_HI; i++)
- ignore[i] = !ignore[i];
- xcast = TRUE;
- break;
- case 'u':
- operation ^= DASHu;
- for (i = U_LO; i <= U_HI; i++)
- ignore[i] = !ignore[i];
- xcast = TRUE;
- break;
- case 'U':
- universe = !universe;
- for (i = S_LO; i <= S_HI; i++)
- ignore[i] = !ignore[i];
- xcast = TRUE;
- break;
- case 'c':
- if (!relation) {
- relation = DASHr0;
- SetTwin(Mon, Day, Yea, Tim, Zon, Lon, Lat);
- } else
- relation = 0;
- xcast = TRUE;
- break;
- case 's':
- operation ^= DASHs;
- xcast = TRUE;
- break;
- case 'h':
- centerplanet = centerplanet ? 0 : 1;
- xcast = TRUE;
- break;
- case 'f':
- operation ^= DASHf;
- xcast = TRUE;
- break;
- case 'F':
- operation ^= DASH3;
- xcast = TRUE;
- break;
- case '+':
- Animate(4, abs(dir));
- xcast = TRUE;
- break;
- case '-':
- Animate(4, -abs(dir));
- xcast = TRUE;
- break;
- case 'o':
- SetSave(Mon, Day, Yea, Tim, Zon, Lon, Lat);
- break;
- case 'O':
- SetMain(MonX, DayX, YeaX, TimX, ZonX, LonX, LatX);
- xcast = TRUE;
- break;
- #ifdef TIME
- case 'n':
- InputData("now");
- SetMain(MM, DD, YY, TT, ZZ, OO, AA);
- xcast = TRUE;
- break;
- #endif
- case 'N': /* The continuous update animation. */
- xnow = xnow ? 0 : -10;
- break;
- case '!': xnow = -1; break; /* These are the nine different */
- case '@': xnow = -2; break; /* "add time to chart" animations. */
- case '#': xnow = -3; break;
- case '$': xnow = -4; break;
- case '%': xnow = -5; break;
- case '^': xnow = -6; break;
- case '&': xnow = -7; break;
- case '*': xnow = -8; break;
- case '(': xnow = -9; break;
- case 'V': modex = MODEv; xredraw = TRUE; break; /* Should we go */
- case 'L': modex = MODEL; xredraw = TRUE; break; /* switch to a */
- case 'A': modex = MODEg; xredraw = TRUE; break; /* new chart type? */
- case 'Z': modex = MODEZ; xredraw = TRUE; break;
- case 'S': modex = MODES; xredraw = TRUE; break;
- case 'E': modex = MODEE; xredraw = TRUE; break;
- case 'W': modex = MODEW; xredraw = TRUE; break;
- case 'G': modex = MODEG; xredraw = TRUE; break;
- case 'P': modex = MODEP; xredraw = TRUE; break;
- #ifdef BIORHYTHM
- case 'Y': /* Should we switch to biorhythm chart? */
- if (!relation) {
- SetTwin(Mon, Day, Yea, Tim, Zon, Lon, Lat);
- }
- relation = DASHrb;
- modex = MODEb;
- xcast = TRUE;
- break;
- #endif
- case '0':
- exdisplay ^= DASHZ0 | DASHEy | DASHXW0;
- modex = (modex == MODEv ? MODEw : (modex == MODEw ? MODEv :
- modex));
- xredraw = TRUE;
- break;
- case 'v': case 'H': case '?':
- #ifdef MSG
- _setvideomode(_DEFAULTMODE);
- if (i != 'v')
- _settextrows(43);
- #endif
- if (i == 'v')
- ChartLocation();
- else
- XDisplayKeys();
- #ifdef MSG
- while (!kbhit())
- ;
- i = getch();
- if (i == 'q' || i == ESCAPE || i == '\3') {
- xbreak = TRUE;
- break;
- }
- XBegin();
- xresize = TRUE;
- #endif
- break;
- #ifdef MSG
- case '\t':
- if (xscreen == hiresmode)
- xscreen = loresmode;
- else
- xscreen = hiresmode;
- XBegin();
- chartx = config.numxpixels;
- charty = config.numypixels;
- if (chartx > charty)
- chartx = charty;
- if (ISEGA(xscreen))
- chartx = EGATOVGA(chartx);
- else if (ISCGA(xscreen))
- chartx = CGATOVGA(chartx);
- if ((modex == MODEv || modex == MODEw) && xtext &&
- !(exdisplay & DASHv0))
- chartx += SIDET;
- xresize = TRUE;
- break;
- #endif
- case '\b':
- #ifdef MSG
- #ifdef MOUSE
- SetPtrVis(HIDE);
- #endif
- #endif /* MSG */
- DrawClearScreen();
- break;
- #ifdef MOUSE
- case 'z'-'`': coldrw = BLACK; break;
- case 'e'-'`': coldrw = MAROON; break;
- case 'f'-'`': coldrw = DKGREEN; break;
- case 'o'-'`': coldrw = ORANGE; break;
- case 'n'-'`': coldrw = DKBLUE; break;
- case 'u'-'`': coldrw = PURPLE; break;
- case 'k'-'`': coldrw = DKCYAN; break;
- case 'l'-'`': coldrw = LTGRAY; break;
- case 'd'-'`': coldrw = DKGRAY; break;
- case 'r'-'`': coldrw = RED; break;
- case 'g'-'`': coldrw = GREEN; break;
- case 'y'-'`': coldrw = YELLOW; break;
- case 'b'-'`': coldrw = BLUE; break;
- case 'v'-'`': coldrw = MAGENTA; break;
- case 'j'-'`': coldrw = CYAN; break;
- case 'a'-'`': coldrw = WHITE; break;
- #endif
- case 'q': case ESCAPE: case '\3':
- xbreak = TRUE;
- break;
- default:
- if (i > '0' && i <= '9') {
- #ifdef MSG
- if (xnow)
- #endif
- /* Process numbers 1..9 signifying animation rate. */
- dir = (dir > 0 ? 1 : -1)*(i-'0');
- #ifdef MSG
- else {
- /* If we aren't in animation mode, then 1..9 refers to the */
- /* clipping "quadrant" to use if chart size > screen size. */
- xcorner = i-'0';
- xresize = TRUE;
- }
- #endif
- break;
- }
- printc(BELL); /* Any key not bound will sound a beep. */
- } /* switch */
- } /* if */
- #ifdef X11
- default:
- ;
- } /* switch */
- } /* if */
- #endif
- } /* while */
- }
-
-
- /* This is called right before program termination to get rid of the window. */
-
- void XEnd()
- {
- #ifdef X11
- XFreeGC(disp, gc);
- XFreeGC(disp, pmgc);
- XFreePixmap(disp, pixmap);
- XDestroyWindow(disp, window);
- XCloseDisplay(disp);
- #else
- _setvideomode(_DEFAULTMODE);
- #endif
- }
- #endif /* ISG */
-
-
- /*
- ******************************************************************************
- ** Main graphics processing
- ******************************************************************************
- */
-
- /* Print a list of every command switch dealing with the graphics features */
- /* that can be passed to the program, and a description of what it does. */
- /* This is part of what the -H switch prints, if graphics were compiled in. */
-
- void XDisplaySwitches()
- {
- Prints(" _X: Create a graphics chart instead of displaying it as text.");
- #ifdef ISG
- Prints(" _Xb: Create bitmap file instead of putting graphics on screen.");
- #endif
- Prints(" _Xb[n,c,v,a,b]: Set bitmap file output mode to X11 normal,");
- Prints(" compacted, very compact, Ascii (bmtoa), or Windows bmp.");
- #ifdef PS
- Prints(" _Xp: Create PostScript stroke graphic instead of bitmap file.");
- Prints(" _Xp0: Like _Xp but create complete instead of encapsulated file.");
- #endif
- #ifdef META
- Prints(" _XM[0]: Create Windows metafile stroke graphic instead of bitmap.");
- #endif
- Prints(" _Xo <file>: Write output bitmap or graphic to specified file.");
- #ifdef X11
- Prints(" _XB: Display X chart on root instead of in a separate window.");
- #endif
- Prints(" _Xm: Create monochrome graphic instead of one in color.");
- Prints(" _Xr: Create chart graphic in reversed colors (white background).");
- #ifdef X11
- Prints(" _Xw <hor> [<ver>], _ge[..]: Change the size of chart graphic.");
- #else
- Prints(" _Xw <hor> [<ver>]: Change the size of chart graphic.");
- #endif
- Prints(" _Xs <100,200,300>: Change the size of map or characters by n%.");
- Prints(" _Xi: Create chart graphic in slightly modified form.");
- Prints(" _XT: Inhibit display of chart info at bottom of graphic.");
- Prints(" _Xl: Inhibit labeling of object points in chart graphic.");
- Prints(" _X1 <object>: Rotate wheel charts so object is at left edge.");
- Prints(" _X2 <object>: Rotate wheel charts so object is at top edge.");
- #ifdef X11
- Prints(" _Xd <name>, _di[..] <name>: Open X window on specified display.");
- #endif
- Prints(" _XW: Simply create an image of the world map.");
- Prints(" _XW0: Like _XW but do a non-rectangular Mollewide projection.");
- Prints(" _XP: Create just the world map, but from a polar projection.");
- Prints(" _XG [<degrees>]: Display the image of the world as a globe.");
- #ifdef ISG
- Prints(" _Xn [<mode>]: Start up chart or globe display in animation mode.");
- Prints("Also, press 'H' while running for list of key press options.");
- #endif
- }
-
-
- /* Process a command line switch passed to the program dealing with the */
- /* graphics features. This is just like the processing of each switch in the */
- /* main program; however, here each switch has been prefixed with an 'X'. */
-
- int XProcessSwitches(argc, argv, pos)
- int argc, pos;
- char **argv;
- {
- int i = 0;
- char string[STRING], c;
-
- switch (argv[0][pos]) {
- case '\0':
- break;
-
- case 'b':
- c = CAP(argv[0][pos+1]);
- if (IsValidBmpmode(c))
- bitmapmode = c;
- xbitmap = TRUE;
- psfile = metafile = FALSE;
- break;
-
- #ifdef PS
- case 'p':
- psfile = TRUE + (argv[0][pos+1] != '0');
- xbitmap = metafile = FALSE;
- break;
- #endif
-
- #ifdef META
- case 'M':
- if (argv[0][pos+1] == '0')
- xfont = !xfont;
- metafile = TRUE;
- xbitmap = psfile = FALSE;
- break;
- #endif
-
- case 'o':
- if (argc <= 1) {
- TooFew("Xo");
- return -1;
- }
- if (!xbitmap && !psfile && !metafile)
- xbitmap = TRUE;
- outputfile = argv[1];
- i++;
- break;
-
- #ifdef X11
- case 'B':
- xroot = !xroot;
- break;
- #endif
-
- case 'm':
- xcolor = !xcolor;
- break;
-
- case 'r':
- xreverse = !xreverse;
- break;
-
- case 'w':
- if (argc <= 1) {
- TooFew("Xw");
- return -1;
- }
- chartx = atoi(argv[1]);
- if (argc > 2 && (charty = atoi(argv[2]))) {
- argc--; argv++;
- i++;
- } else
- charty = chartx;
- if (!IsValidGraphx(chartx)) {
- BadVal("Xw", chartx);
- return -1;
- }
- if (!IsValidGraphy(charty)) {
- BadVal("Xw", charty);
- return -1;
- }
- i++;
- break;
-
- case 's':
- if (argc <= 1) {
- TooFew("Xs");
- return -1;
- }
- scale = atoi(argv[1]);
- if (scale < 100)
- scale *= 100;
- if (!IsValidScale(scale)) {
- BadVal("Xs", scale);
- return -1;
- }
- i++;
- break;
-
- case 'i':
- xbonus = !xbonus;
- break;
-
- case 'T':
- xtext = !xtext;
- break;
-
- case 'l':
- xlabel = !xlabel;
- break;
-
- case '1':
- if (argc <= 1) {
- TooFew("X1");
- return -1;
- }
- xeast = atoi(argv[1]);
- if (!IsItem(xeast)) {
- BadVal("X1", xeast);
- return -1;
- }
- i++;
- break;
-
- case '2':
- if (argc <= 1) {
- TooFew("X2");
- return -1;
- }
- xeast = atoi(argv[1]);
- if (!IsItem(xeast)) {
- BadVal("X2", xeast);
- return -1;
- }
- xeast = -xeast;
- i++;
- break;
-
- case 'd':
- if (argc <= 1) {
- TooFew("Xd");
- return -1;
- }
- dispname = argv[1];
- i++;
- break;
-
- case 'W':
- if (argc > 1 && ((degree = atoi(argv[1])) || argv[1][0] == '0')) {
- i++;
- if (degree < 0 || degree >= DEGR) {
- BadVal("XW", degree);
- return -1;
- }
- } else
- degree = 0;
- modex = MODEW;
- if (argv[0][pos+1] == '0')
- exdisplay |= DASHXW0;
- autom = TRUE;
- break;
-
- case 'P':
- if (argc > 1 && ((degree = atoi(argv[1])) || argv[1][0] == '0')) {
- i++;
- if (degree < 0 || degree >= DEGR) {
- BadVal("XP", degree);
- return -1;
- }
- } else
- degree = 0;
- modex = MODEP;
- if (argv[0][pos+1] == '0')
- exdisplay |= DASHXP0;
- autom = TRUE;
- break;
-
- case 'G':
- if (argc > 1 && ((degree = atoi(argv[1])) || argv[1][0] == '0')) {
- i++;
- if (degree < 0 || degree >= DEGR) {
- BadVal("XG", degree);
- return -1;
- }
- if (argc > 2 && ((tilt = atof(argv[2])) || argv[2][0] == '0')) {
- i++;
- if (tilt < -DEGQUAD || tilt > DEGQUAD) {
- BadVal2("XG", tilt);
- return -1;
- }
- }
- }
- modex = MODEG;
- autom = TRUE;
- break;
-
- #ifdef ISG
- case 'n':
- if (argc > 1 && (xnow = atoi(argv[1])))
- i++;
- else
- xnow = 10;
- if (xnow < 1 || xnow > 10) {
- BadVal("Xn", xnow);
- return -1;
- }
- break;
- #endif
-
- default:
- sprintf(string, "Unknown switch '%s'", argv[0]);
- PrintError(string);
- return -1;
- }
- return i; /* 'i' contains the value to be added to argc when we return. */
- }
-
-
- /* This is the main interface to all the graphics features. This routine */
- /* is called from the main program if any of the -X switches were specified, */
- /* and it sets up for and goes and generates the appropriate graphics chart. */
- /* We return TRUE if successfull, FALSE if some non-fatal error occurred. */
-
- bool XAction()
- {
- char string[STRING];
-
- xfile = (xbitmap || psfile || metafile);
-
- /* First figure out what graphic mode to generate the chart in, based on */
- /* various non-X command switches, e.g. -L combined with -X, -g combined */
- /* with -X, and so on, and determine the size the window is to be, too. */
-
- if (modex == MODEv) {
- if (todisplay & DASHw)
- modex = MODEw;
- else if (todisplay & DASHL)
- modex = MODEL;
- else if ((todisplay & DASHg) | (todisplay & DASHm)) {
- modex = MODEg;
- if (relation <= DASHr0 &&
- (todisplay & DASHm) > 0 && (exdisplay & DASHm0) == 0)
- exdisplay |= DASHg0;
- chartx = charty =
- (gridobjects + (relation <= DASHr0))*CELLSIZE*SCALE + 1;
- } else if (todisplay & DASHZ)
- modex = MODEZ;
- else if (todisplay & DASHS)
- modex = MODES;
- else if (todisplay & DASHE)
- modex = MODEE;
- else if (relation == DASHrb)
- modex = MODEb;
- }
- if ((modex == MODEv || modex == MODEw) && !(exdisplay & DASHv0))
- chartx += SIDESIZE;
- if (modex == MODEL || modex == MODEW) {
- chartx = DEGR*SCALE+2;
- charty = (90*2+1)*SCALE+2;
- }
- if (xfile) { /* Initialize bitmap or window. */
- if (chartx > BITMAPX)
- chartx = BITMAPX;
- if (charty > BITMAPY)
- charty = BITMAPY;
- if (xbitmap) {
- bitmaprow = (chartx + 1) >> 1;
- Allocate(bm, (long)bitmaprow * charty, bitmap);
- if (bm == NULL) {
- sprintf(string,
- "Not enough memory for %d by %d bitmap (%ld bytes).",
- chartx, charty, (long)bitmaprow * charty);
- PrintError(string);
- return FALSE;
- }
- }
- #ifdef PS
- else if (psfile)
- PSbegin();
- #endif
- else {
- Allocate(bm, MAXMETA, bitmap);
- if (bm == NULL) {
- sprintf(string,
- "Not enough memory for metafile. (%ld bytes.)", MAXMETA);
- PrintError(string);
- return FALSE;
- }
- chartx *= METAMUL; /* Increase chart sizes and scales behind the */
- charty *= METAMUL; /* scenes to make graphics look smoother. */
- scale *= METAMUL;
- }
- XColorInit();
- }
- #ifdef ISG
- else
- XBegin();
- #endif
- if (xroot || xfile) /* Go draw the graphic chart. */
- XChart();
- if (xfile) { /* Write bitmap to file if in that mode. */
- WriteFile();
- if (!psfile)
- Deallocate(bm);
- }
- #ifdef ISG
- else {
- #ifdef X11
- if (xroot) {
- XSetWindowBackgroundPixmap(disp, root, pixmap); /* Process -XB. */
- XClearWindow(disp, root);
-
- /* If -Xn in effect with -XB, then enter infinite loop where we */
- /* calculate and animate chart, displaying on the root window. */
- if (xnow)
- loop {
- Animate(xnow, 1);
- if (relation > DASHr0 || (modex != MODEZ && modex != MODES))
- XFillRectangle(disp, pixmap, pmgc, 0, 0, chartx, charty);
- XChart();
- XSetWindowBackgroundPixmap(disp, root, pixmap);
- XClearWindow(disp, root);
- }
- } else
- #endif
- XSpin(); /* Window's up; process commands given to window now. */
- XEnd();
- return TRUE;
- }
- #endif /* ISG */
- }
- #endif /* GRAPH */
-
- /* xdriver.c */
-