/* ** Astrolog (Version 4.40) File: xscreen.c ** ** IMPORTANT NOTICE: The graphics database and chart display routines ** used in this program are Copyright (C) 1991-1995 by Walter D. Pullen ** (astara@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 1/29/1995. */ #include "astrolog.h" #ifdef ATARI /* Ajout Abel PHILIPPE */ #include void BGIDriver(void); #endif #ifdef GRAPH /* ****************************************************************************** ** Astrolog Icon. ****************************************************************************** */ #ifdef X11 /* This information used to define Astrolog's X icon (Rainbow over Third */ /* Eye) is identical to the output format used by the bitmap program. */ /* You could extract this section and run xsetroot -bitmap on it. */ #define icon_width 63 #define icon_height 32 static char icon_bits[] = { 0x00,0x00,0x00,0xa8,0x0a,0x00,0x00,0x00,0x00,0x00,0x40,0x55,0x55,0x01,0x00, 0x00,0x00,0x00,0xa8,0xaa,0xaa,0x0a,0x00,0x00,0x00,0x00,0x54,0xf5,0x57,0x15, 0x00,0x00,0x00,0x80,0xaa,0xaa,0xaa,0xaa,0x00,0x00,0x00,0x40,0xd5,0xff,0xff, 0x55,0x01,0x00,0x00,0xa0,0xaa,0xaa,0xaa,0xaa,0x02,0x00,0x00,0x50,0xfd,0xff, 0xff,0x5f,0x05,0x00,0x00,0xa8,0xaa,0x2a,0xaa,0xaa,0x0a,0x00,0x00,0xd4,0xff, 0xaf,0xfa,0xff,0x15,0x00,0x00,0xaa,0x2a,0x00,0x00,0xaa,0x2a,0x00,0x00,0xf5, 0xbf,0xaa,0xaa,0xfe,0x57,0x00,0x80,0xaa,0x02,0x00,0x00,0xa0,0xaa,0x00,0x40, 0xfd,0xab,0xfa,0xaf,0xea,0x5f,0x01,0xa0,0xaa,0x80,0xff,0xff,0x80,0xaa,0x02, 0x50,0xff,0xea,0xff,0xff,0xab,0x7f,0x05,0xa0,0x2a,0xf0,0xff,0xff,0x07,0xaa, 0x02,0xd0,0xbf,0xfa,0x0f,0xf8,0xaf,0x7e,0x05,0xa8,0x0a,0xfc,0x01,0xc0,0x1f, 0xa8,0x0a,0xd4,0xaf,0x7e,0x00,0x00,0xbf,0xfa,0x15,0xa8,0x0a,0x3f,0x00,0x00, 0x7e,0xa8,0x0a,0xf4,0xaf,0x1f,0xe0,0x03,0xfc,0xfa,0x15,0xaa,0x82,0x0f,0xdc, 0x1d,0xf8,0xa0,0x2a,0xf4,0xab,0x07,0x23,0x62,0xf0,0xea,0x17,0xaa,0xc2,0x87, 0x91,0xc4,0xf0,0xa1,0x2a,0xf4,0xeb,0xc3,0xd0,0x85,0xe1,0xeb,0x17,0xaa,0xe0, 0x83,0x91,0xc4,0xe0,0x83,0x2a,0xf5,0xeb,0x03,0x23,0x62,0xe0,0xeb,0x57,0xaa, 0xe0,0x01,0xdc,0x1d,0xc0,0x83,0x2a,0xf5,0xeb,0x01,0xe0,0x03,0xc0,0xeb,0x57, 0xaa,0xe0,0x01,0x00,0x00,0xc0,0x83,0x2a,0xfd,0xeb,0x01,0x00,0x00,0xc0,0xeb, 0x5f}; #endif /* ****************************************************************************** ** Interactive Screen Graphics Routines. ****************************************************************************** */ /* 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 InitColorsX() { int i; #ifdef X11 Colormap cmap; XColor xcol; if (!gi.fFile) { cmap = XDefaultColormap(gi.disp, gi.screen); /* Allocate a color from the present X11 colormap. Given a string like */ /* "violet", allocate this color and return a value specifying it. */ for (i = 0; i < 16; i++) { XParseColor(gi.disp, cmap, szColorX[i], &xcol); XAllocColor(gi.disp, cmap, &xcol); rgbind[i] = xcol.pixel; } } #endif gi.kiOn = kMainA[!gs.fInverse]; gi.kiOff = kMainA[gs.fInverse]; gi.kiLite = gs.fColor ? kMainA[2+gs.fInverse] : gi.kiOn; gi.kiGray = gs.fColor ? kMainA[3-gs.fInverse] : gi.kiOn; for (i = 0; i <= 8; i++) kMainB[i] = gs.fColor ? kMainA[i] : gi.kiOn; for (i = 0; i <= 7; i++) kRainbowB[i] = gs.fColor ? kRainbowA[i] : gi.kiOn; for (i = 0; i < 4; i++) kElemB[i] = gs.fColor ? kElemA[i] : gi.kiOn; for (i = 0; i <= cAspect; i++) kAspB[i] = gs.fColor ? kAspA[i] : gi.kiOn; for (i = 0; i <= cObj; i++) kObjB[i] = gs.fColor ? kObjA[i] : gi.kiOn; #ifdef X11 if (!gi.fFile) { XSetBackground(gi.disp, gi.gc, rgbind[gi.kiOff]); XSetForeground(gi.disp, gi.pmgc, rgbind[gi.kiOff]); } #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 BeginX() { #ifdef X11 gi.disp = XOpenDisplay(gs.szDisplay); if (gi.disp == NULL) { PrintError("Can't open display."); Terminate(tcFatal); } gi.screen = DefaultScreen(gi.disp); bg = BlackPixel(gi.disp, gi.screen); fg = WhitePixel(gi.disp, gi.screen); hint.x = gi.xOffset; hint.y = gi.yOffset; hint.width = gs.xWin; hint.height = gs.yWin; 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(gi.disp, gi.wind); wmhint->input = True; XSetWMHints(gi.disp, gi.wind, wmhint); #endif gi.depth = DefaultDepth(gi.disp, gi.screen); if (gi.depth < 5) { gi.fMono = fTrue; /* Is this a monochrome monitor? */ gs.fColor = fFalse; } gi.root = RootWindow(gi.disp, gi.screen); if (gs.fRoot) gi.wind = gi.root; /* If -XB in effect, we'll use the root window. */ else gi.wind = XCreateSimpleWindow(gi.disp, DefaultRootWindow(gi.disp), hint.x, hint.y, hint.width, hint.height, 5, fg, bg); gi.pmap = XCreatePixmap(gi.disp, gi.wind, gs.xWin, gs.yWin, gi.depth); gi.icon = XCreateBitmapFromData(gi.disp, DefaultRootWindow(gi.disp), icon_bits, icon_width, icon_height); if (!gs.fRoot) XSetStandardProperties(gi.disp, gi.wind, szAppName, szAppName, gi.icon, (char **)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. */ gi.gc = XCreateGC(gi.disp, gi.wind, 0, 0); XSetGraphicsExposures(gi.disp, gi.gc, 0); gi.pmgc = XCreateGC(gi.disp, gi.wind, 0, 0); InitColorsX(); /* Go set up colors. */ if (!gs.fRoot) XSelectInput(gi.disp, gi.wind, KeyPressMask | StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask); XMapRaised(gi.disp, gi.wind); XSync(gi.disp, 0); XFillRectangle(gi.disp, gi.pmap, gi.pmgc, 0, 0, gs.xWin, gs.yWin); #endif /* X11 */ #ifdef MSG if (!FValidResmode(gi.nRes)) /* Initialize graphics mode to hi-res. */ gi.nRes = gs.nResHi; _setvideomode(gi.nRes); if (_grstatus()) { PrintError("Can't enter graphics mode."); Terminate(tcFatal); } _getvideoconfig((struct videoconfig far *) &gi.cfg); if (gi.cfg.numcolors < 16) { gi.fMono = fTrue; gs.fColor = fFalse; } _remapallpalette((long FAR *) rgb); _setactivepage(0); _setvisualpage(0); InitColorsX(); #ifdef MOUSE MouseInit(xPcScreen, yPcScreen); #endif /* Make sure we reset textrows upon restart. */ gs.nTextRows = abs(gs.nTextRows); #endif /* MSG */ #ifdef BGI int i; static struct palettetype pal; if (!FValidResmode(gi.nRes)) /* Initialize graphics mode to hi-res. */ gi.nRes = gs.nResHi; if (!gi.fLoaded) { #ifdef ATARI registerbgidriver(BGIDriver); #else /* Ajout Abel PHILIPPE */ registerfarbgidriver(ATT_driver_far); /* attf.obj */ registerfarbgidriver(CGA_driver_far); /* cgaf.obj */ registerfarbgidriver(EGAVGA_driver_far); /* egavgaf.obj */ registerfarbgidriver(Herc_driver_far); /* hercf.obj */ registerfarbgidriver(IBM8514_driver_far); /* ibm8514f.obj */ registerfarbgidriver(PC3270_driver_far); /* pc3270f.obj */ #endif /* Ajout Abel PHILIPPE */ gi.nDriver = DETECT; initgraph(&gi.nDriver, &gi.nGraph, ""); gi.fLoaded = fTrue; } if (gi.nRes <= 0) { switch (gi.nDriver) { case CGA: gi.nGraph = CGAHI; break; case MCGA: gi.nGraph = MCGAHI; break; case EGA: gi.nGraph = EGAHI; break; case EGA64: gi.nGraph = EGA64HI; break; case EGAMONO: gi.nGraph = EGAMONOHI; break; case HERCMONO: gi.nGraph = HERCMONOHI; break; case ATT400: gi.nGraph = ATT400HI; break; case VGA: gi.nGraph = VGAHI; break; case PC3270: gi.nGraph = PC3270HI; break; case IBM8514: gi.nGraph = IBM8514HI; break; default: gi.nGraph = 0; } } else { switch (gi.nDriver) { case CGA: gi.nGraph = CGAHI; break; case MCGA: gi.nGraph = MCGAHI; break; case EGA: gi.nGraph = EGAHI; break; case EGA64: gi.nGraph = EGA64HI; break; case EGAMONO: gi.nGraph = EGAMONOHI; break; case HERCMONO: gi.nGraph = HERCMONOHI; break; case ATT400: gi.nGraph = ATT400HI; break; case VGA: gi.nGraph = VGAMED; break; case PC3270: gi.nGraph = PC3270HI; break; case IBM8514: gi.nGraph = IBM8514LO; break; default: gi.nGraph = 0; } } #ifdef ATARI /* Ajout Abel PHILIPPE */ Cur_off(); #endif setgraphmode(gi.nGraph); if (graphresult()) { PrintError("Can't enter graphics mode."); Terminate(tcFatal); } gi.nPages = 1 + (gi.nDriver == HERCMONO || (gi.nDriver == VGA && gi.nGraph != VGAHI) || gi.nDriver == EGA); if (getmaxcolor()+1 < 16) { gi.fMono = fTrue; gs.fColor = fFalse; } getpalette(&pal); for (i = 0; i < pal.size; i++) pal.colors[i] = (char)rgb[i]; setallpalette(&pal); setactivepage(0); setvisualpage(0); gi.nPageCur = 0; InitColorsX(); #ifdef MOUSE MouseInit(xPcScreen, yPcScreen); #endif /* Make sure we reset textrows upon restart. */ gs.nTextRows = abs(gs.nTextRows); #endif /* BGI */ } /* 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; if (!FBetween(mode, 1, 9)) mode = 4; h = RFloor(TT); m = RFract(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 = NSgn(toadd); } else if (m < 0.0) { m += 60.0; toadd = NSgn(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 = NSgn(toadd); } else if (h < 0.0) { h += 24.0; toadd = NSgn(toadd); } DD = AddDay(MM, DD, YY, 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 = NSgn(toadd); } else if (DD < 1) { DD += DayInMonth(Mod12(MM - 1), YY); toadd = NSgn(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 = NSgn(toadd); } else if (MM < 1) { MM += 12; toadd = NSgn(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 (gi.nMode == gWorldMap || gi.nMode == gGlobe || gi.nMode == gPolar) { gs.nRot += toadd; if (gs.nRot >= nDegMax) /* For animating globe display, add */ gs.nRot -= nDegMax; /* in appropriate degree value. */ else if (gs.nRot < 0) gs.nRot += nDegMax; } else { if (mode == 10) { #ifdef TIME /* For the continuous chart update to present moment */ /* animation mode, go get whatever time it is now. */ FInputData(szNowCore); #else ciCore = ciMain; AddTime(1, toadd); #endif } else { /* Otherwise add on appropriate time vector to chart info. */ ciCore = ciMain; AddTime(mode, toadd); } ciMain = ciCore; if (us.nRel) CastRelation(fFalse); else CastChart(fTrue); } } /* This routine exits graphics mode, prompts the user for a set of command */ /* switches, processes them, and returns to the previous graphics with the */ /* new settings in effect, allowing one to change most any setting without */ /* having to lose their graphics state or fall way back to a -Q loop. */ void CommandLineX() { char szCommandLine[cchSzMax], *rgsz[MAXSWITCHES]; int argc, fT, fPause = fFalse; ciCore = ciMain; #ifdef MSG _setvideomode(_DEFAULTMODE); _settextrows(gs.nTextRows); #endif #ifdef BGI restorecrtmode(); #ifdef ATARI /* Ajout Abel PHILIPPE */ Cur_on(); #else if (gs.nTextRows > 25) textmode(C4350); #endif /* Ajout Abel PHILIPPE */ #endif fT = us.fLoop; us.fLoop = fTrue; argc = NPromptSwitches(szCommandLine, rgsz); is.cchRow = 0; is.fSzInteract = fTrue; if (!FProcessSwitches(argc, rgsz)) fPause = fTrue; else { is.fMult = fFalse; FPrintTables(); if (is.fMult) { ClearB((lpbyte)&us.fCredit, (int)((lpbyte)&us.fLoop - (lpbyte)&us.fCredit)); fPause = fTrue; } } #ifdef PCG /* Pause for the user if there was either an error processing the */ /* switches, or one of the informational text tables was brought up. */ if (fPause) { AnsiColor(kDefault); is.cchRow = 0; PrintSz("Press any key to return to graphics.\n"); while (!kbhit()) ; getch(); } #endif is.fSzInteract = fFalse; us.fLoop = fT; ciMain = ciCore; BeginX(); } /* Given two chart size values, adjust them such that the chart will look */ /* "square". We round the higher value down and check certain conditions. */ void SquareX(x, y, force) int *x, *y, force; { if (!force && !fSquare) /* Unless we want to force a square, realize */ return; /* that some charts look better rectangular. */ if (*x > *y) *x = *y; else *y = *x; #ifdef PCG if (FEgaRes(gi.nRes)) /* Scale horizontal size if we're in a PC */ *x = VgaFromEga(*x); /* graphics mode without "square" pixels. */ else if (FCgaRes(gi.nRes)) *x = VgaFromCga(*x); #endif if (fSidebar) /* Take into account chart's sidebar, if any. */ *x += xSideT; } /* This routine gets called after graphics are 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 InteractX() { #ifdef X11 char sz[cchSzDef]; XEvent xevent; KeySym keysym; int fResize = fFalse, fRedraw = fTrue; #else /* PCG */ #ifdef MOUSE int eventx, eventy, eventbtn; #endif int fResize = fTrue, fRedraw = fFalse; #endif /* PCG */ int fBreak = fFalse, fPause = fFalse, fCast = fFalse, xcorner = 7, #ifdef MOUSE mousex = -1, mousey = -1, buttonx = -1, buttony = -1, #endif dir = 1, length, key, i; bool fT; #ifdef MOUSE KI coldrw = gi.kiLite; #endif neg(gs.nAnim); while (!fBreak) { gi.nScale = gs.nScale/100; /* Some chart windows, like the world maps and aspect grids, should */ /* always be a certian size, so correct if a resize was attempted. */ if (fMap) { length = nDegMax*gi.nScale; if (gs.xWin != length) { gs.xWin = length; fResize = fTrue; } length = nDegHalf*gi.nScale; if (gs.yWin != length) { gs.yWin = length; fResize = fTrue; } } else if (gi.nMode == gGrid) { if (gs.xWin != (length = (gs.nGridCell + (us.nRel <= rcDual))*CELLSIZE*gi.nScale+1)) { gs.xWin = length; fResize = fTrue; } if (gs.yWin != length) { gs.yWin = length; fResize = fTrue; } /* Make sure the window isn't too large or too small. */ } else { if (gs.xWin < BITMAPX1) { gs.xWin = BITMAPX1; fResize = fTrue; } else if (gs.xWin > BITMAPX) { gs.xWin = BITMAPX; fResize = fTrue; } if (gs.yWin < BITMAPY1) { gs.yWin = BITMAPY1; fResize = fTrue; } else if (gs.yWin > BITMAPY) { gs.yWin = BITMAPY; fResize = fTrue; } } /* If in animation mode, ensure we are in the flicker free resolution. */ if (gs.nAnim < 0) { neg(gs.nAnim); #ifdef PCG if (gi.nRes == gs.nResHi && !gs.fJetTrail) { gi.nRes = gs.nResLo; BeginX(); gs.xWin = xPcScreen; gs.yWin = yPcScreen; SquareX(&gs.xWin, &gs.yWin, fFalse); fResize = fTrue; } #endif } /* Physically resize window if we've changed the size parameters. */ if (fResize) { fResize = fFalse; #ifdef X11 XResizeWindow(gi.disp, gi.wind, gs.xWin, gs.yWin); XFreePixmap(gi.disp, gi.pmap); gi.pmap = XCreatePixmap(gi.disp, gi.wind, gs.xWin, gs.yWin, gi.depth); #else if (xPcScreen > gs.xWin) gi.xOffset = (xPcScreen - gs.xWin) / 2; else { if (xcorner % 3 == 1) gi.xOffset = 0; else if (xcorner % 3 == 0) gi.xOffset = -gs.xWin + xPcScreen; else gi.xOffset = -(gs.xWin - xPcScreen) / 2; } if (yPcScreen > gs.yWin) gi.yOffset = (yPcScreen - gs.yWin) / 2; else { if (xcorner > 6) gi.yOffset = 0; else if (xcorner < 4) gi.yOffset = -gs.yWin + yPcScreen; else gi.yOffset = -(gs.yWin - yPcScreen) / 2; } #endif fRedraw = fTrue; } /* Recast chart if the chart information has changed any. */ if (fCast) { fCast = fFalse; ciCore = ciMain; if (us.nRel) CastRelation(fFalse); else CastChart(fTrue); fRedraw = fTrue; } if (gs.nAnim && !fPause) fRedraw = fTrue; /* Update the screen if anything has changed since last time around. */ if (fRedraw) { fRedraw = fFalse; /* If we're in animation mode, change the chart info appropriately. */ if (gs.nAnim && !fPause) Animate(gs.nAnim, dir); /* Clear the screen and set up a buffer to draw in. */ #ifdef X11 XFillRectangle(gi.disp, gi.pmap, gi.pmgc, 0, 0, gs.xWin, gs.yWin); #else /* PCG */ #ifdef MOUSE MouseShow(fFalse); #endif #ifdef MSG if (gi.cfg.numvideopages > 1) _setactivepage(_getactivepage() == gs.fJetTrail); #else if (gi.nPages > 1) { gi.nPageCur = (gi.nPageCur == gs.fJetTrail); setactivepage(gi.nPageCur); } #endif #endif /* PCG */ DrawChartX(); /* Make the drawn chart visible in the current screen buffer. */ #ifdef X11 XSync(gi.disp, 0); XCopyArea(gi.disp, gi.pmap, gi.wind, gi.gc, 0, 0, gs.xWin, gs.yWin, 0, 0); #else /* PCG */ #ifdef MSG if (gi.cfg.numvideopages > 1) _setvisualpage(_getactivepage()); #else if (gi.nPages > 1) setvisualpage(gi.nPageCur); #endif #ifdef MOUSE if (!gs.nAnim || fPause) MouseShow(fTrue); #endif #endif /* PCG */ } /* if */ /* Now process what's on the event queue, i.e. any keys pressed, etc. */ #ifdef X11 if (XEventsQueued(gi.disp, QueuedAfterFlush /*QueuedAfterReading*/) || !gs.nAnim || fPause) { XNextEvent(gi.disp, &xevent); /* Restore what's on window if a part of it gets uncovered. */ if (xevent.type == Expose && xevent.xexpose.count == 0) { XSync(gi.disp, 0); XCopyArea(gi.disp, gi.pmap, gi.wind, gi.gc, 0, 0, gs.xWin, gs.yWin, 0, 0); } switch (xevent.type) { /* Check for a manual resize of window by user. */ case ConfigureNotify: gs.xWin = xevent.xconfigure.width; gs.yWin = xevent.xconfigure.height; XFreePixmap(gi.disp, gi.pmap); gi.pmap = XCreatePixmap(gi.disp, gi.wind, gs.xWin, gs.yWin, gi.depth); fRedraw = fTrue; break; case MappingNotify: XRefreshKeyboardMapping((XMappingEvent *)&xevent); break; #ifdef MOUSE /* Process any mouse buttons the user pressed. */ case ButtonPress: mousex = xevent.xbutton.x; mousey = xevent.xbutton.y; if (xevent.xbutton.button == Button1) { DrawColor(gi.kiLite); DrawPoint(mousex, mousey); XSync(gi.disp, 0); XCopyArea(gi.disp, gi.pmap, gi.wind, gi.gc, 0, 0, gs.xWin, gs.yWin, 0, 0); } else if (xevent.xbutton.button == Button2 && (gi.nMode == gAstroGraph || gi.nMode == gWorldMap) && gs.nRot == 0) { Lon = DegToDec(rDegHalf - (real)(xevent.xbutton.x-1)/(real)(gs.xWin-2)*rDegMax); Lat = DegToDec(rDegQuad - (real)(xevent.xbutton.y-1)/(real)(gs.yWin-2)*181.0); sprintf(sz, "Mouse is at %s.", SzLocation(Lon, Lat)); PrintNotice(sz); } else if (xevent.xbutton.button == Button3) fBreak = fTrue; break; /* Check for user dragging any of the mouse buttons across window. */ case MotionNotify: DrawColor(coldrw); DrawLine(mousex, mousey, xevent.xbutton.x, xevent.xbutton.y); XSync(gi.disp, 0); XCopyArea(gi.disp, gi.pmap, gi.wind, gi.gc, 0, 0, gs.xWin, gs.yWin, 0, 0); mousex = xevent.xbutton.x; mousey = xevent.xbutton.y; break; #endif /* Process any keys user pressed in window. */ case KeyPress: length = XLookupString((XKeyEvent *)&xevent, xkey, 10, &keysym, 0); if (length == 1) { key = xkey[0]; #else /* PCG */ #ifdef MOUSE if ((!gs.nAnim || fPause) && MouseStatus(&eventx, &eventy, &eventbtn)) { /* If the left button is down, draw on the screen. */ if (eventbtn == mfLeft && mousex >= 0) { MouseShow(fFalse); DrawColor(coldrw); PcMoveTo(mousex, mousey); buttonx = eventx; buttony = eventy; PcLineTo(buttonx, buttony); /* If the right button is down, change the default location. */ } else if (eventbtn == mfRight) { if (fMap && gs.nRot == 0 && !gs.fConstel && !gs.fMollewide) { Lon = rDegHalf-(real)(eventx-gi.xOffset)/(real)(gs.xWin-2)*rDegMax; if (Lon < -rDegHalf) Lon = -rDegHalf; else if (Lon > rDegHalf) Lon = rDegHalf; Lat = rDegQuad-(real)(eventy-gi.yOffset)/(real)(gs.yWin-2)*181.0; if (Lat < -rDegQuad) Lat = -rDegQuad; else if (Lat > rDegQuad) Lat = rDegQuad; fCast = fTrue; /* Right button means draw lines if not in a world map mode. */ } else if (buttonx >= 0) { MouseShow(fFalse); DrawColor(coldrw); PcMoveTo(buttonx, buttony); PcLineTo(eventx, eventy); } /* Middle button (which most PC's don't have) means exit program. */ } else if (eventbtn == mfMiddle) fBreak = fTrue; mousex = eventx; mousey = eventy; MouseShow(fTrue); } else #endif /* MOUSE */ if (kbhit()) { key = getch(); #endif /* PCG */ LSwitch: switch (key) { #ifdef PCG case chNull: key = NFromAltN(getch()); goto LSwitch; #endif case ' ': fRedraw = fTrue; break; case 'p': not(fPause); break; case 'r': neg(dir); break; case 'x': not(gs.fInverse); InitColorsX(); fRedraw = fTrue; break; case 'm': if (!gi.fMono) { not(gs.fColor); #ifdef MSG _getvideoconfig((struct videoconfig far *) &gi.cfg); #endif InitColorsX(); fRedraw = fTrue; } break; case 'B': #ifdef X11 XSetWindowBackgroundPixmap(gi.disp, gi.root, gi.pmap); XClearWindow(gi.disp, gi.root); #else gs.xWin = xPcScreen; gs.yWin = yPcScreen; SquareX(&gs.xWin, &gs.yWin, fFalse); fResize = fTrue; #endif break; case 't': not(gs.fText); fRedraw = fTrue; break; case 'i': not(gs.fAlt); fRedraw = fTrue; break; case 'b': not(gs.fBorder); fRedraw = fTrue; break; case 'l': not(gs.fLabel); fRedraw = fTrue; break; case 'j': not(gs.fJetTrail); break; case '<': if (gs.nScale > 100) { gs.nScale -= 100; fResize = fTrue; } break; case '>': if (gs.nScale < 400) { gs.nScale += 100; fResize = fTrue; } break; case '[': if (gi.nMode == gGlobe && gs.rTilt > -rDegQuad) { gs.rTilt = gs.rTilt > -rDegQuad ? gs.rTilt-11.25 : -rDegQuad; fRedraw = fTrue; } break; case ']': if (gi.nMode == gGlobe && gs.rTilt < rDegQuad) { gs.rTilt = gs.rTilt < rDegQuad ? gs.rTilt+11.25 : rDegQuad; fRedraw = fTrue; } break; case 'Q': SquareX(&gs.xWin, &gs.yWin, fTrue); fResize = fTrue; break; case 'R': for (i = oChi; i <= oVes; i++) not(ignore[i]); for (i = oLil; i <= oEP; i++) not(ignore[i]); fCast = fTrue; break; case 'C': not(us.fCusp); for (i = cuspLo; i <= cuspHi; i++) ignore[i] = !us.fCusp || !ignore[i]; fCast = fTrue; break; case 'u': not(us.fUranian); for (i = uranLo; i <= uranHi; i++) ignore[i] = !us.fUranian || !ignore[i]; fCast = fTrue; break; case 'U': us.nStar = !us.nStar; for (i = starLo; i <= starHi; i++) ignore[i] = !us.nStar || !ignore[i]; fCast = fTrue; break; case 'c': if (!us.nRel) { us.nRel = rcDual; ciTwin = ciMain; } else us.nRel = 0; fCast = fTrue; break; case 's': not(us.fSiderial); fCast = fTrue; break; case 'h': us.objCenter = us.objCenter ? 0 : 1; fCast = fTrue; break; case 'f': not(us.fFlip); fCast = fTrue; break; case 'g': not(us.fDecan); fCast = fTrue; break; case '+': Animate(gs.nAnim, abs(dir)); fCast = fTrue; break; case '-': Animate(gs.nAnim, -abs(dir)); fCast = fTrue; break; case 'o': ciSave = ciMain; break; case 'O': ciMain = ciSave; fCast = fTrue; break; #ifdef TIME case 'n': FInputData(szNowCore); ciMain = ciCore; fCast = fTrue; break; #endif case 'N': /* The continuous update animation. */ gs.nAnim = gs.nAnim ? 0 : -10; break; /* These are the nine different "add time to chart" animations. */ case '!': gs.nAnim = -1; break; case '@': gs.nAnim = -2; break; case '#': gs.nAnim = -3; break; case '$': gs.nAnim = -4; break; case '%': gs.nAnim = -5; break; case '^': gs.nAnim = -6; break; case '&': gs.nAnim = -7; break; case '*': gs.nAnim = -8; break; case '(': gs.nAnim = -9; break; /* Should we go switch to a new chart type? */ case 'V': gi.nMode = gWheel; fRedraw = fTrue; break; case 'A': gi.nMode = gGrid; fRedraw = fTrue; break; case 'Z': gi.nMode = gHorizon; fRedraw = fTrue; break; case 'S': gi.nMode = gOrbit; fRedraw = fTrue; break; case 'J': gi.nMode = gDisposit; fRedraw = fTrue; break; case 'L': gi.nMode = gAstroGraph; fRedraw = fTrue; break; case 'K': gi.nMode = gCalendar; fRedraw = fTrue; break; case 'E': gi.nMode = gEphemeris; fRedraw = fTrue; break; case 'W': gi.nMode = gWorldMap; fRedraw = fTrue; break; case 'G': gi.nMode = gGlobe; fRedraw = fTrue; break; case 'P': gi.nMode = gPolar; fRedraw = fTrue; break; #ifdef BIORHYTHM case 'Y': /* Should we switch to biorhythm chart? */ if (!us.nRel) ciTwin = ciMain; us.nRel = rcBiorhythm; gi.nMode = gBiorhythm; fCast = fTrue; break; #endif #ifdef CONSTEL case 'F': if (!fMap && gi.nMode != gGlobe && gi.nMode != gPolar) gi.nMode = gWorldMap; not(gs.fConstel); fRedraw = fTrue; break; #endif case '0': not(us.fPrimeVert); not(us.fCalendarYear); not(us.nEphemYears); not(gs.fMollewide); gi.nMode = (gi.nMode == gWheel ? gHouse : (gi.nMode == gHouse ? gWheel : gi.nMode)); fRedraw = fTrue; break; case 'v': case 'H': case '?': #ifdef MSG _setvideomode(_DEFAULTMODE); if (key != 'v') _settextrows(50); #endif #ifdef BGI restorecrtmode(); #ifdef ATARI /* Ajout Abel PHILIPPE */ Cur_on(); #else if (key != 'v') textmode(C4350); #endif /* Ajout Abel PHILIPPE */ #endif length = us.nScrollRow; us.nScrollRow = 0; if (key == 'v') ChartListing(); else DisplayKeysX(); us.nScrollRow = length; #ifdef PCG while (!kbhit()) ; key = getch(); if (key == 'q' || key == chEscape || key == chBreak) { fBreak = fTrue; break; } BeginX(); fResize = fTrue; #endif break; case chReturn: CommandLineX(); fResize = fCast = fTrue; break; #ifdef PCG case chTab: if (gi.nRes == gs.nResHi) gi.nRes = gs.nResLo; else gi.nRes = gs.nResHi; BeginX(); gs.xWin = xPcScreen; gs.yWin = yPcScreen; SquareX(&gs.xWin, &gs.yWin, fFalse); fResize = fTrue; break; #endif case chDelete: #ifdef PCG #ifdef MOUSE MouseShow(fFalse); #endif #endif /* PCG */ fT = gs.fJetTrail; gs.fJetTrail = fFalse; DrawClearScreen(); gs.fJetTrail = fT; break; #ifdef MOUSE case 'z'-'`': coldrw = kBlack; break; case 'e'-'`': coldrw = kMaroon; break; case 'f'-'`': coldrw = kDkGreen; break; case 'o'-'`': coldrw = kOrange; break; case 'n'-'`': coldrw = kDkBlue; break; case 'u'-'`': coldrw = kPurple; break; case 'k'-'`': coldrw = kDkCyan; break; case 'l'-'`': coldrw = kLtGray; break; case 'd'-'`': coldrw = kDkGray; break; case 'r'-'`': coldrw = kRed; break; case 'g'-'`': coldrw = kGreen; break; case 'y'-'`': coldrw = kYellow; break; case 'b'-'`': coldrw = kBlue; break; case 'v'-'`': coldrw = kMagenta; break; case 'j'-'`': coldrw = kCyan; break; case 'a'-'`': coldrw = kWhite; break; #ifdef PCG case 't'-'`': MouseShow(fFalse); if (buttonx >= 0) #ifdef MSG _rectangle(_GBORDER, buttonx, buttony, mousex, mousey); #else DrawEdge(Min(buttonx, mousex) - gi.xOffset, Min(buttony, mousey) - gi.yOffset, Max(mousex, buttonx) - gi.xOffset, Max(mousey, buttony) - gi.yOffset); #endif MouseShow(fTrue); break; case 'x'-'`': MouseShow(fFalse); if (buttonx >= 0) #ifdef MSG _ellipse(_GBORDER, buttonx, buttony, mousex, mousey); #else DrawEllipse(Min(buttonx, mousex) - gi.xOffset, Min(buttony, mousey) - gi.yOffset, Max(mousex, buttonx) - gi.xOffset, Max(mousey, buttony) - gi.yOffset); #endif MouseShow(fTrue); break; #endif /* PCG */ #endif /* MOUSE */ case 'q': case chEscape: case chBreak: fBreak = fTrue; break; default: if (key > '0' && key <= '9') { #ifdef PCG if (gs.nAnim && !fPause) #endif /* Process numbers 1..9 signifying animation rate. */ dir = (dir > 0 ? 1 : -1)*(key-'0'); #ifdef PCG else { /* If we aren't in animation mode, then 1..9 refers to the */ /* clipping "quadrant" to use if chart size > screen size. */ xcorner = key-'0'; fResize = fTrue; } #endif break; } else if (FBetween(key, 201, 248)) { is.fSzInteract = fTrue; if (szMacro[key-201]) { FProcessCommandLine(szMacro[key-201]); fResize = fCast = fTrue; } is.fSzInteract = fFalse; break; } putchar(chBell); /* 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 EndX() { #ifdef X11 XFreeGC(gi.disp, gi.gc); XFreeGC(gi.disp, gi.pmgc); XFreePixmap(gi.disp, gi.pmap); XDestroyWindow(gi.disp, gi.wind); XCloseDisplay(gi.disp); #endif #ifdef MSG _setvideomode(_DEFAULTMODE); #endif #ifdef BGI restorecrtmode(); #ifdef ATARI /* Ajout Abel PHILIPPE */ Cur_on(); #endif #endif } #endif /* ISG */ /* ****************************************************************************** ** Main Graphics Processing. ****************************************************************************** */ /* Process one 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 NProcessSwitchesX(argc, argv, pos, fOr, fAnd, fNot) int argc, pos; bool fOr, fAnd, fNot; char **argv; { int darg = 0, i, j; real rT; char ch1; ch1 = argv[0][pos+1]; switch (argv[0][pos]) { case chNull: break; case 'b': if (is.fSzInteract) { ErrorArgv("Xb"); return tcError; } ch1 = ChCap(ch1); if (FValidBmpmode(ch1)) gs.chBmpMode = ch1; SwitchF2(gs.fBitmap); gs.fPS = gs.fMeta = fFalse; break; #ifdef PS case 'p': if (is.fSzInteract) { ErrorArgv("Xp"); return tcError; } gs.fPS = fTrue + (ch1 != '0'); gs.fBitmap = gs.fMeta = fFalse; break; #endif #ifdef META case 'M': if (is.fSzInteract) { ErrorArgv("XM"); return tcError; } if (ch1 == '0') SwitchF(gs.fFont); SwitchF2(gs.fMeta); gs.fBitmap = gs.fPS = fFalse; break; #endif case 'o': if (is.fSzInteract) { ErrorArgv("Xo"); return tcError; } if (argc <= 1) { ErrorArgc("Xo"); return tcError; } if (!gs.fBitmap && !gs.fPS && !gs.fMeta) gs.fBitmap = fTrue; gi.szFileOut = SzPersist(argv[1]); darg++; break; #ifdef X11 case 'B': if (is.fSzInteract) { ErrorArgv("XB"); return tcError; } SwitchF(gs.fRoot); break; #endif case 'm': SwitchF(gs.fColor); break; case 'r': SwitchF(gs.fInverse); break; case 'w': if (argc <= 1) { ErrorArgc("Xw"); return tcError; } i = atoi(argv[1]); if (argc > 2 && ((j = atoi(argv[2])) || argv[2][0] == '0')) { argc--; argv++; darg++; } else j = i; if (!FValidGraphx(i)) { ErrorValN("Xw", i); return tcError; } if (!FValidGraphy(j)) { ErrorValN("Xw", j); return tcError; } gs.xWin = i; gs.yWin = j; darg++; break; case 's': if (argc <= 1) { ErrorArgc("Xs"); return tcError; } i = atoi(argv[1]); if (i < 100) i *= 100; if (!FValidScale(i)) { ErrorValN("Xs", i); return tcError; } gs.nScale = i; darg++; break; case 'i': SwitchF(gs.fAlt); break; case 't': SwitchF(gs.fText); break; case 'u': SwitchF(gs.fBorder); break; case 'l': SwitchF(gs.fLabel); break; case 'j': SwitchF(gs.fJetTrail); break; case '1': if (argc <= 1) { ErrorArgc("X1"); return tcError; } i = atoi(argv[1]); if (!FItem(i)) { ErrorValN("X1", i); return tcError; } gs.nLeft = i; darg++; break; case '2': if (argc <= 1) { ErrorArgc("X2"); return tcError; } i = atoi(argv[1]); if (!FItem(i)) { ErrorValN("X2", i); return tcError; } gs.nLeft = -i; darg++; break; case 'd': if (is.fSzInteract) { ErrorArgv("Xd"); return tcError; } if (argc <= 1) { ErrorArgc("Xd"); return tcError; } gs.szDisplay = SzPersist(argv[1]); darg++; break; case 'W': if (argc > 1 && ((i = atoi(argv[1])) || argv[1][0] == '0')) { darg++; if (!FValidRotation(i)) { ErrorValN("XW", i); return tcError; } gs.nRot = i; } gi.nMode = gWorldMap; if (ch1 == '0') gs.fMollewide = fTrue; is.fHaveInfo = fTrue; break; case 'G': if (argc > 1 && ((i = atoi(argv[1])) || argv[1][0] == '0')) { darg++; if (!FValidRotation(i)) { ErrorValN("XG", i); return tcError; } gs.nRot = i; if (argc > 2 && ((rT = atof(argv[2])) || argv[2][0] == '0')) { darg++; if (!FValidTilt(rT)) { ErrorValR("XG", rT); return tcError; } gs.rTilt = rT; } } gi.nMode = gGlobe; is.fHaveInfo = fTrue; break; case 'P': if (argc > 1 && ((i = atoi(argv[1])) || argv[1][0] == '0')) { darg++; if (!FValidRotation(i)) { ErrorValN("XP", i); return tcError; } } else i = 0; gs.nRot = i; gi.nMode = gPolar; if (ch1 == '0') gs.fPrintMap = fTrue; is.fHaveInfo = fTrue; break; #ifdef CONSTEL case 'F': if (!fMap && gi.nMode != gGlobe && gi.nMode != gPolar) gi.nMode = gWorldMap; not(gs.fConstel); is.fHaveInfo = fTrue; break; #endif #ifdef ISG case 'n': if (argc > 1 && (i = atoi(argv[1]))) darg++; else i = 10; if (i < 1 || i > 10) { ErrorValN("Xn", i); return tcError; } gs.nAnim = i; break; #endif default: ErrorSwitch(argv[0]); return tcError; } /* 'darg' contains the value to be added to argc when we return. */ return darg; } /* Process one command line switch passed to the program dealing with more */ /* obscure graphics options. This is structured very much like the function */ /* NProcessSwitchesX(), except here we know each switch begins with 'YX'. */ int NProcessSwitchesRareX(argc, argv, pos) int argc, pos; char **argv; { int darg = 0, i, j; char ch1; ch1 = argv[0][pos+1]; switch (argv[0][pos]) { case chNull: if (argc <= 2) { ErrorArgc("YX"); return tcError; } #ifdef PCG i = atoi(argv[1]); if (!FValidResmode(i)) { ErrorValN("YX", i); return tcError; } gs.nResHi = i; i = atoi(argv[2]); if (!FValidResmode(i)) { ErrorValN("YX", i); return tcError; } gs.nResLo = i; gs.fBitmap = gs.fPS = gs.fMeta = fFalse; #endif darg += 2; break; case 'G': if (argc <= 1) { ErrorArgc("YXG"); return tcError; } i = atoi(argv[1]); if (!FValidGlyphs(i)) { ErrorValN("YXg", i); return tcError; } gs.nGlyphs = i; j = i/1000; if (FBetween(j, 1, 2)) szDrawSign[sCap] = szDrawSign[cSign+j]; j = (i/100)%10; if (FBetween(j, 1, 2)) szDrawObject[oUra] = szDrawObject[oNorm+j]; j = (i/10)%10; if (FBetween(j, 1, 2)) szDrawObject[oPlu] = szDrawObject[oNorm+2+j]; j = i%10; if (FBetween(j, 1, 3)) szDrawObject[oLil] = szDrawObject[oNorm+4+j]; darg++; break; case 'g': if (argc <= 1) { ErrorArgc("YXg"); return tcError; } i = atoi(argv[1]); if (!FValidGrid(i)) { ErrorValN("YXg", i); return tcError; } gs.nGridCell = i; darg++; break; case 'f': if (argc <= 1) { ErrorArgc("YXf"); return tcError; } gs.fFont = atoi(argv[1]); darg++; break; #ifdef PS case 'p': if (ch1 == '0') { if (argc <= 2) { ErrorArgc("YXp0"); return tcError; } gs.xInch = atof(argv[1]); gs.yInch = atof(argv[2]); darg += 2; break; } if (argc <= 1) { ErrorArgc("YXp"); return tcError; } gs.nOrient = atoi(argv[1]); darg++; break; #endif default: ErrorSwitch(argv[0]); return tcError; } /* 'darg' contains the value to be added to argc when we return. */ return darg; } /* 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 fTrue if successfull, fFalse if some non-fatal error occurred. */ bool FActionX() { int i; /* Set up variables in preparation for graphics. Set the glyphs for */ /* certain objects to point to their current setting, and if doing */ /* constellations, give a couple stars more correct astronomical names. */ #ifdef CONSTEL if (gs.fConstel) { szObjName[starLo-1+10] = "Alnilam"; /* Normally "Orion" */ szObjName[starLo-1+47] = "M31"; /* Normally "Andromeda" */ } #endif i = gs.nGlyphs/1000; szDrawSign[sCap] = szDrawSign[cSign+(i == 2 ? 2 : 1)]; i = (gs.nGlyphs/100)%10; szDrawObject[oUra] = szDrawObject[oNorm+(i == 2 ? 2 : 1)]; i = (gs.nGlyphs/10)%10; szDrawObject[oPlu] = szDrawObject[oNorm+2+(i == 2 ? 2 : 1)]; i = gs.nGlyphs%10; szDrawObject[oLil] = szDrawObject[oNorm+4+(FBetween(i, 2, 3) ? i : fSouthNode ? 3 : 1)]; /* if (fSouthNode) szObjectFont[oSou] = '>';*/ gi.fFile = (gs.fBitmap || gs.fPS || gs.fMeta); #ifdef PS gi.fEps = gs.fPS > fTrue; #endif /* 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 (gi.nMode == gWheel) { if (us.fWheel) gi.nMode = gHouse; else if (us.fGrid || us.fMidpoint) { gi.nMode = gGrid; if (us.nRel <= rcDual && us.fMidpoint && !us.fAspList) us.fGridConfig = fTrue; gs.xWin = gs.yWin = (gs.nGridCell + (us.nRel <= rcDual))*CELLSIZE*gi.nScale + 1; } else if (us.fHorizon) gi.nMode = gHorizon; else if (us.fOrbit) gi.nMode = gOrbit; else if (us.fInfluence) gi.nMode = gDisposit; else if (us.fAstroGraph) gi.nMode = gAstroGraph; else if (us.fCalendar) gi.nMode = gCalendar; else if (us.fEphemeris) gi.nMode = gEphemeris; else if (us.nRel == rcBiorhythm) gi.nMode = gBiorhythm; } if (fMap) { gs.xWin = nDegMax*gi.nScale; gs.yWin = nDegHalf*gi.nScale; } gi.nScaleT = gs.fPS ? PSMUL : (gs.fMeta ? METAMUL : 1); if (gi.fFile) { if (gs.xWin == 0) gs.xWin = DEFAULTX; if (gs.yWin == 0) gs.yWin = DEFAULTY; if (fSidebar) gs.xWin += SIDESIZE; if (gs.xWin > BITMAPX) gs.xWin = BITMAPX; if (gs.yWin > BITMAPY) gs.yWin = BITMAPY; BeginFileX(); if (gs.fBitmap) { gi.cbBmpRow = (gs.xWin + 1) >> 1; gi.yBand = gs.yWin; if (!FEnsureGrid()) return fFalse; while ((gi.bm = PAllocate((long)gi.cbBmpRow * gi.yBand, fTrue, NULL)) == NULL) { PrintWarning("The bitmap must be generated in multiple stages."); gi.yBand = (gi.yBand + 1) / 2; if (gi.yBand < 1 || gs.chBmpMode != 'B') return fFalse; } if (gi.yBand == gs.yWin) gi.yBand = 0; else { gi.yOffset = gs.yWin - gs.yWin % gi.yBand; if (gi.yOffset == gs.yWin) gi.yOffset -= gi.yBand; } } #ifdef PS else if (gs.fPS) PsBegin(); #endif #ifdef META else { if (!FEnsureGrid()) return fFalse; for (gi.cbMeta = MAXMETA; gi.cbMeta > 0 && (gi.bm = PAllocate(gi.cbMeta, fTrue, NULL)) == NULL; gi.cbMeta -= MAXMETA/8) PrintWarning("Attempting to get maximum memory for metafile."); if (gi.cbMeta == 0) return fFalse; gs.xWin *= METAMUL; /* Increase chart sizes and scales behind the */ gs.yWin *= METAMUL; /* scenes to make graphics look smoother. */ gs.nScale *= METAMUL; } #endif InitColorsX(); } #ifdef ISG else { #ifdef PCG BeginX(); if (gs.xWin == 0 || gs.yWin == 0) { if (gs.xWin == 0) gs.xWin = xPcScreen; if (gs.yWin == 0) gs.yWin = yPcScreen; SquareX(&gs.xWin, &gs.yWin, fFalse); } else if (fSidebar) gs.xWin += SIDESIZE; #else if (gs.xWin == 0 || gs.yWin == 0) { if (gs.xWin == 0) gs.xWin = DEFAULTX; if (gs.yWin == 0) gs.yWin = DEFAULTY; SquareX(&gs.xWin, &gs.yWin, fFalse); } else if (fSidebar) gs.xWin += SIDESIZE; BeginX(); #endif } #endif /* ISG */ if (gi.fFile || gs.fRoot) /* Go draw the graphic chart. */ DrawChartX(); if (gi.fFile) { /* Write bitmap to file if in that mode. */ EndFileX(); while (gi.yBand) { gi.yOffset -= gi.yBand; DrawChartX(); EndFileX(); } if (!gs.fPS) DeallocateHuge(gi.bm); } #ifdef ISG else { #ifdef X11 if (gs.fRoot) { /* Process -XB. */ XSetWindowBackgroundPixmap(gi.disp, gi.root, gi.pmap); XClearWindow(gi.disp, gi.root); /* If -Xn in effect with -XB, then enter infinite loop where we */ /* calculate and animate chart, displaying on the root window. */ while (gs.nAnim) { Animate(gs.nAnim, 1); if (!gs.fJetTrail) XFillRectangle(gi.disp, gi.pmap, gi.pmgc, 0, 0, gs.xWin, gs.yWin); DrawChartX(); XSetWindowBackgroundPixmap(gi.disp, gi.root, gi.pmap); XClearWindow(gi.disp, gi.root); } } else #endif InteractX(); /* Window's up; process commands given to window now. */ EndX(); } #endif /* ISG */ return fTrue; } #endif /* GRAPH */ /* xscreen.c */