home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume37 / astrolog / part05 < prev    next >
Encoding:
Text File  |  1993-05-18  |  52.0 KB  |  1,738 lines

  1. Newsgroups: comp.sources.misc
  2. From: astrolog@u.washington.edu (Astrolog)
  3. Subject: v37i074:  astrolog - Generation of astrology charts v3.05, Part05/12
  4. Message-ID: <1993May19.061622.11488@sparky.imd.sterling.com>
  5. X-Md4-Signature: 70fb06081e0808e7eff1a569a6cc4232
  6. Date: Wed, 19 May 1993 06:16:22 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: astrolog@u.washington.edu (Astrolog)
  10. Posting-number: Volume 37, Issue 74
  11. Archive-name: astrolog/part05
  12. Environment: UNIX, DOS, VMS
  13. Supersedes: astrolog: Volume 30, Issue 62-69
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 5 (of 12)."
  22. # Contents:  xgeneral.c xdriver.c
  23. # Wrapped by pul@hardy on Sun May 16 22:23:16 1993
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f 'xgeneral.c' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'xgeneral.c'\"
  27. else
  28. echo shar: Extracting \"'xgeneral.c'\" \(16971 characters\)
  29. sed "s/^X//" >'xgeneral.c' <<'END_OF_FILE'
  30. X/*
  31. X** Astrolog (Version 3.05) File: xgeneral.c
  32. X** Initially programmed 10/23-29/1991.
  33. X**
  34. X** IMPORTANT: The planetary calculation routines used in this program
  35. X** have been Copyrighted and the core of this program is basically a
  36. X** conversion to C of the routines created by James Neely as listed in
  37. X** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
  38. X** available from Matrix Software. The copyright gives us permission to
  39. X** use the routines for our own purposes but not to sell them or profit
  40. X** from them in any way.
  41. X**
  42. X** IMPORTANT: the graphics database and chart display routines used in
  43. X** this program are Copyright (C) 1991-1993 by Walter D. Pullen. Permission
  44. X** is granted to freely use and distribute these routines provided one
  45. X** doesn't sell, restrict, or profit from them in any way. Modification
  46. X** is allowed provided these notices remain with any altered or edited
  47. X** versions of the program.
  48. X*/
  49. X
  50. X#include "astrolog.h"
  51. X
  52. X#ifdef GRAPH
  53. X
  54. X/* Macros to access a point in a bitmap. */
  55. X
  56. X#ifdef NOPC
  57. X#define AIND(B, X, Y) ((B)->m[(X) >> 1][(Y)])
  58. X#else
  59. X#define AIND(B, X, Y) ((B)[(long)(Y)*(long)(BITMAPX >> 1) + ((X) >> 1)])
  60. X#endif
  61. X#define PGET(B, X, Y) (AIND(B, X, Y) >> (((X)&1^1) << 2) & 15)
  62. X#define PSET(B, X, Y, O) AIND(B, X, Y) = AIND(B, X, Y) & \
  63. X  15 << (((X)&1) << 2) | (O) << (((X)&1^1) << 2)
  64. X
  65. X
  66. X/*
  67. X*******************************************************************************
  68. X** Core graphic procedures
  69. X*******************************************************************************
  70. X*/
  71. X
  72. X/* Set a single point on the screen. This is the most basic graphic function */
  73. X/* and is called by all the more complex routines. Based on what mode we are */
  74. X/* in, we either set a cell in the bitmap array or a pixel on the window.    */
  75. X
  76. Xvoid DrawPoint(x, y, o)
  77. Xint x, y;
  78. Xbit o;
  79. X{
  80. X  if (xbitmap) {
  81. X
  82. X    /* Force the coordinates to be within the bounds of the bitmap. */
  83. X
  84. X    if (x < 0)
  85. X      x = 0;
  86. X    else if (x >= chartx)
  87. X      x = chartx-1;
  88. X    if (y < 0)
  89. X      y = 0;
  90. X    else if (y >= charty)
  91. X      y = charty-1;
  92. X    PSET(bm, x, y, o);
  93. X  }
  94. X#ifdef X11
  95. X  else
  96. X    XDrawPoint(disp, pixmap, gc, x, y);
  97. X#endif
  98. X#ifdef MSC
  99. X  else
  100. X    _setpixel(x, y);
  101. X#endif
  102. X}
  103. X
  104. X
  105. X/* Draw dot a little larger than just a single pixel at specified location. */
  106. X
  107. Xvoid DrawSpot(x, y, o)
  108. Xint x, y;
  109. Xbit o;
  110. X{
  111. X  DrawPoint(x, y, o);
  112. X  DrawPoint(x, y-1, o);
  113. X  DrawPoint(x-1, y, o);
  114. X  DrawPoint(x+1, y, o);
  115. X  DrawPoint(x, y+1, o);
  116. X}
  117. X
  118. X
  119. X/* Draw a filled in block, defined by the corners of its rectangle. */
  120. X
  121. Xvoid DrawBlock(x1, y1, x2, y2, o)
  122. Xint x1, y1, x2, y2;
  123. Xbit o;
  124. X{
  125. X  int x, y;
  126. X  SORT(y1, y2); SORT(x1, x2);
  127. X  if (xbitmap)
  128. X    for (y = y1; y <= y2; y++)         /* For bitmap, it's faster to  */
  129. X      for (x = x1; x <= x2; x++)       /* just fill in the array.     */
  130. X        PSET(bm, x, y, o);
  131. X#ifdef X11
  132. X  else
  133. X    for (y = y1; y <= y2; y++)         /* For X window, let's go call */
  134. X      DrawLine(x1, y, x2, y, o, 0);    /* XDrawLine for fewer events. */
  135. X#endif
  136. X#ifdef MSC
  137. X  else {
  138. X    Xcolor(o);
  139. X    _rectangle(_GFILLINTERIOR, x1, y1, x2, y2);
  140. X  }
  141. X#endif
  142. X}
  143. X
  144. X
  145. X/* Draw a rectangle on the screen with specified thickness. This is just   */
  146. X/* like DrawBlock() except that we are only drawing the edges of the area. */
  147. X
  148. Xvoid DrawBox(x1, y1, x2, y2, xsiz, ysiz, o)
  149. Xint x1, y1, x2, y2, xsiz, ysiz;
  150. Xbit o;
  151. X{
  152. X  DrawBlock(x1, y1, x2, y1 + ysiz - 1, o);
  153. X  DrawBlock(x1, y1 + ysiz, x1 + xsiz - 1, y2 - ysiz, o);
  154. X  DrawBlock(x2 - xsiz + 1, y1 + ysiz, x2, y2 - ysiz, o);
  155. X  DrawBlock(x1, y2 - ysiz + 1, x2, y2, o);
  156. X}
  157. X
  158. X
  159. X/* Draw a line on the screen, specified by its endpoints. In addition, we */
  160. X/* have specified a skip factor, which allows us to draw dashed lines.    */
  161. X
  162. Xvoid DrawLine(x1, y1, x2, y2, o, skip)
  163. Xint x1, y1, x2, y2, skip;
  164. Xbit o;
  165. X{
  166. X  int x = x1, y = y1, xadd, yadd, yinc, xabs, yabs, i, j = 0;
  167. X
  168. X  if (skip < 0)
  169. X    skip = 0;
  170. X#ifdef X11
  171. X  if (!xbitmap) {
  172. X    Xcolor(o);
  173. X
  174. X    /* For non-dashed X window lines, let's just have the Xlib do it for us. */
  175. X
  176. X    if (!skip) {
  177. X      XDrawLine(disp, pixmap, gc, x1, y1, x2, y2);
  178. X      return;
  179. X    }
  180. X  }
  181. X#endif
  182. X#ifdef MSC
  183. X  if (!xbitmap) {
  184. X    Xcolor(o);
  185. X
  186. X    /* For non-dashed lines, let's have the graphics library do it for us. */
  187. X
  188. X    if (!skip) {
  189. X      _moveto(x1, y1);
  190. X      _lineto(x2, y2);
  191. X      return;
  192. X    }
  193. X  }
  194. X#endif
  195. X  xadd = x2 - x1 >= 0 ? 1 : 3;
  196. X  yadd = y2 - y1 >= 0 ? 2 : 4;
  197. X  xabs = abs(x2 - x1);
  198. X  yabs = abs(y2 - y1);
  199. X
  200. X  /* Technically what we're doing here is drawing a line which is more    */
  201. X  /* horizontal then vertical. We always increment x by 1, and increment  */
  202. X  /* y whenever a fractional variable passes a certain amount. For lines  */
  203. X  /* that are more vertical than horizontal, we just swap x and y coords. */
  204. X
  205. X  if (xabs < yabs) {
  206. X    SWAP(xadd, yadd);
  207. X    SWAP(xabs, yabs);
  208. X  }
  209. X  yinc = (xabs >> 1) - ((xabs & 1 ^ 1) && xadd > 2);
  210. X  for (i = xabs+1; i; i--) {
  211. X    if (j < 1)
  212. X      DrawPoint(x, y, o);
  213. X    j = j < skip ? j+1 : 0;
  214. X    switch (xadd) {
  215. X    case 1: x++; break;
  216. X    case 2: y++; break;
  217. X    case 3: x--; break;
  218. X    case 4: y--; break;
  219. X    }
  220. X    yinc += yabs;
  221. X    if (yinc - xabs >= 0) {
  222. X      yinc -= xabs;
  223. X      switch (yadd) {
  224. X      case 1: x++; break;
  225. X      case 2: y++; break;
  226. X      case 3: x--; break;
  227. X      case 4: y--; break;
  228. X      }
  229. X    }
  230. X  }
  231. X}
  232. X
  233. X
  234. X/* Draw a normal line on the screen; however, if the x coordinates are close */
  235. X/* to opposite sides of the window, then we assume that the line runs off    */
  236. X/* one side and reappears on the other, so draw the appropriate two lines    */
  237. X/* instead. This is used by the Ley line and astro-graph routines, which     */
  238. X/* draw lines running around the world and hence off the edges of the maps.  */
  239. X
  240. Xvoid DrawWrap(xold, yold, xnew, ynew, o)
  241. Xint xold, yold, xnew, ynew;
  242. Xbit o;
  243. X{
  244. X  int xmid, ymid, i;
  245. X
  246. X  if (xold < 0) {
  247. X    DrawPoint(xnew, ynew, o);
  248. X    return;
  249. X  }
  250. X  xmid = 180*SCALE;
  251. X
  252. X  /* If endpoints aren't near opposite edges, just draw the line and return. */
  253. X
  254. X  if (dabs((real)(xnew-xold)) < (real) xmid) {
  255. X    DrawLine(xold, yold, xnew, ynew, o, 0);
  256. X    return;
  257. X  }
  258. X  i = xold < xmid ? xold+chartx-xnew-2 : xnew+chartx-xold-2;
  259. X
  260. X  /* Determine vertical coordinate where our line runs off edges of screen. */
  261. X
  262. X  ymid = yold+(int)((real)(ynew-yold)*
  263. X    (xold < xmid ? (real)(xold-1) : (real)(chartx-xold-2))/(real)i);
  264. X  DrawLine(xold, yold, xold < xmid ? 1 : chartx-2, ymid, o, 0);
  265. X  DrawLine(xnew < xmid ? 1 : chartx-2, ymid, xnew, ynew, o, 0);
  266. X}
  267. X
  268. X
  269. X/* This routine, and its companion below, clips a line defined by its */
  270. X/* endpoints to either above the y=0 line, or below some line y=c. By */
  271. X/* passing in parameters in different orders, we can clip to vertical */
  272. X/* lines, too. These are used by the DrawClip() routine below.        */
  273. X
  274. Xvoid ClipNegative(x1, y1, x2, y2)
  275. Xint *x1, *y1, *x2, *y2;
  276. X{
  277. X  *x1 -= (int)((long)*y1*(*x2-*x1)/(*y2-*y1));
  278. X  *y1 = 0;
  279. X}
  280. X
  281. Xvoid ClipGreater(x1, y1, x2, y2, s)
  282. Xint *x1, *y1, *x2, *y2, s;
  283. X{
  284. X  *x1 += (int)((long)(s-*y1)*(*x2-*x1)/(*y2-*y1));
  285. X  *y1 = s;
  286. X}
  287. X
  288. X
  289. X/* Draw a line on the screen. This is just like DrawLine() routine earlier; */
  290. X/* however, first clip the endpoints to the window viewport before drawing. */
  291. X
  292. Xvoid DrawClip(x1, y1, x2, y2, o, skip)
  293. Xint x1, y1, x2, y2, skip;
  294. Xbit o;
  295. X{
  296. X  if (x1 < 0)
  297. X    ClipNegative(&y1, &x1, &y2, &x2);    /* Check left side of window. */
  298. X  if (x2 < 0)
  299. X    ClipNegative(&y2, &x2, &y1, &x1);
  300. X  if (y1 < 0)
  301. X    ClipNegative(&x1, &y1, &x2, &y2);    /* Check top side of window.  */
  302. X  if (y2 < 0)
  303. X    ClipNegative(&x2, &y2, &x1, &y1);
  304. X  if (x1 > chartx)
  305. X    ClipGreater(&y1, &x1, &y2, &x2, chartx);    /* Check right of window.  */
  306. X  if (x2 > chartx)
  307. X    ClipGreater(&y2, &x2, &y1, &x1, chartx);
  308. X  if (y1 > charty)
  309. X    ClipGreater(&x1, &y1, &x2, &y2, charty);    /* Check bottom of window. */
  310. X  if (y2 > charty)
  311. X    ClipGreater(&x2, &y2, &x1, &y1, charty);
  312. X  DrawLine(x1, y1, x2, y2, o, skip);            /* Go draw the line.       */
  313. X}
  314. X
  315. X
  316. X/* Print a string of text on the graphic window at specified location. To do */
  317. X/* this we use Astrolog's own "font" and draw each letter separately.        */
  318. X
  319. Xvoid DrawText(string, x, y, o)
  320. Xchar *string;
  321. Xint x, y;
  322. Xcolor o;
  323. X{
  324. X  int s = scale;
  325. X
  326. X  scale = 100;
  327. X  x++;
  328. X  y -= FONTY-3;
  329. X  while (*string) {
  330. X    DrawBlock(x, y, x+FONTX-1, y+FONTY-2, off);
  331. X    DrawTurtle(asciidraw[*string-' '], x, y, o);
  332. X    x += FONTX;
  333. X    string++;
  334. X  }
  335. X  scale = s;
  336. X}
  337. X
  338. X
  339. X/* Draw the glyph of an object at particular coordinates on the window. */
  340. X
  341. Xvoid DrawObject(i, x, y)
  342. Xint i, x, y;
  343. X{
  344. X  char glyph[4];
  345. X
  346. X  if (!label)    /* If we are inhibiting labels, then do nothing. */
  347. X    return;
  348. X
  349. X  /* For other planet centered charts, we have to remember that that     */
  350. X  /* particular planet's index now represents the Earth. If we are given */
  351. X  /* that index to draw, then change it so we draw the Earth instead.    */
  352. X
  353. X  if (modex != 's' &&
  354. X      ((i == centerplanet && i > 2) || (centerplanet == 0 && i == 1)))
  355. X    i = 0;
  356. X  if (i <= OBJECTS)
  357. X    DrawTurtle(objectdraw[i], x, y, objectcolor[i]);
  358. X
  359. X  /* Normally we can just go draw the glyph; however, uranians and stars   */
  360. X  /* don't have glyphs, so for these draw their three letter abbreviation. */
  361. X
  362. X  else {
  363. X    sprintf(glyph, "%c%c%c", OBJNAM(i));
  364. X    DrawText(glyph, x-StringLen(glyph)*FONTX/2, y+FONTY/2, objectcolor[i]);
  365. X  }
  366. X}
  367. X
  368. X
  369. X/* Convert a string segment to a positive number, updating the string to  */
  370. X/* point beyond the number chars. Return 1 if the string doesn't point to */
  371. X/* a numeric value. This is used by the DrawTurtle() routine to extract   */
  372. X/* motion vector quantities from draw strings, e.g. the "12" in "U12".    */
  373. X
  374. Xint IntInString(str)
  375. Xchar **str;
  376. X{
  377. X  int num = 0, i = 0;
  378. X
  379. X  while (TRUE) {
  380. X    if (**str < '0' || **str > '9')
  381. X      return num > 0 ? num : (i < 1 ? 1 : 0);
  382. X    num = num*10+(**str)-'0';
  383. X    (*str)++;
  384. X    i++;
  385. X  }
  386. X}
  387. X
  388. X
  389. X/* This routine is used to draw complicated objects composed of lots of line */
  390. X/* segments on the screen, such as all the glyphs and coastline pieces. It   */
  391. X/* is passed in a string of commands defining what to draw in relative       */
  392. X/* coordinates. This is a copy of the format of the BASIC draw command found */
  393. X/* in PC's. For example, "U5R10D5L10" means go up 5 dots, right 10, down 5,  */
  394. X/* and left 10 - draw a box twice as wide as it is high.                     */
  395. X
  396. Xvoid DrawTurtle(lin, x0, y0, o)
  397. Xchar *lin;
  398. Xint x0, y0;
  399. Xbit o;
  400. X{
  401. X  int i, j, x, y, deltax, deltay, blank, noupdate;
  402. X  char cmd;
  403. X
  404. X  turtlex = x0; turtley = y0;
  405. X#ifdef WIN
  406. X  if (!xbitmap)
  407. X    Xcolor(o);
  408. X#endif
  409. X  while (cmd = CAP(*lin)) {
  410. X    lin++;
  411. X
  412. X    /* 'B' prefixing a command means just move the cursor, and don't draw. */
  413. X
  414. X    if (blank = cmd == 'B') {
  415. X      cmd = CAP(*lin);
  416. X      lin++;
  417. X    }
  418. X
  419. X    /* 'N' prefixing a command means don't update cursor when done drawing. */
  420. X
  421. X    if (noupdate = cmd == 'N') {
  422. X      cmd = CAP(*lin);
  423. X      lin++;
  424. X    }
  425. X
  426. X    /* Here we process the eight directional commands. */
  427. X
  428. X    switch (cmd) {
  429. X    case 'U': deltax =  0; deltay = -1; break;    /* Up    */
  430. X    case 'D': deltax =  0; deltay =  1; break;    /* Down  */
  431. X    case 'L': deltax = -1; deltay =  0; break;    /* Left  */
  432. X    case 'R': deltax =  1; deltay =  0; break;    /* Right */
  433. X    case 'E': deltax =  1; deltay = -1; break;    /* Northeast */
  434. X    case 'F': deltax =  1; deltay =  1; break;    /* Southeast */
  435. X    case 'G': deltax = -1; deltay =  1; break;    /* Southwest */
  436. X    case 'H': deltax = -1; deltay = -1; break;    /* Northwest */
  437. X    default:                                      /* Shouldn't happen. */
  438. X      fprintf(stderr, "%s: Bad turtle subcommand: '%c'\n", appname, cmd);
  439. X      Terminate(1);
  440. X    }
  441. X    x = turtlex;
  442. X    y = turtley;
  443. X    j = IntInString(&lin)*SCALE;    /* Figure out how far to draw. */
  444. X    if (blank) {
  445. X      turtlex += deltax*j;
  446. X      turtley += deltay*j;
  447. X    } else {
  448. X      DrawPoint(turtlex, turtley, o);
  449. X      for (i = 0; i < j; i++) {
  450. X        turtlex += deltax;
  451. X        turtley += deltay;
  452. X        DrawPoint(turtlex, turtley, o);
  453. X      }
  454. X      if (noupdate) {
  455. X        turtlex = x;
  456. X        turtley = y;
  457. X      }
  458. X    }
  459. X  }
  460. X}
  461. X
  462. X
  463. X/*
  464. X*******************************************************************************
  465. X** Bitmap file routines
  466. X*******************************************************************************
  467. X*/
  468. X
  469. X#define INTTOHEX(I) (char) ((I) < 10 ? '0' + (I) : 'a' + (I) - 10)
  470. X
  471. X/* Write the bitmap array to a previously opened file in a format that   */
  472. X/* can be read in by the Unix X commands bitmap and xsetroot. The 'mode' */
  473. X/* parameter defines how much white space is put in the file.            */
  474. X
  475. Xvoid WriteXBitmap(data, name, mode)
  476. XFILE *data;
  477. Xchar *name, mode;
  478. X{
  479. X  int x, y, i, value, temp = 0;
  480. X
  481. X  fprintf(data, "#define %s_width %d\n" , name, chartx);
  482. X  fprintf(data, "#define %s_height %d\n", name, charty);
  483. X  fprintf(data, "static %s %s_bits[] = {",
  484. X    mode != 'V' ? "char" : "short", name);
  485. X  for (y = 0; y < charty; y++) {
  486. X    x = 0;
  487. X    do {
  488. X
  489. X      /* Process each row, eight columns at a time. */
  490. X
  491. X      if (y + x > 0)
  492. X        fprintf(data, ",");
  493. X      if (temp == 0)
  494. X        fprintf(data, "\n%s",
  495. X          mode == 'N' ? "  " : (mode == 'C' ? " " : ""));
  496. X      value = 0;
  497. X      for (i = (mode != 'V' ? 7 : 15); i >= 0; i--)
  498. X        value = (value << 1) +
  499. X          (!(PGET(bm, x+i, y)^(xreverse*15))^xreverse && (x + i < chartx));
  500. X      if (mode == 'N')
  501. X        putc(' ', data);
  502. X      fprintf(data, "0x");
  503. X      if (mode == 'V')
  504. X        fprintf(data, "%c%c",
  505. X          INTTOHEX(value >> 12), INTTOHEX((value >> 8) & 15));
  506. X      fprintf(data, "%c%c",
  507. X        INTTOHEX((value >> 4) & 15), INTTOHEX(value & 15));
  508. X      temp++;
  509. X
  510. X      /* Is it time to skip to the next line while writing the file yet? */
  511. X
  512. X      if ((mode == 'N' && temp >= 12) ||
  513. X          (mode == 'C' && temp >= 15) ||
  514. X          (mode == 'V' && temp >= 11))
  515. X        temp = 0;
  516. X      x += (mode != 'V' ? 8 : 16);
  517. X    } while (x < chartx);
  518. X  }
  519. X  fprintf(data, "};\n");
  520. X}
  521. X
  522. X
  523. X/* Write the bitmap array to a previously opened file in a simple boolean    */
  524. X/* Ascii rectangle, one char per pixel, where '#' represents an off bit and  */
  525. X/* '-' an on bit. The output format is identical to the format generated by  */
  526. X/* the Unix bmtoa command, and it can be converted into a bitmap with atobm. */
  527. X
  528. Xvoid WriteAscii(data)
  529. XFILE *data;
  530. X{
  531. X  int x, y, i;
  532. X
  533. X  for (y = 0; y < charty; y++) {
  534. X    for (x = 0; x < chartx; x++) {
  535. X      i = PGET(bm, x, y);
  536. X      if (xcolor)
  537. X        putc(INTTOHEX(i), data);
  538. X      else
  539. X        putc(i ? '-' : '#', data);
  540. X    }
  541. X    putc('\n', data);
  542. X  }
  543. X}
  544. X
  545. X
  546. X#define putbyte(A) putc((byte) (A), data)
  547. X#define putword(A) putbyte(LOBYTE(A)); putbyte(HIBYTE(A))
  548. X#define putlong(A) putword(LOWORD(A)); putword(HIWORD(A))
  549. X
  550. X/* Write the bitmap array to a previously opened file in the bitmap format  */
  551. X/* used in Microsoft Windows for its .bmp extension files. This is a pretty */
  552. X/* efficient format, only requiring one bit per pixel and a small header.   */
  553. X
  554. Xvoid WriteBmp(data)
  555. XFILE *data;
  556. X{
  557. X  int x, y;
  558. X  unsigned long value;
  559. X
  560. X  /* BitmapFileHeader */
  561. X  putbyte('B'); putbyte('M');
  562. X  putlong(14+40 + (xcolor ? 64 : 8) +
  563. X    (long)4*charty*((chartx-1 >> (xcolor ? 3 : 5))+1));
  564. X  putword(0); putword(0);
  565. X  putlong(14+40 + (xcolor ? 64 : 8));
  566. X  /* BitmapInfo / BitmapInfoHeader */
  567. X  putlong(40);
  568. X  putlong(chartx); putlong(charty);
  569. X  putword(1); putword(xcolor ? 4 : 1);
  570. X  putlong(0 /*BI_RGB*/); putlong(0);
  571. X  putlong(chartx*10); putlong(charty*10);
  572. X  putlong(0); putlong(0);
  573. X  /* RgbQuad */
  574. X  if (xcolor)
  575. X    for (x = 0; x < 16; x++) {
  576. X      putbyte(RGBB(rgbbmp[x])); putbyte(RGBG(rgbbmp[x]));
  577. X      putbyte(RGBR(rgbbmp[x])); putbyte(0);
  578. X    }
  579. X  else {
  580. X    putlong(0);
  581. X    putbyte(255); putbyte(255); putbyte(255); putbyte(0);
  582. X  }
  583. X  /* Data */
  584. X  for (y = charty-1; y >= 0; y--) {
  585. X    value = 0;
  586. X    for (x = 0; x < chartx; x++) {
  587. X      if ((x & (xcolor ? 7 : 31)) == 0 && x > 0) {
  588. X        putlong(value);
  589. X        value = 0;
  590. X      }
  591. X      if (xcolor)
  592. X        value |= (dword)PGET(bm, x, y) << ((x & 7 ^ 1) << 2);
  593. X      else
  594. X        if (PGET(bm, x, y))
  595. X          value |= (long)1 << (x & 31 ^ 7);
  596. X    }
  597. X    putlong(value);
  598. X  }
  599. X}
  600. X
  601. X
  602. X/* Output the bitmap in memory to a file. This basically consists of just    */
  603. X/* calling the routine to actually write a bitmap to a file, although we     */
  604. X/* need to prompt the user for a filename if it wasn't specified beforehand. */
  605. X
  606. Xvoid WriteFile()
  607. X{
  608. X  FILE *data;
  609. X  int tty;
  610. X
  611. X  tty = (outputfile[0] == 't' && outputfile[1] == 't' &&
  612. X    outputfile[2] == 'y' && outputfile[3] == 0);
  613. X  while (TRUE) {
  614. X    if (tty) {
  615. X      printf("Enter name of file to write X bitmap to > ");
  616. X      if (gets(outputfile) == (char *) NULL) {
  617. X        printf("\n%s terminated.\n", appname);
  618. X        Terminate(2);
  619. X      }
  620. X    }
  621. X    data = fopen(outputfile, "wb");
  622. X    if (data != NULL)
  623. X      break;
  624. X    else {
  625. X      printf("Bad output file.\n");
  626. X      tty = TRUE;
  627. X    }
  628. X  }
  629. X  if (bitmapmode == 'B')
  630. X    WriteBmp(data);
  631. X  else if (bitmapmode == 'A')
  632. X    WriteAscii(data);
  633. X  else
  634. X    WriteXBitmap(data, outputfile, bitmapmode);
  635. X  fclose(data);
  636. X}
  637. X#endif
  638. X
  639. X/* xgeneral.c */
  640. END_OF_FILE
  641. if test 16971 -ne `wc -c <'xgeneral.c'`; then
  642.     echo shar: \"'xgeneral.c'\" unpacked with wrong size!
  643. fi
  644. # end of 'xgeneral.c'
  645. fi
  646. if test -f 'xdriver.c' -a "${1}" != "-c" ; then 
  647.   echo shar: Will not clobber existing file \"'xdriver.c'\"
  648. else
  649. echo shar: Extracting \"'xdriver.c'\" \(32400 characters\)
  650. sed "s/^X//" >'xdriver.c' <<'END_OF_FILE'
  651. X/*
  652. X** Astrolog (Version 3.05) File: xdriver.c
  653. X** Initially programmed 10/23-29/1991.
  654. X**
  655. X** IMPORTANT: The planetary calculation routines used in this program
  656. X** have been Copyrighted and the core of this program is basically a
  657. X** conversion to C of the routines created by James Neely as listed in
  658. X** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
  659. X** available from Matrix Software. The copyright gives us permission to
  660. X** use the routines for our own purposes but not to sell them or profit
  661. X** from them in any way.
  662. X**
  663. X** IMPORTANT: the graphics database and chart display routines used in
  664. X** this program are Copyright (C) 1991-1993 by Walter D. Pullen. Permission
  665. X** is granted to freely use and distribute these routines provided one
  666. X** doesn't sell, restrict, or profit from them in any way. Modification
  667. X** is allowed provided these notices remain with any altered or edited
  668. X** versions of the program.
  669. X*/
  670. X
  671. X#include "astrolog.h"
  672. X
  673. X#ifdef GRAPH
  674. X
  675. X#ifdef X11
  676. X/* Size of the Astrolog X11 icon. These values are defined in xdata.c too. */
  677. X
  678. X#define icon_width 63
  679. X#define icon_height 32
  680. X#endif
  681. X
  682. X/* Macros to allocate a bitmap from free memory. */
  683. X
  684. X#ifdef NOPC
  685. X#define BITMAPSIZE sizeof(bitmapstruct)
  686. X#else
  687. X#define BITMAPSIZE ((long)(BITMAPX >> 1)*(BITMAPY))
  688. X#endif
  689. X
  690. X/* Global variables. */
  691. X
  692. X#ifdef MSC
  693. X#define HIRESMODE _MAXRESMODE
  694. X#define LORESMODE _ERESCOLOR
  695. Xstruct videoconfig config;
  696. Xint xscreen = HIRESMODE;
  697. X#endif
  698. X
  699. X
  700. X/*
  701. X*******************************************************************************
  702. X** X routines
  703. X*******************************************************************************
  704. X*/
  705. X
  706. X#ifdef X11
  707. X/* Allocate a color from the present colormap. Given a string like "red" or */
  708. X/* "blue" allocate this color and return a value specifying it.             */
  709. X
  710. Xcolor XMakeColor(name)
  711. Xchar *name;
  712. X{
  713. X  XColor col;
  714. X  XParseColor(disp, cmap, name, &col);
  715. X  XAllocColor(disp, cmap, &col);
  716. X  return col.pixel;
  717. X}
  718. X#endif
  719. X
  720. X
  721. X/* Set up all the colors used by the program, i.e. the foreground and   */
  722. X/* background colors, and all the colors in the object arrays, based on */
  723. X/* whether or not we are in monochrome and/or reverse video mode.       */
  724. X
  725. XXColorInit()
  726. X{
  727. X  int i;
  728. X
  729. X#ifdef X11
  730. X  cmap = XDefaultColormap(disp, screen);
  731. X  for (i = 0; i < 16; i++)
  732. X    rgbind[i] = XMakeColor(rgbname[i]);
  733. X#endif
  734. X  on  = mainansi[!xreverse];
  735. X  off = mainansi[xreverse];
  736. X  hilite = xcolor ? mainansi[2] : on;
  737. X  gray   = xcolor ? mainansi[3] : on;
  738. X  for (i = 0; i <= 6; i++)
  739. X    maincolor[i]    = xcolor ? mainansi[i]    : on;
  740. X  for (i = 0; i <= 7; i++)
  741. X    rainbowcolor[i] = xcolor ? rainbowansi[i] : on;
  742. X  for (i = 0; i < 4; i++)
  743. X    elemcolor[i]    = xcolor ? elemansi[i]    : on;
  744. X  for (i = 0; i <= ASPECTS; i++)
  745. X    aspectcolor[i]  = xcolor ? aspectansi[i]  : on;
  746. X  for (i = 0; i <= TOTAL; i++)
  747. X    objectcolor[i]  = xcolor ? objectansi[i]  : on;
  748. X#ifdef WIN
  749. X  if (!xbitmap) {
  750. X#ifdef X11
  751. X    XSetBackground(disp, gc,   rgbind[off]);  /* Initialize X window colors. */
  752. X    XSetForeground(disp, pmgc, rgbind[off]);
  753. X#endif
  754. X    Xcolor(on);
  755. X  }
  756. X#endif
  757. X}
  758. X
  759. X
  760. X#ifdef WIN
  761. X/* This routine opens up and initializes a window and prepares it to be */
  762. X/* drawn upon, and gets various information about the display, too.     */
  763. X
  764. Xvoid XBegin()
  765. X{
  766. X#ifdef X11
  767. X  disp = XOpenDisplay(dispname);
  768. X  if (!disp) {
  769. X    fprintf(stderr, "%s: Can't open display.\n", appname);
  770. X    Terminate(1);
  771. X  }
  772. X  screen = DefaultScreen(disp);
  773. X  bg = BlackPixel(disp, screen);
  774. X  fg = WhitePixel(disp, screen);
  775. X  hint.x = hint.width = chartx; hint.y = hint.height = charty;
  776. X  hint.min_width = BITMAPX1; hint.min_height = BITMAPY1;
  777. X  hint.max_width = BITMAPX;  hint.max_height = BITMAPY;
  778. X  hint.flags = PPosition | PSize | PMaxSize | PMinSize;
  779. X  /*wmhint = XGetWMHints(disp, window);
  780. X  wmhint->input = True;
  781. X  XSetWMHints(disp, window, wmhint);*/
  782. X  depth = DefaultDepth(disp, screen);
  783. X  if (depth < 5) {
  784. X    xmono = TRUE;      /* Is this a monochrome monitor? */
  785. X    xcolor = FALSE;
  786. X  }
  787. X  root = RootWindow(disp, screen);
  788. X  if (xroot)
  789. X    window = root;     /* If -XB in effect, we'll use the root window. */
  790. X  else
  791. X    window = XCreateSimpleWindow(disp, DefaultRootWindow(disp),
  792. X      hint.x, hint.y, hint.width, hint.height, 5, fg, bg);
  793. X  pixmap = XCreatePixmap(disp, window, chartx, charty, depth);
  794. X  icon = XCreateBitmapFromData(disp, DefaultRootWindow(disp),
  795. X    icon_bits, icon_width, icon_height);
  796. X  if (!xroot)
  797. X    XSetStandardProperties(disp, window, appname, appname, icon, xkey, 0,
  798. X      &hint);
  799. X
  800. X  /* We have two graphics workareas. One is what the user currently sees in */
  801. X  /* the window, and the other is what we are currently drawing on. When    */
  802. X  /* done, we can quickly copy this to the viewport for a smooth look.      */
  803. X
  804. X  gc = XCreateGC(disp, window, 0, 0);
  805. X  XSetGraphicsExposures(disp, gc, 0);
  806. X  pmgc = XCreateGC(disp, window, 0, 0);
  807. X  XColorInit();                            /* Go set up colors. */
  808. X  if (!xroot)
  809. X    XSelectInput(disp, window, KeyPressMask | StructureNotifyMask |
  810. X      ExposureMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask);
  811. X  XMapRaised(disp, window);
  812. X  XSync(disp, 0);
  813. X  XFillRectangle(disp, pixmap, pmgc, 0, 0, chartx, charty);
  814. X#else
  815. X  _setvideomode(xscreen);
  816. X  if (_grstatus()) {
  817. X    fprintf(stderr, "%s: Can't enter graphics mode.\n", appname);
  818. X    Terminate(1);
  819. X  }
  820. X  _getvideoconfig((struct videoconfig far *) &config);
  821. X  if (config.numcolors < 16) {
  822. X    xmono = TRUE;
  823. X    xcolor = FALSE;
  824. X  }
  825. X  _remapallpalette((long far *) rgb);
  826. X  _setactivepage(0);
  827. X  _clearscreen(_GCLEARSCREEN);
  828. X  _setvisualpage(0);
  829. X  XColorInit();
  830. X#endif
  831. X}
  832. X
  833. X
  834. X/* Add a certain amount of time to the current hour/day/month/year quantity */
  835. X/* defining the present chart. This is used by the chart animation feature. */
  836. X/* We can add or subtract anywhere from 1 to 9 seconds, minutes, hours,     */
  837. X/* days, months, years, decades, centuries, or millenia in any one call.    */
  838. X/* This is mainly just addition to the appropriate quantity, but we have    */
  839. X/* to check for overflows, e.g. Dec 30 + 3 days = Jan 2 of Current year + 1 */
  840. X
  841. Xvoid AddTime(mode, num)
  842. Xint mode, num;
  843. X{
  844. X  real toadd, h, m, j;
  845. X
  846. X  toadd = (real)num;
  847. X  h = floor(F);
  848. X  m = FRACT(F)*100.0;
  849. X  if (mode == 1)
  850. X    m += 1.0/60.0*(real)toadd;    /* Add seconds. */
  851. X  else if (mode == 2)
  852. X    m += 1.0*(real)toadd;         /* add minutes. */
  853. X
  854. X  /* Add hours, either naturally or if minute value overflowed. */
  855. X
  856. X  if (m < 0.0 || m >= 60.0 || mode == 3) {
  857. X    if (m >= 60.0) {
  858. X      m -= 60.0; toadd = Sgn(toadd);
  859. X    } else if (m < 0.0) {
  860. X      m += 60.0; toadd = Sgn(toadd);
  861. X    }
  862. X    h += 1.0*(real)toadd;
  863. X  }
  864. X
  865. X  /* Add days, either naturally or if hour value overflowed. */
  866. X
  867. X  if (h >= 24.0 || h < 0.0 || mode == 4) {
  868. X    if (h >= 24.0) {
  869. X      h -= 24.0; toadd = Sgn(toadd);
  870. X    } else if (h < 0.0) {
  871. X      h += 24.0; toadd = Sgn(toadd);
  872. X    }
  873. X    D += 1.0*(real)toadd;
  874. X  }
  875. X
  876. X  /* Add months, either naturally or if day value overflowed. */
  877. X
  878. X  if (D > (j = (real)DayInMonth((int) M, (int) Y)) ||
  879. X      D < 1.0 || mode == 5) {
  880. X    if (D > j) {
  881. X      D -= j; toadd = Sgn(toadd);
  882. X    } else if (D < 1.0) {
  883. X      D += (real)DayInMonth(Mod12(((int) M) - 1), (int) Y); toadd = Sgn(toadd);
  884. X    }
  885. X    M += 1.0*(real)toadd;
  886. X  }
  887. X
  888. X  /* Add years, either naturally or if month value overflowed. */
  889. X
  890. X  if (M > 12.0 || M < 1.0 || mode == 6) {
  891. X    if (M > 12.0) {
  892. X      M -= 12.0; toadd = Sgn(toadd);
  893. X    } else if (M < 1.0) {
  894. X      M += 12.0; toadd = Sgn(toadd);
  895. X    }
  896. X    Y += 1.0*(real)toadd;
  897. X  }
  898. X  if (mode == 7)
  899. X    Y += 10.0*(real)toadd;      /* Add decades.   */
  900. X  else if (mode == 8)
  901. X    Y += 100.0*(real)toadd;     /* Add centuries. */
  902. X  else if (mode == 9)
  903. X    Y += 1000.0*(real)toadd;    /* Add millenia.  */
  904. X  F = h+m/100.0;                /* Recalibrate hour time. */
  905. X}
  906. X
  907. X
  908. X/* Print a list of every key that one can press in an X window to do a */
  909. X/* certain function, and a description of what it does. This list gets */
  910. X/* displayed whenever one presses the 'H' or '?' key in the window.    */
  911. X
  912. Xvoid DisplayKeys()
  913. X{
  914. X  sprintf(string, "\n%s window keypress options (version %s):", appname,
  915. X    VERSION);
  916. X  Prints(string);
  917. X  Prints(" Press 'H' or '?' to display this list of key options.");
  918. X  Prints(" Press 'p' to toggle pause status on or off.");
  919. X  Prints(" Press 'x' to toggle fg/bg colors on screen.");
  920. X  Prints(" Press 'm' to toggle color/monochrome display on screen.");
  921. X  Prints(" Press 'T' to toggle header info on current chart on screen.");
  922. X  Prints(" Press 'i' to toggle status of the minor chart modification.");
  923. X  Prints(" Press 'l' to toggle labeling of object points in chart.");
  924. X  Prints(" Press 'v' to display current chart positions on text screen.");
  925. X  Prints(" Press 'R' to toggle restriction status of minor objects.");
  926. X  Prints(" Press 'C' to toggle restriction status of minor house cusps.");
  927. X  Prints(" Press 'u' to toggle restriction status of uranian planets.");
  928. X  Prints(" Press 'U' to toggle restriction status of fixed stars.");
  929. X  Prints(" Press 's', 'h', 'f', 'F' to toggle status of sidereal zodiac,");
  930. X  Prints("        heliocentric charts, domal charts, and decan charts.");
  931. X  Prints(" Press 'O' and 'o' to recall/store a previous chart from memory.");
  932. X#ifdef X11
  933. X  Prints(" Press 'B' to dump current window contents to root background.");
  934. X#else
  935. X  Prints(" Press 'B' to resize chart display to full size of screen.");
  936. X#endif
  937. X  Prints(" Press 'Q' to resize chart display to a square.");
  938. X  Prints(" Press '<' and '>' to decrease/increase the scale size of the");
  939. X  Prints("       glyphs and the size of world map.");
  940. X  Prints(" Press '[' and ']' to decrease/increase tilt in globe display.");
  941. X  Prints(" Press 'N' to toggle animation status on or off. Charts will");
  942. X  Prints("       be updated to current status and globe will rotate.");
  943. X  Prints(" Press '!'-'(' to begin updating current chart by adding times.");
  944. X  Prints("       !: seconds, @: minutes, #: hours, $: days, %: months,");
  945. X  Prints("       ^: years, &: years*10, *: years*100, (: years*1000.");
  946. X  Prints(" Press 'r' to reverse direction of time-lapse or animation.");
  947. X  Prints(" Press '1'-'9' to set rate of animation to 'n' degrees, etc.");
  948. X#ifdef MSC
  949. X  Prints(" Press '1'-'9' to determine section of chart to show if clipped.");
  950. X#endif
  951. X  Prints(" Press 'V','L','A','Z','S','W','G','P' to switch to normal (_v),");
  952. X  Prints("       astro-graph (_L), grid (_g), local (_Z), space (_S),");
  953. X  Prints("       world (_XW), globe (_XG), and polar (_XP) modes.");
  954. X  Prints(" Press '0' to toggle between _Z & _Z0, and _XW & _XW0 modes.");
  955. X#ifdef MSC
  956. X  Prints(" Press 'tab' to toggle between graphics resolutions.");
  957. X#endif
  958. X  Prints(" Press 'q' to terminate the window and program.");
  959. X#ifdef X11
  960. X  Prints("\n Left   mouse button: Draw lines on chart in window.");
  961. X  Prints(" Middle mouse button: Print coordinates of pointer on world map.");
  962. X  Prints(" Right  mouse button: Terminate the window and program.");
  963. X#endif
  964. X}
  965. X
  966. X
  967. X/* These macros are used by the 'o' and 'O' keys to save chart information. */
  968. X
  969. X#define STOREX  MonX = Mon; DayX = Day; YeaX = Yea; TimX = Tim; ZonX = Zon; \
  970. X  LonX = Lon; LatX = Lat
  971. X#define RECALLX Mon = MonX; Day = DayX; Yea = YeaX; Tim = TimX; Zon = ZonX; \
  972. X  Lon = LonX; Lat = LatX
  973. X
  974. X/* This routine gets called after an X window is brought up and displayed   */
  975. X/* on the screen. It loops, processing key presses, mouse clicks, etc, that */
  976. X/* the window receives, until the user specifies they want to exit program. */
  977. X
  978. Xvoid XSpin()
  979. X{
  980. X#ifdef X11
  981. X  int xupdate = FALSE, xevent = TRUE;
  982. X#else
  983. X  int xupdate = TRUE, xevent = FALSE;
  984. X#endif
  985. X  int xbreak = FALSE, xpause = FALSE, xnew = FALSE, xcorner = 7,
  986. X    buttonx = 0, buttony = 0, dir = 1, length, i;
  987. X  real MonX, DayX, YeaX, TimX, ZonX, LonX, LatX, lon, lat;
  988. X
  989. X  STOREX;
  990. X  while (!xbreak) {
  991. X
  992. X#ifndef MSC
  993. X    /* First, make sure the window isn't too large or too small. */
  994. X
  995. X    if (chartx < BITMAPX1) {
  996. X      chartx = BITMAPX1;
  997. X      xupdate = TRUE;
  998. X    } else if (chartx > BITMAPX) {
  999. X      chartx = BITMAPX;
  1000. X      xupdate = TRUE;
  1001. X    }
  1002. X    if (charty < BITMAPY1) {
  1003. X      charty = BITMAPY1;
  1004. X      xupdate = TRUE;
  1005. X    } else if (charty > BITMAPY) {
  1006. X      charty = BITMAPY;
  1007. X      xupdate = TRUE;
  1008. X    }
  1009. X#endif
  1010. X
  1011. X    /* Some chart windows, like the world maps and aspect grids, should */
  1012. X    /* always be a certian size, so correct if a resize was attempted.  */
  1013. X
  1014. X    if (modex == 'l' || modex == 'w') {
  1015. X      length = 360*SCALE+2;
  1016. X      if (chartx != length) {
  1017. X        chartx = length;
  1018. X        xupdate = TRUE;
  1019. X      }
  1020. X      length = (90*2+1)*SCALE+2;
  1021. X      if (charty != length) {
  1022. X        charty = length;
  1023. X        xupdate = TRUE;
  1024. X      }
  1025. X    } else if (modex == 'a') {
  1026. X      if (chartx !=
  1027. X        (length = (OBJECTS+(relation==1))*CELLSIZE*SCALE+1)) {
  1028. X        chartx = length;
  1029. X        xupdate = TRUE;
  1030. X      } if (charty != length) {
  1031. X        charty = length;
  1032. X        xupdate = TRUE;
  1033. X      }
  1034. X    }
  1035. X
  1036. X#ifdef MSC
  1037. X    /* If in animation mode, ensure we are in the flicker free resolution. */
  1038. X
  1039. X    if (xnow < 0 && xscreen == HIRESMODE) {
  1040. X      xnow = -xnow;
  1041. X      xscreen = LORESMODE;
  1042. X      XBegin();
  1043. X      chartx = config.numxpixels;
  1044. X      charty = config.numypixels;
  1045. X      if (chartx > charty)
  1046. X        chartx = charty;
  1047. X      chartx = (long)chartx * 480 / 350;
  1048. X      xupdate = TRUE;
  1049. X    }
  1050. X#else
  1051. X    if (xnow < 0)
  1052. X      xnow = -xnow;
  1053. X#endif
  1054. X
  1055. X    /* Physically resize window if we've changed the size parameters. */
  1056. X
  1057. X    if (xupdate) {
  1058. X      xupdate = FALSE;
  1059. X#ifdef X11
  1060. X      XResizeWindow(disp, window, chartx, charty);
  1061. X      XFreePixmap(disp, pixmap);
  1062. X      pixmap = XCreatePixmap(disp, window, chartx, charty, depth);
  1063. X#else
  1064. X      if (config.numxpixels > chartx)
  1065. X        buttonx = (config.numxpixels - chartx) >> 1;
  1066. X      else {
  1067. X        if (xcorner % 3 == 1)
  1068. X          buttonx = 0;
  1069. X        else if (xcorner % 3 == 0)
  1070. X          buttonx = -chartx + config.numxpixels;
  1071. X        else
  1072. X          buttonx = -(chartx - config.numxpixels) / 2;
  1073. X      }
  1074. X      if (config.numypixels > charty)
  1075. X        buttony = (config.numypixels - charty) >> 1;
  1076. X      else {
  1077. X        if (xcorner > 6)
  1078. X          buttony = 0;
  1079. X        else if (xcorner < 4)
  1080. X          buttony = -charty + config.numypixels;
  1081. X        else
  1082. X          buttony = -(charty - config.numypixels) / 2;
  1083. X      }
  1084. X      _setviewport(buttonx, buttony, config.numxpixels, config.numypixels);
  1085. X#endif
  1086. X      xevent = TRUE;
  1087. X    }
  1088. X
  1089. X    /* Recast chart if the chart information has changed any. */
  1090. X
  1091. X    if (xnew && (!xnow || xpause)) {
  1092. X      xnew = FALSE;
  1093. X      M = Mon; D = Day; Y = Yea; F = Tim; X = Zon; L5 = Lon; LA = Lat;
  1094. X      CastChart(TRUE);
  1095. X      xevent = TRUE;
  1096. X    }
  1097. X    if (xnow && !xpause)
  1098. X      xevent = TRUE;
  1099. X
  1100. X    /* Update the window if anything has changed since last time around. */
  1101. X
  1102. X    if (xevent) {
  1103. X      xevent = FALSE;
  1104. X
  1105. X      /* If we're in animation mode, change the chart info appropriately. */
  1106. X
  1107. X      if (xnow) {
  1108. X        if (modex == 'w' || modex == 'g' || modex == 'p') {
  1109. X          degree += dir;
  1110. X          if (degree >= 360)      /* For animating globe display, add */
  1111. X            degree -= 360;        /* in appropriate degree value.     */
  1112. X          else if (degree < 0)
  1113. X            degree += 360;
  1114. X        } else {
  1115. X          if (xnow == 10)
  1116. X#ifdef TIME
  1117. X            /* For the continuous chart update to present moment */
  1118. X            /* animation mode, go get whatever time it is now.   */
  1119. X            InputData("now")
  1120. X#endif
  1121. X              ;
  1122. X          else {  /* Otherwise add on appropriate time vector to chart info. */
  1123. X            M = Mon; D = Day; Y = Yea; F = Tim; X = Zon; L5 = Lon; LA = Lat;
  1124. X            AddTime(xnow, dir);
  1125. X          }
  1126. X          Mon = M; Day = D; Yea = Y; Tim = F; Zon = X; Lon = L5; Lat = LA;
  1127. X          CastChart(TRUE);
  1128. X          if (relation) {
  1129. X            for (i = 1; i <= total; i++)    /* Make sure animations    */
  1130. X              planet2[i] = planet[i];       /* of relationship charts  */
  1131. X            for (i = 1; i <= SIGNS; i++)    /* are reflected properly. */
  1132. X              house2[i] = house[i];
  1133. X          }
  1134. X        }            /* Update window display with new chart. */
  1135. X      }
  1136. X#ifdef X11
  1137. X      Xcolor(on);
  1138. X      XFillRectangle(disp, pixmap, pmgc, 0, 0, chartx, charty);
  1139. X#else
  1140. X      if (config.numvideopages > 1)
  1141. X        _setactivepage(_getactivepage() == 0);
  1142. X      _clearscreen(_GCLEARSCREEN);
  1143. X      DrawBlock(0, 0, chartx-1, charty-1, off);
  1144. X#endif
  1145. X      XChart();
  1146. X#ifdef X11
  1147. X      XSync(disp, 0);
  1148. X      XCopyArea(disp, pixmap, window, gc, 0, 0, chartx, charty, 0, 0);
  1149. X#else
  1150. X      if (config.numvideopages > 1)
  1151. X        _setvisualpage(_getactivepage());
  1152. X#endif
  1153. X    }
  1154. X
  1155. X    /* Now process what's on the event queue, i.e. any keys pressed, etc. */
  1156. X
  1157. X#ifdef X11
  1158. X    if (XEventsQueued(disp, QueuedAfterFlush /*QueuedAfterReading*/ )) {
  1159. X      XNextEvent(disp, &event);
  1160. X
  1161. X      /* Restore what's on window if a part of it gets uncovered. */
  1162. X
  1163. X      if (event.type == Expose && event.xexpose.count == 0) {
  1164. X        XSync(disp, 0);
  1165. X        XCopyArea(disp, pixmap, window, gc, 0, 0, chartx, charty, 0, 0);
  1166. X      }
  1167. X      switch (event.type) {
  1168. X
  1169. X      /* Check for a manual resize of window by user. */
  1170. X
  1171. X      case ConfigureNotify:
  1172. X        chartx = event.xconfigure.width;
  1173. X        charty = event.xconfigure.height;
  1174. X        XFreePixmap(disp, pixmap);
  1175. X        pixmap = XCreatePixmap(disp, window, chartx, charty, depth);
  1176. X        xevent = TRUE;
  1177. X        break;
  1178. X      case MappingNotify:
  1179. X        XRefreshKeyboardMapping(&event);
  1180. X        break;
  1181. X
  1182. X      /* Process any mouse buttons the user pressed. */
  1183. X
  1184. X      case ButtonPress:
  1185. X        buttonx = event.xbutton.x; buttony = event.xbutton.y;
  1186. X        if (event.xbutton.button == Button1) {
  1187. X          Xcolor(hilite);
  1188. X          DrawPoint(buttonx, buttony, hilite);
  1189. X          XSync(disp, 0);
  1190. X          XCopyArea(disp, pixmap, window, gc, 0, 0, chartx, charty, 0, 0);
  1191. X        } else if (event.xbutton.button == Button2 &&
  1192. X          (modex == 'l' || modex == 'w') && degree == 0) {
  1193. X          lon = 180.0-(real)(event.xbutton.x-1)/(real)(chartx-2)*DEGREES;
  1194. X          lat =  90.0-(real)(event.xbutton.y-1)/(real)(charty-2)*181.0;
  1195. X          printf("Mouse is at %s.\n", StringLocation(lon, lat, 60.0));
  1196. X        } else if (event.xbutton.button == Button3)
  1197. X          xbreak = TRUE;
  1198. X        break;
  1199. X
  1200. X      /* Check for user dragging any of the mouse buttons across window. */
  1201. X
  1202. X      case MotionNotify:
  1203. X        Xcolor(hilite);
  1204. X        DrawLine(buttonx, buttony, event.xbutton.x, event.xbutton.y,
  1205. X          hilite, 0);
  1206. X        XSync(disp, 0);
  1207. X        XCopyArea(disp, pixmap, window, gc, 0, 0, chartx, charty, 0, 0);
  1208. X        buttonx = event.xbutton.x; buttony = event.xbutton.y;
  1209. X        break;
  1210. X
  1211. X      /* Process any keys user pressed in window. */
  1212. X
  1213. X      case KeyPress:
  1214. X        length = XLookupString(&event, xkey, 10, &key, 0);
  1215. X        if (length == 1) {
  1216. X          i = xkey[0];
  1217. X#else
  1218. X        if (kbhit()) {
  1219. X          i = getch();
  1220. X#endif
  1221. X          switch (i) {
  1222. X          case 'p':
  1223. X            xpause = !xpause;
  1224. X            break;
  1225. X          case 'r':
  1226. X            dir = -dir;
  1227. X            break;
  1228. X          case 'x':
  1229. X            xreverse = !xreverse;
  1230. X            XColorInit();
  1231. X            xevent = TRUE;
  1232. X            break;
  1233. X          case 'm':
  1234. X            if (!xmono) {
  1235. X              xcolor = !xcolor;
  1236. X#ifdef MSC
  1237. X              _getvideoconfig((struct videoconfig far *) &config);
  1238. X#endif
  1239. X              XColorInit();
  1240. X              xevent = TRUE;
  1241. X            }
  1242. X            break;
  1243. X          case 'B':
  1244. X#ifdef X11
  1245. X            XSetWindowBackgroundPixmap(disp, root, pixmap);
  1246. X            XClearWindow(disp, root);
  1247. X#else
  1248. X            chartx = config.numxpixels;
  1249. X            charty = config.numypixels;
  1250. X            xupdate = TRUE;
  1251. X#endif
  1252. X            break;
  1253. X          case 'T':
  1254. X            xtext = !xtext;
  1255. X            xevent = TRUE;
  1256. X            break;
  1257. X          case 'i':
  1258. X            bonus = !bonus;
  1259. X            xevent = TRUE;
  1260. X            break;
  1261. X          case '<':
  1262. X            if (scale > 100) {
  1263. X              scale -= 100;
  1264. X              xupdate = TRUE;
  1265. X            }
  1266. X            break;
  1267. X          case '>':
  1268. X            if (scale < 300) {
  1269. X              scale += 100;
  1270. X              xupdate = TRUE;
  1271. X            }
  1272. X            break;
  1273. X          case '[':
  1274. X            if (modex == 'g') {
  1275. X              tilt = tilt > -90.0 ? tilt-11.25 : -90.0;
  1276. X              xevent = TRUE;
  1277. X            }
  1278. X            break;
  1279. X          case ']':
  1280. X            if (modex == 'g') {
  1281. X              tilt = tilt < 90.0 ? tilt+11.25 : 90.0;
  1282. X              xevent = TRUE;
  1283. X            }
  1284. X            break;
  1285. X          case 'Q':
  1286. X            if (chartx > charty)
  1287. X              chartx = charty;
  1288. X            else
  1289. X              charty = chartx;
  1290. X#ifdef MSC
  1291. X            if (xscreen == LORESMODE)
  1292. X              chartx = (long)chartx * 480 / 350;
  1293. X#endif
  1294. X            xupdate = TRUE;
  1295. X            break;
  1296. X          case 'R':
  1297. X            for (i = 11; i <= 15; i++)
  1298. X              ignore[i] = !ignore[i];
  1299. X            ignore[17] = !ignore[17]; ignore[20] = !ignore[20];
  1300. X            xevent = TRUE;
  1301. X            break;
  1302. X          case 'C':
  1303. X            operation ^= DASHC;
  1304. X            for (i = C_LO; i <= C_HI; i++)
  1305. X              ignore[i] = !ignore[i];
  1306. X            xnew = TRUE;
  1307. X            break;
  1308. X          case 'u':
  1309. X            operation ^= DASHu;
  1310. X            for (i = U_LO; i <= U_HI; i++)
  1311. X              ignore[i] = !ignore[i];
  1312. X            xnew = TRUE;
  1313. X            break;
  1314. X          case 'U':
  1315. X            universe = !universe;
  1316. X            for (i = S_LO; i <= S_HI; i++)
  1317. X              ignore[i] = !ignore[i];
  1318. X            xnew = TRUE;
  1319. X            break;
  1320. X          case 's':
  1321. X            operation ^= DASHs;
  1322. X            xnew = TRUE;
  1323. X            break;
  1324. X          case 'h':
  1325. X            centerplanet = centerplanet ? 0 : 1;
  1326. X            xnew = TRUE;
  1327. X            break;
  1328. X          case 'f':
  1329. X            operation ^= DASHf;
  1330. X            xnew = TRUE;
  1331. X            break;
  1332. X          case 'F':
  1333. X            operation ^= DASH3;
  1334. X            xnew = TRUE;
  1335. X            break;
  1336. X          case 'o':
  1337. X            STOREX;
  1338. X            break;
  1339. X          case 'O':
  1340. X            RECALLX;
  1341. X            xnew = TRUE;
  1342. X            break;
  1343. X          case 'l':
  1344. X            label = !label;
  1345. X            xevent = TRUE;
  1346. X            break;
  1347. X          case 'N':                      /* The continuous update animation. */
  1348. X            xnow = xnow ? 0 : -10;
  1349. X            break;
  1350. X          case '!': xnow = -1; break;    /* These are the nine different     */
  1351. X          case '@': xnow = -2; break;    /* "add time to chart" animations.  */
  1352. X          case '#': xnow = -3; break;
  1353. X          case '$': xnow = -4; break;
  1354. X          case '%': xnow = -5; break;
  1355. X          case '^': xnow = -6; break;
  1356. X          case '&': xnow = -7; break;
  1357. X          case '*': xnow = -8; break;
  1358. X          case '(': xnow = -9; break;
  1359. X          case 'V': modex = 'c'; xevent = TRUE; break;    /* Should we go    */
  1360. X          case 'L': modex = 'l'; xevent = TRUE; break;    /* switch to a     */
  1361. X          case 'A': modex = 'a'; xevent = TRUE; break;    /* new chart type? */
  1362. X          case 'Z': modex = 'z'; xevent = TRUE; break;
  1363. X          case 'S': modex = 's'; xevent = TRUE; break;
  1364. X          case 'W': modex = 'w'; xevent = TRUE; break;
  1365. X          case 'P': modex = 'p'; xevent = TRUE; break;
  1366. X          case 'G': modex = 'g'; xevent = TRUE; break;
  1367. X          case '0':
  1368. X            exdisplay ^= DASHZ0 | DASHXW0;
  1369. X            xevent = TRUE;
  1370. X            break;
  1371. X          case 'v':
  1372. X#ifdef MSC
  1373. X            _setvideomode(_DEFAULTMODE);
  1374. X#endif
  1375. X            ChartLocation(FALSE);
  1376. X#ifdef MSC
  1377. X            while (!kbhit());
  1378. X            XBegin();
  1379. X            xupdate = TRUE;
  1380. X#endif
  1381. X            break;
  1382. X          case 'H': case '?':
  1383. X#ifdef MSC
  1384. X            _setvideomode(_DEFAULTMODE);
  1385. X            _settextrows(43);
  1386. X#endif
  1387. X            DisplayKeys();
  1388. X#ifdef MSC
  1389. X            while (!kbhit());
  1390. X            XBegin();
  1391. X            xupdate = TRUE;
  1392. X#endif
  1393. X            break;
  1394. X#ifdef MSC
  1395. X          case '\t':
  1396. X            if (xscreen == HIRESMODE)
  1397. X              xscreen = LORESMODE;
  1398. X            else
  1399. X              xscreen = HIRESMODE;
  1400. X            XBegin();
  1401. X            chartx = config.numxpixels;
  1402. X            charty = config.numypixels;
  1403. X            if (chartx > charty)
  1404. X              chartx = charty;
  1405. X            if (xscreen == LORESMODE)
  1406. X              chartx = (long)chartx * 480 / 350;
  1407. X            xupdate = TRUE;
  1408. X            break;
  1409. X#endif
  1410. X          case 'q': case ESCAPE: case '\3':
  1411. X            xbreak = TRUE;
  1412. X            break;
  1413. X          default:
  1414. X            if (i > '0' && i <= '9') {
  1415. X#ifdef MSC
  1416. X              if (xnow)
  1417. X#endif
  1418. X                /* Process numbers 1..9 signifying animation rate. */
  1419. X                dir = (dir > 0 ? 1 : -1)*(i-'0');
  1420. X#ifdef MSC
  1421. X              else {
  1422. X                /* If we aren't in animation mode, then 1..9 refers to the */
  1423. X                /* clipping "quadrant" to use if chart size > screen size. */
  1424. X                xcorner = i-'0';
  1425. X                xupdate = TRUE;
  1426. X              }
  1427. X#endif
  1428. X            }
  1429. X          }  /* switch */
  1430. X        }  /* if */
  1431. X#ifdef X11
  1432. X      default:
  1433. X        ;
  1434. X      }  /* switch */
  1435. X    }  /* if */
  1436. X#endif
  1437. X  }  /* while */
  1438. X}
  1439. X
  1440. X
  1441. X/* This is called right before program termination to get rid of the window. */
  1442. X
  1443. Xvoid XEnd()
  1444. X{
  1445. X#ifdef X11
  1446. X  XFreeGC(disp, gc);
  1447. X  XFreeGC(disp, pmgc);
  1448. X  XFreePixmap(disp, pixmap);
  1449. X  XDestroyWindow(disp, window);
  1450. X  XCloseDisplay(disp);
  1451. X#else
  1452. X  _setvideomode(_DEFAULTMODE);
  1453. X#endif
  1454. X}
  1455. X#endif
  1456. X
  1457. X
  1458. X/*
  1459. X*******************************************************************************
  1460. X** Main processing
  1461. X*******************************************************************************
  1462. X*/
  1463. X
  1464. X
  1465. X/* Print a list of every command switch dealing with the graphics features  */
  1466. X/* that can be passed to the program, and a description of what it does.    */
  1467. X/* This is part of what the -H switch prints, if graphics were compiled in. */
  1468. X
  1469. Xvoid XDisplaySwitches()
  1470. X{
  1471. X  Prints(" _X: Create a graphics chart instead of displaying it as text.");
  1472. X#ifdef WIN
  1473. X  Prints(" _Xb: Create bitmap file instead of putting graphics on screen.");
  1474. X#endif
  1475. X  Prints(" _Xb[n,c,v,a,b]: Set bitmap file output mode to X11 normal,");
  1476. X  Prints("     compacted, very compact, Ascii (bmtoa), or Windows bmp.");
  1477. X  Prints(" _Xo <file>: Write output bitmap to specified file.");
  1478. X#ifdef X11
  1479. X  Prints(" _XB: Display X chart on root instead of in a separate window.");
  1480. X#endif
  1481. X  Prints(" _Xm: Create monochrome graphic instead of one in color.");
  1482. X  Prints(" _Xr: Create chart graphic in reversed colors (white background).");
  1483. X  Prints(" _Xw <hor> [<ver>]: Change the size of the chart graphic.");
  1484. X  Prints(" _Xs <100,200,300>: Change the size of map or characters by n%.");
  1485. X  Prints(" _Xi: Create chart graphic in slightly modified form.");
  1486. X  Prints(" _XT: Inhibit display of chart info at bottom of graphic.");
  1487. X  Prints(" _X1 <object>: Rotate wheel charts so object is at left edge.");
  1488. X  Prints(" _X2 <object>: Rotate wheel charts so object is at top edge.");
  1489. X#ifdef X11
  1490. X  Prints(" _Xd <name>, _di[..] <name>: Open X window on specified display.");
  1491. X#endif
  1492. X  Prints(" _XW: Simply create an image of the world map.");
  1493. X  Prints(" _XW0: Like _XW but do a non-rectangular Mollewide projection.");
  1494. X  Prints(" _XP: Create just the world map, but from a polar projection.");
  1495. X  Prints(" _XG [<degrees>]: Display the image of the world as a globe.");
  1496. X#ifdef WIN
  1497. X  Prints(" _Xn: Start up chart or globe display in animation mode.");
  1498. X  Prints("Also, press 'H' while running for list of key press options.");
  1499. X#endif
  1500. X}
  1501. X
  1502. X
  1503. X/* Process a command line switch passed to the program dealing with the      */
  1504. X/* graphics features. This is just like the processing of each switch in the */
  1505. X/* main program; however, here each switch has been prefixed with an 'X'.    */
  1506. X
  1507. Xint XProcess(argc, argv, pos)
  1508. Xint argc, pos;
  1509. Xchar **argv;
  1510. X{
  1511. X  int i = 0, j;
  1512. X  char c;
  1513. X
  1514. X  switch (argv[0][pos]) {
  1515. X  case 0:
  1516. X    break;
  1517. X  case 'W':
  1518. X    if (argc > 1 && ((degree = atoi(argv[1])) || argv[1][0] == '0')) {
  1519. X      i++;
  1520. X      if (degree < 0 || degree > 359)
  1521. X        BadVal("XW", degree);
  1522. X    } else
  1523. X      degree = 0;
  1524. X    modex = 'w';
  1525. X    if (argv[0][pos+1] == '0')
  1526. X      exdisplay |= DASHXW0;
  1527. X    autom = TRUE;
  1528. X    break;
  1529. X  case 'P':
  1530. X    if (argc > 1 && ((degree = atoi(argv[1])) || argv[1][0] == '0')) {
  1531. X      i++;
  1532. X      if (degree < 0 || degree > 359)
  1533. X        BadVal("XP", degree);
  1534. X    } else
  1535. X      degree = 0;
  1536. X    modex = 'p';
  1537. X    if (argv[0][pos+1] == '0')
  1538. X      exdisplay |= DASHXP0;
  1539. X    autom = TRUE;
  1540. X    break;
  1541. X  case 'G':
  1542. X    if (argc > 1 && ((degree = atoi(argv[1])) || argv[1][0] == '0')) {
  1543. X      i++;
  1544. X      if (degree < 0 || degree > 359)
  1545. X        BadVal("XG", degree);
  1546. X      if (argc > 2 && ((tilt = atof(argv[2])) || argv[2][0] == '0')) {
  1547. X        i++;
  1548. X        if (tilt < -90.0 || tilt > 90.0)
  1549. X          BadVal2("XG", tilt);
  1550. X      }
  1551. X    }
  1552. X    modex = 'g';
  1553. X    autom = TRUE;
  1554. X    break;
  1555. X  case 'b':
  1556. X    c = CAP(argv[0][pos+1]);
  1557. X    if (c == 'N' || c == 'C' || c == 'V' || c == 'A' || c == 'B')
  1558. X      bitmapmode = c;
  1559. X    xbitmap = TRUE;
  1560. X    break;
  1561. X#ifdef X11
  1562. X  case 'B':
  1563. X    xroot = TRUE;
  1564. X    break;
  1565. X#endif
  1566. X  case 'm':
  1567. X    xcolor = FALSE;
  1568. X    break;
  1569. X  case 'r':
  1570. X    xreverse = TRUE;
  1571. X    break;
  1572. X  case 'w':
  1573. X    if (argc <= 1)
  1574. X      TooFew("Xw");
  1575. X    chartx = atoi(argv[1]);
  1576. X    if (argc > 2 && (charty = atoi(argv[2]))) {
  1577. X      argc--; argv++;
  1578. X      i++;
  1579. X    } else
  1580. X      charty = chartx;
  1581. X    if (chartx < BITMAPY1 || chartx > BITMAPX)
  1582. X      BadVal("Xw", chartx);
  1583. X    if (charty < BITMAPY1 || charty > BITMAPY)
  1584. X      BadVal("Xw", charty);
  1585. X    i++;
  1586. X    break;
  1587. X  case 's':
  1588. X    if (argc <= 1)
  1589. X      TooFew("Xs");
  1590. X    scale = atoi(argv[1]);
  1591. X    if (scale >= 1 && scale <= 3)
  1592. X      scale *= 100;
  1593. X    else if (scale < 100 || scale > 300 || scale%100 > 0)
  1594. X      BadVal("Xs", scale);
  1595. X    i++;
  1596. X    break;
  1597. X  case 'i':
  1598. X    bonus = TRUE;
  1599. X    break;
  1600. X  case 'T':
  1601. X    xtext = FALSE;
  1602. X    break;
  1603. X  case '1':
  1604. X    if (argc <= 1)
  1605. X      TooFew("X1");
  1606. X    xeast = atoi(argv[1]);
  1607. X    if (xeast < 1 || xeast > TOTAL)
  1608. X      BadVal("X1", xeast);
  1609. X    i++;
  1610. X    break;
  1611. X  case '2':
  1612. X    if (argc <= 1)
  1613. X      TooFew("X2");
  1614. X    xeast = atoi(argv[1]);
  1615. X    if (xeast < 1 || xeast > TOTAL)
  1616. X      BadVal("X2", xeast);
  1617. X    xeast = -xeast;
  1618. X    i++;
  1619. X    break;
  1620. X  case 'd':
  1621. X    if (argc <= 1)
  1622. X      TooFew("Xd");
  1623. X    dispname = argv[1];
  1624. X    i++;
  1625. X    break;
  1626. X#ifdef WIN
  1627. X  case 'n':
  1628. X    if (argc > 1 && (xnow = atoi(argv[1])))
  1629. X      i++;
  1630. X    else
  1631. X      xnow = 10;
  1632. X    if (xnow < 1 || xnow > 10)
  1633. X      BadVal("Xn", xnow);
  1634. X    break;
  1635. X#endif
  1636. X  case 'o':
  1637. X    if (argc <= 1)
  1638. X      TooFew("Xo");
  1639. X    xbitmap = TRUE;
  1640. X    for (j = 0; outputfile[j] = argv[1][j]; j++)
  1641. X      ;
  1642. X    i++;
  1643. X    break;
  1644. X  default:
  1645. X    fprintf(stderr, "%s: Unknown switch -X%c\n", appname, argv[0][pos]);
  1646. X    Terminate(1);
  1647. X  }
  1648. X  return i;    /* 'i' contains the value to be added to argc when we return. */
  1649. X}
  1650. X
  1651. X
  1652. X/* This is the main interface to all the graphics features. This routine     */
  1653. X/* is called from the main program if any of the -X switches were specified, */
  1654. X/* and it sets up for and goes and generates the appropriate graphics chart. */
  1655. X
  1656. Xvoid XAction()
  1657. X{
  1658. X  /* First figure out what graphic mode to generate the chart in, based on */
  1659. X  /* various non-X command switches, e.g. -L combined with -X, -g combined */
  1660. X  /* with -X, and so on, and determine the size the window is to be, too.  */
  1661. X
  1662. X  if (modex == 'c' && (todisplay & DASHL) > 0)
  1663. X    modex = 'l';
  1664. X  else if (modex == 'c' && (todisplay & DASHg | todisplay & DASHm) > 0) {
  1665. X    modex = 'a';
  1666. X    chartx = charty = (OBJECTS + (relation == DASHr0))*CELLSIZE*SCALE + 1;
  1667. X  } else if (modex == 'c' && (todisplay & DASHZ) > 0) {
  1668. X    modex = 'z';
  1669. X    /*if (!(exdisplay & DASHZ0)) {
  1670. X      chartx = (360+12)*SCALE;
  1671. X      charty = (90*2+12)*SCALE;
  1672. X    }*/
  1673. X  } else if (modex == 'c' && (todisplay & DASHS) > 0)
  1674. X    modex = 's';
  1675. X  if (modex == 'l' || modex == 'w') {
  1676. X    chartx = 360*SCALE+2;
  1677. X    charty = (90*2+1)*SCALE+2;
  1678. X  }
  1679. X  if (xbitmap) {                       /* Initialize bitmap or window. */
  1680. X    Allocate(bm, BITMAPSIZE, bitmap);
  1681. X    if (bm == NULL) {
  1682. X      fprintf(stderr, "%s: Out of memory for bitmap.\n", appname);
  1683. X      Terminate(1);
  1684. X    }
  1685. X    XColorInit();
  1686. X  }
  1687. X#ifdef WIN
  1688. X  else
  1689. X    XBegin();
  1690. X#endif
  1691. X  if (xroot || xbitmap)    /* Go draw the graphic chart. */
  1692. X    XChart();
  1693. X  if (xbitmap) {    /* Write bitmap to file if in that mode. */
  1694. X    WriteFile();
  1695. X    Deallocate(bm);
  1696. X  }
  1697. X#ifdef WIN
  1698. X  else {
  1699. X#ifdef X11
  1700. X    if (xroot) {
  1701. X      XSetWindowBackgroundPixmap(disp, root, pixmap);    /* Process -XB. */
  1702. X      XClearWindow(disp, root);
  1703. X    } else
  1704. X#endif
  1705. X      XSpin();    /* Window's up; process commands given to window now. */
  1706. X    XEnd();
  1707. X  }
  1708. X#endif
  1709. X}
  1710. X#endif
  1711. X
  1712. X/* xdriver.c */
  1713. END_OF_FILE
  1714. if test 32400 -ne `wc -c <'xdriver.c'`; then
  1715.     echo shar: \"'xdriver.c'\" unpacked with wrong size!
  1716. fi
  1717. # end of 'xdriver.c'
  1718. fi
  1719. echo shar: End of archive 5 \(of 12\).
  1720. cp /dev/null ark5isdone
  1721. MISSING=""
  1722. for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
  1723.     if test ! -f ark${I}isdone ; then
  1724.     MISSING="${MISSING} ${I}"
  1725.     fi
  1726. done
  1727. if test "${MISSING}" = "" ; then
  1728.     echo You have unpacked all 12 archives.
  1729.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1730. else
  1731.     echo You still need to unpack the following archives:
  1732.     echo "        " ${MISSING}
  1733. fi
  1734. ##  End of shell archive.
  1735. exit 0
  1736.  
  1737. exit 0 # Just in case...
  1738.