home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / sun / volume2 / sunplot / sunplot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-04  |  21.9 KB  |  983 lines

  1. /*
  2.  * Sunplot - plotter backend for Sun workstation
  3.  *
  4.  * Copyright (c) 1987 by Sjoerd Mullender, Vrije Universiteit, Amsterdam.
  5.  *
  6.  * This program may be redistributed without fee as long as this copyright
  7.  * notice is in tact.
  8.  * Any commercial use is strictly prohibited.
  9.  */
  10.  
  11. #ifndef lint
  12. static char rcsid[] = "$Header: /tmp_mnt/tuintje/ufs1/cl/sjoerd/src/sunplot/RCS/sunplot.c,v 1.5 89/12/08 10:53:15 sjoerd Exp $";
  13. #endif
  14.  
  15. #include <stdio.h>
  16. #include <suntool/sunview.h>
  17. #include <suntool/scrollbar.h>
  18. #include <suntool/panel.h>
  19. #include <suntool/canvas.h>
  20.  
  21. /*
  22.  * Configurable definitions
  23.  */
  24. #define INIT_CANVAS_SIZE    512
  25. #define DEFAULT_SPACE        4096
  26. #define MAX_NAME_LENGTH        128
  27.  
  28. /*
  29.  * Unconfigurable definitions
  30.  */
  31. #define BIG            0x7FFFFFFF
  32.  
  33. #define FORMAT_RASTER        0
  34. #define FORMAT_ICON        1
  35. #define FORMAT_PLOT        2
  36.  
  37. #define LABEL            0
  38. #define SQUARE            1
  39. #define REVERSE            2
  40.  
  41. int client_object;        /* used for notifier */
  42. int *me = &client_object;    /* idem */
  43.  
  44. int curx, cury;            /* current position on plot */
  45. int lox, loy, hix = DEFAULT_SPACE, hiy = DEFAULT_SPACE;    /* current space */
  46. int slox, shix, sloy, shiy;    /* saved space settings for zooming */
  47. int minx, maxx, miny, maxy;    /* minimum and maximum values encountered */
  48. int hor_size, ver_size;        /* canvas size */
  49. int turned, xmirror, ymirror;    /* orientation of plot */
  50. int zooming;
  51. int make_label = TRUE;        /* print labels */
  52. int square = TRUE;        /* canvas is square */
  53. int reverse = FALSE;        /* reverse video */
  54. int dirty;
  55. Frame frame, dump_frame, options_frame;
  56. Panel panel, dump_panel, options_panel;
  57. Panel_item next_page_item;
  58. Panel_item hor_size_item, ver_size_item, toggle_item, font_item;
  59. Panel_item dump_format, dump_file_item;
  60. Canvas canvas;
  61. Pixwin *pw;
  62. Pixfont *font;
  63. char font_name[MAX_NAME_LENGTH];
  64. char font_dir[] = "/usr/lib/fonts/fixedwidthfonts/";
  65. Pr_texture texture;
  66. Pr_brush brush = {1};
  67.  
  68. short sunplot_icon_image[] = {
  69. #include "sunplot.icon"
  70. };
  71. mpr_static(sunplot_icon, 64, 64, 1, sunplot_icon_image);
  72.  
  73. char *malloc(), *realloc();
  74.  
  75. /*
  76.  *  input module
  77.  */
  78.  
  79. static char *plotcommands, *plptr;
  80. static int plotlength;
  81. static int maxplotlength;
  82. static int eof_seen;
  83.  
  84. getchr()
  85. {
  86.     register c;
  87.  
  88.     if (plptr < plotcommands + plotlength)
  89.         return *plptr++ & 0xFF;
  90.     if (eof_seen || (c = getchar()) == EOF) {
  91.         eof_seen = 1;
  92.         return EOF;
  93.     }
  94.     if (plotlength >= maxplotlength) {
  95.         plotcommands = realloc(plotcommands, maxplotlength *= 2);
  96.         plptr = plotcommands + plotlength;
  97.     }
  98.     *plptr++ = c;
  99.     plotlength++;
  100.     return c;
  101. }
  102.  
  103. getint()
  104. {
  105.     register n;
  106.  
  107.     n = getchr();
  108.     n = n | getchr() << 8;
  109.     if (n & 0x8000)            /* sign extend */
  110.         n |= ~0x7FFF;
  111.     return n;
  112. }
  113.  
  114. char *getstr()
  115. {
  116.     register i = plptr - plotcommands;
  117.     register c;
  118.  
  119.     while ((c = getchr()) != EOF && c != '\0' && c != '\n')
  120.         ;
  121.     plptr[-1] = 0;
  122.     return plotcommands + i;
  123. }
  124.  
  125. /*
  126.  * plot module
  127.  */
  128.  
  129. #define point(x,y)    pw_put(pw, plotx(x, y), ploty(x, y), !reverse)
  130.  
  131. #if 0
  132. #define line(x0,y0,x1,y1)    pw_vector(pw,plotx(x0,y0),ploty(x0,y0),plotx(x1,y1),ploty(x1,y1),PIX_SRC,!reverse)
  133. #else
  134. #define line(x0,y0,x1,y1)    pw_line(pw,plotx(x0,y0),ploty(x0,y0),plotx(x1,y1),ploty(x1,y1),&brush,&texture,reverse?PIX_CLR:PIX_SET)
  135. #endif
  136.  
  137. #define convx(x,s)    (((x) - lox) * (s) / (hix - lox))
  138. #define convy(y,s)    (((y) - loy) * (s) / (hiy - loy))
  139.  
  140. initplot()
  141. {
  142.     plptr = plotcommands = malloc(maxplotlength = 1024);
  143.     plotlength = 0;
  144. }
  145.  
  146. plotx(x, y)
  147. {
  148.     register a;
  149.  
  150.     switch (turned) {
  151.     case 0: a = convx(x, hor_size); break;
  152.     case 1: a = hor_size - 1 - convy(y, hor_size); break;
  153.     case 2: a = hor_size - 1 - convx(x, hor_size); break;
  154.     case 3: a = convy(y, hor_size); break;
  155.     }
  156.     return xmirror ? hor_size - 1 - a : a;
  157. }
  158.  
  159. ploty(x, y)
  160. {
  161.     register a;
  162.  
  163.     switch (turned) {
  164.     case 0: a = ver_size - 1 - convy(y, ver_size); break;
  165.     case 1: a = ver_size - 1 - convx(x, ver_size); break;
  166.     case 2: a = convy(y, ver_size); break;
  167.     case 3: a = convx(x, ver_size); break;
  168.     }
  169.     a = ymirror ? ver_size - 1 - a : a;
  170.     return zooming ? a+1 : a;
  171. }
  172.  
  173. label(s)
  174. char *s;
  175. {
  176.     struct pr_size pr_size;
  177.  
  178.     if (!make_label)
  179.         return 0;
  180.     pw_text(pw, plotx(curx, cury), ploty(curx, cury), reverse ? PIX_NOT(PIX_SRC)&PIX_DST : PIX_SRC|PIX_DST, font, s);
  181.     pr_size = pf_textwidth(strlen(s), font, s);
  182.     return pr_size.x * (hix - lox) / hor_size;
  183. }
  184.  
  185. linemod(s)
  186. char *s;
  187. {
  188.     static short dotted[] = {1,5,0};
  189.     static short solid[] = {1,0};
  190.     static short longdashed[] = {10,6,0};
  191.     static short shortdashed[] = {5,3,0};
  192.     static short dotdashed[] = {7,3,1,3,0};
  193.  
  194.     if (strcmp(s, "dotted") == 0) {
  195.         texture.pattern = dotted;
  196.     } else if (strcmp(s, "solid") == 0) {
  197.         texture.pattern = solid;
  198.     } else if (strcmp(s, "longdashed") == 0) {
  199.         texture.pattern = longdashed;
  200.     } else if (strcmp(s, "shortdashed") == 0) {
  201.         texture.pattern = shortdashed;
  202.     } else if (strcmp(s, "dotdashed") == 0) {
  203.         texture.pattern = dotdashed;
  204.     }
  205. }
  206.  
  207. isqrt(n)
  208. {
  209.     int a, b, c;
  210.  
  211.     a = n;
  212.     b = n;
  213.     if (n > 1) {
  214.         while (a > 0) {
  215.             a = a >> 2;
  216.             b = b >> 1;
  217.         }
  218.         do {
  219.             a = b;
  220.             c = n / b;
  221.             b = (c + a) >> 1;
  222.         } while ((a - c) < -1 || (a - c) > 1);
  223.     }
  224.     return b;
  225. }
  226.  
  227. static setcir(x, y, a1, b1, c1, a2, b2, c2)
  228. {
  229.     if (a1 * y - b1 * x >= c1 && a2 * y - b2 * x <= c2)
  230.         point(x, y);
  231. }
  232.  
  233. arc(x, y, x1, y1, x2, y2)
  234. {
  235.     register a1 = x1 - x, b1 = y1 - y, a2 = x2 - x, b2 = y2 - y;
  236.     register c1 = a1 * y - b1 * x, c2 = a2 * y - b2 * x;
  237.     register r2 = a1 * a1 + b1 * b1;
  238.     register i, di, sqrt, dx, dy;
  239.  
  240.     dx = (hix - lox) / hor_size;
  241.     dy = (hiy - loy) / ver_size;
  242.     di = dx < dy ? dx : dy;
  243.     if (di <= 0)
  244.         di = 1;
  245.     for (i = isqrt(r2 >> 1); i >= 0; i -= di) {
  246.         sqrt = isqrt(r2 - i * i);
  247.         setcir(x + i, y + sqrt, a1, b1, c1, a2, b2, c2);
  248.         setcir(x + i, y - sqrt, a1, b1, c1, a2, b2, c2);
  249.         setcir(x - i, y + sqrt, a1, b1, c1, a2, b2, c2);
  250.         setcir(x - i, y - sqrt, a1, b1, c1, a2, b2, c2);
  251.         setcir(x + sqrt, y + i, a1, b1, c1, a2, b2, c2);
  252.         setcir(x + sqrt, y - i, a1, b1, c1, a2, b2, c2);
  253.         setcir(x - sqrt, y + i, a1, b1, c1, a2, b2, c2);
  254.         setcir(x - sqrt, y - i, a1, b1, c1, a2, b2, c2);
  255.     }
  256. }
  257.  
  258. circle(x, y, r)
  259. {
  260.     arc(x, y, x + r, y, x - r, y);
  261.     arc(x, y, x - r, y, x + r, y);
  262. }
  263.  
  264. Notify_value input_reader(me, fd)
  265. int *me;
  266. int fd;
  267. {
  268.     int newx, newy, x, y, r;
  269.     register char *p;
  270.  
  271.     do {
  272.         switch (getchr()) {
  273.         case 'm':                /* move */
  274.             dirty = 1;
  275.             curx = getint();
  276.             cury = getint();
  277.             if (curx < minx) minx = curx;
  278.             if (curx > maxx) maxx = curx;
  279.             if (cury < miny) miny = cury;
  280.             if (cury > maxy) maxy = cury;
  281.             break;
  282.         case 'n':                /* cont */
  283.             dirty = 1;
  284.             newx = getint();
  285.             newy = getint();
  286.             line(curx, cury, newx, newy);
  287.             curx = newx;
  288.             cury = newy;
  289.             if (curx < minx) minx = curx;
  290.             if (curx > maxx) maxx = curx;
  291.             if (cury < miny) miny = cury;
  292.             if (cury > maxy) maxy = cury;
  293.             break;
  294.         case 'p':                /* point */
  295.             dirty = 1;
  296.             curx = getint();
  297.             cury = getint();
  298.             point(curx, cury);
  299.             if (curx < minx) minx = curx;
  300.             if (curx > maxx) maxx = curx;
  301.             if (cury < miny) miny = cury;
  302.             if (cury > maxy) maxy = cury;
  303.             break;
  304.         case 'l':                /* line */
  305.             dirty = 1;
  306.             newx = getint();
  307.             newy = getint();
  308.             curx = getint();
  309.             cury = getint();
  310.             line(newx, newy, curx, cury);
  311.             if (newx < minx) minx = newx;
  312.             if (newx > maxx) maxx = newx;
  313.             if (newy < miny) miny = newy;
  314.             if (newy > maxy) maxy = newy;
  315.             if (curx < minx) minx = curx;
  316.             if (curx > maxx) maxx = curx;
  317.             if (cury < miny) miny = cury;
  318.             if (cury > maxy) maxy = cury;
  319.             break;
  320.         case 't':                /* label */
  321.             dirty = 1;
  322.             p = getstr();
  323.             curx += label(p);
  324.             plptr[-1] = '\n';
  325.             if (curx < minx) minx = curx;
  326.             if (curx > maxx) maxx = curx;
  327.             break;
  328.         case 'a':                /* arc */
  329.             dirty = 1;
  330.             x = getint();
  331.             y = getint();
  332.             newx = getint();
  333.             newy = getint();
  334.             curx = getint();
  335.             cury = getint();
  336.             arc(x, y, newx, newy, curx, cury);
  337.             if (x < minx) minx = x;
  338.             if (x > maxx) maxx = x;
  339.             if (y < miny) miny = y;
  340.             if (y > maxy) maxy = y;
  341.             if (newx < minx) minx = newx;
  342.             if (newx > maxx) maxx = newx;
  343.             if (newy < miny) miny = newy;
  344.             if (newy > maxy) maxy = newy;
  345.             if (curx < minx) minx = curx;
  346.             if (curx > maxx) maxx = curx;
  347.             if (cury < miny) miny = cury;
  348.             if (cury > maxy) maxy = cury;
  349.             break;
  350.         case 'c':                /* circle */
  351.             dirty = 1;
  352.             curx = getint();
  353.             cury = getint();
  354.             r = getint();
  355.             circle(curx, cury, r);
  356.             if (curx - r < minx) minx = curx - r;
  357.             if (curx + r > maxx) maxx = curx + r;
  358.             if (cury - r < miny) miny = cury - r;
  359.             if (cury + r > maxy) maxy = cury + r;
  360.             break;
  361.         case 'e':                /* erase */
  362.             if (!dirty)
  363.                 break;
  364.             panel_set(next_page_item, PANEL_SHOW_ITEM, TRUE, 0);
  365.             /* fall through */
  366.         case EOF:
  367.             notify_set_input_func(me, NOTIFY_FUNC_NULL, fd);
  368.             if (zooming) {
  369.                 lox = slox;
  370.                 hix = shix;
  371.                 loy = sloy;
  372.                 hiy = shiy;
  373.                 zooming = 0;
  374.             }
  375.             return NOTIFY_DONE;
  376.         case 'f':                /* linemod */
  377.             dirty = 1;
  378.             p = getstr();
  379.             linemod(p);
  380.             plptr[-1] = '\n';
  381.             break;
  382.         case 's':                /* space */
  383.             if (zooming) {
  384.                 slox = getint();
  385.                 sloy = getint();
  386.                 shix = getint();
  387.                 shiy = getint();
  388.             } else {
  389.                 lox = getint();
  390.                 loy = getint();
  391.                 hix = getint();
  392.                 hiy = getint();
  393.             }
  394.             break;
  395.         }
  396.     } while (plptr < plotcommands + plotlength || stdin->_cnt > 0);
  397.     return NOTIFY_DONE;
  398. }
  399.  
  400. /*
  401.  * button routines
  402.  */
  403.  
  404. restartplot()
  405. {
  406.     dirty = 0;
  407.     minx = BIG;
  408.     maxx = -BIG;
  409.     miny = BIG;
  410.     maxy = -BIG;
  411.     plptr = plotcommands;
  412.  
  413.     /* clear the canvas */
  414.     pw_writebackground(pw, 0, 0, (int) window_get(canvas, CANVAS_WIDTH),
  415.                 (int) window_get(canvas, CANVAS_HEIGHT),
  416.                 reverse ? PIX_SET : PIX_CLR);
  417. }
  418.  
  419. resetplot()
  420. {
  421.     restartplot();
  422.     plotlength = 0;
  423. }
  424.  
  425. void redraw()
  426. {
  427.     if (zooming) {
  428.         lox = slox;
  429.         hix = shix;
  430.         loy = sloy;
  431.         hiy = shiy;
  432.         zooming = 0;
  433.     }
  434.     restartplot();
  435.     input_reader(me, fileno(stdin));
  436. }
  437.  
  438. void nextpage()
  439. {
  440.     resetplot();
  441.     panel_set(next_page_item, PANEL_SHOW_ITEM, FALSE, 0);
  442.     notify_set_input_func(me, input_reader, fileno(stdin));
  443.     if (stdin->_cnt > 0)
  444.         input_reader(me, fileno(stdin));
  445. }
  446.  
  447. void zoom()
  448. {
  449.     int a;
  450.  
  451.     if (!zooming) {
  452.         slox = lox;
  453.         shix = hix;
  454.         sloy = loy;
  455.         shiy = hiy;
  456.         zooming = 1;
  457.     }
  458.     if (maxx == minx) {
  459.         maxx++;
  460.         minx--;
  461.     }
  462.     if (maxy == miny) {
  463.         maxy++;
  464.         miny--;
  465.     }
  466.     if ((a = (maxx-minx) * (shiy-sloy) / (shix-slox)) >= maxy-miny) {
  467.         loy = miny - (a - maxy + miny) / 2;
  468.         hiy = loy + a;
  469.         lox = minx;
  470.         hix = maxx;
  471.     } else {
  472.         a = (maxy - miny) * (shix - slox) / (shiy - sloy);
  473.         lox = minx - (a - maxx + minx) / 2;
  474.         hix = lox + a;
  475.         loy = miny;
  476.         hiy = maxy;
  477.     }
  478.     hix++;
  479.     hiy++;
  480.     restartplot();
  481.     input_reader(me, fileno(stdin));
  482. }
  483.  
  484. void quit()
  485. {
  486.     /* don't ask for confirmation */
  487.     if (font)
  488.         pf_close(font);
  489.     window_set(frame, FRAME_NO_CONFIRM, TRUE, 0);
  490.     window_destroy(frame);
  491. }
  492.  
  493. void turn()
  494. {
  495.     int tmp;
  496.  
  497.     turned = (turned + 1) & 3;
  498.     tmp = xmirror;
  499.     xmirror = ymirror;
  500.     ymirror = tmp;
  501. }
  502.  
  503. void mirrorx()
  504. {
  505.     xmirror ^= 1;
  506. }
  507.  
  508. void mirrory()
  509. {
  510.     ymirror ^= 1;
  511. }
  512.  
  513. void canvas_fit()
  514. {
  515.     register int w, h;
  516.     
  517.     w = (int) window_get(canvas, WIN_WIDTH) - (int) scrollbar_get((Scrollbar) window_get(canvas, WIN_VERTICAL_SCROLLBAR), SCROLL_THICKNESS);
  518.     h = (int) window_get(canvas, WIN_HEIGHT) - (int) scrollbar_get((Scrollbar) window_get(canvas, WIN_HORIZONTAL_SCROLLBAR), SCROLL_THICKNESS);
  519.     if ((int) panel_get(toggle_item, PANEL_TOGGLE_VALUE, SQUARE)) {
  520.         if (w < h)
  521.             h = w;
  522.         else
  523.             w = h;
  524.     }
  525.     panel_set(hor_size_item, PANEL_VALUE, w, 0);
  526.     panel_set(ver_size_item, PANEL_VALUE, h, 0);
  527. }
  528.  
  529. /*
  530.  * initialization
  531.  */
  532.  
  533. void toggle_proc()
  534. {
  535.     if ((int) panel_get(toggle_item, PANEL_TOGGLE_VALUE, SQUARE)) {
  536.         panel_set(ver_size_item,
  537.             PANEL_SHOW_ITEM,    FALSE,
  538.             0);
  539.         panel_set(hor_size_item,
  540.             PANEL_LABEL_STRING,    "Canvas size:     ",
  541.             0);
  542.     } else {
  543.         panel_set(ver_size_item,
  544.             PANEL_SHOW_ITEM,    TRUE,
  545.             0);
  546.         panel_set(hor_size_item,
  547.             PANEL_LABEL_STRING,    "Horizontal size: ",
  548.             0);
  549.     }
  550. }
  551.  
  552. void options()
  553. {
  554.     window_set(options_frame, WIN_SHOW, TRUE, 0);
  555. }
  556.  
  557. void apply_options()
  558. {
  559.     register int r;
  560.     char *f;
  561.     Cursor cursor;
  562.  
  563.     square = (int) panel_get(toggle_item, PANEL_TOGGLE_VALUE, SQUARE);
  564.     r = (int) panel_get(hor_size_item, PANEL_VALUE);
  565.     if (r != hor_size) {
  566.         window_set(canvas, CANVAS_WIDTH, r, 0);
  567.         hor_size = r;
  568.     }
  569.     if (square)
  570.         r = hor_size;
  571.     else
  572.         r = (int) panel_get(ver_size_item, PANEL_VALUE);
  573.     if (r != ver_size) {
  574.         window_set(canvas, CANVAS_HEIGHT, r, 0);
  575.         ver_size = r;
  576.     }
  577.     f = (char *) panel_get_value(font_item);
  578.     if (f == 0 || *f == 0) {
  579.         if (font_name[0] != 0) {
  580.             font_name[0] = 0;
  581.             if (font)
  582.                 pf_close(font);
  583.             font = pf_default();
  584.         }
  585.     } else {
  586.         if (font_name[0] == 0 || strcmp(f, font_name) != 0) {
  587.             strcpy(font_name, f);
  588.             f = font_name;
  589.             if (*f != '/') {
  590.                 f = malloc(strlen(font_dir)+strlen(font_name)+1);
  591.                 strcpy(f, font_dir);
  592.                 strcat(f, font_name);
  593.             }
  594.             if (font)
  595.                 pf_close(font);
  596.             font = pf_open(f);
  597.             if (f != font_name)
  598.                 free(f);
  599.         }
  600.     }
  601.     if (font == 0) {
  602.         font_name[0] = 0;
  603.         font = pf_default();
  604.     }
  605.     make_label = (int) panel_get(toggle_item, PANEL_TOGGLE_VALUE, LABEL);
  606.     reverse = (int) panel_get(toggle_item, PANEL_TOGGLE_VALUE, REVERSE);
  607.     cursor = (Cursor) window_get(canvas, WIN_CURSOR);
  608.     cursor_set(cursor,
  609.             CURSOR_OP, reverse ? PIX_SRC^PIX_DST : PIX_SRC|PIX_DST,
  610.             0);
  611.     window_set(canvas, WIN_CURSOR, cursor, 0);
  612.     redraw();
  613. }
  614.  
  615. void options_done()
  616. {
  617.     window_set(options_frame, WIN_SHOW, FALSE, 0);
  618.     apply_options();
  619. }
  620.  
  621. void dump()
  622. {
  623.     window_set(dump_frame, WIN_SHOW, TRUE, 0);
  624. }
  625.  
  626. void do_dump()
  627. {
  628.     char *file;
  629.     int width, height;
  630.     register int x, y;
  631.     register char *s;
  632.     register short *p;
  633.     FILE *f;
  634.  
  635.     /* we use the fact that the canvas is retained */
  636.     file = (char *) panel_get_value(dump_file_item);
  637.     if (file != 0 && *file != 0 && (f = fopen(file, "w")) != 0) {
  638.         width = (int) window_get(canvas, CANVAS_WIDTH);
  639.         height = (int) window_get(canvas, CANVAS_HEIGHT);
  640.         switch ((int) panel_get_value(dump_format)) {
  641.         case FORMAT_RASTER:
  642.             pr_dump(pw->pw_prretained, f, (colormap_t *) 0,
  643.                             RT_STANDARD, 0);
  644.             break;
  645.         case FORMAT_ICON:
  646.             p = mpr_d(pw->pw_prretained)->md_image;
  647.             fprintf(f, "\
  648. /* Format_version=1, Width=%d, Height=%d, Depth=1, Valid_bits_per_item=16\n\
  649.  */\n", (width+15) & ~15, height);
  650.             for (y = 0; y < height; y++) {
  651.                 s = "\t";
  652.                 for (x = 0; x < width; x += 16) {
  653.                     fprintf(f, "%s0x%04x,", s, *p & 0xFFFF);
  654.                     p++;
  655.                     s = "";
  656.                 }
  657.                 fprintf(f, "\n");
  658.             }
  659.             break;
  660.         case FORMAT_PLOT:
  661.             fwrite(plotcommands, 1, plotlength, f);
  662.             break;
  663.         }
  664.         fclose(f);
  665.     }
  666. }
  667.  
  668. void dump_done()
  669. {
  670.     window_set(dump_frame, WIN_SHOW, FALSE, 0);
  671. }
  672.  
  673. void fit_screen()
  674. {
  675.     register int w, h;
  676.     
  677.     w = hor_size + (int) scrollbar_get((Scrollbar) window_get(canvas, WIN_VERTICAL_SCROLLBAR), SCROLL_THICKNESS);
  678.     h = ver_size + (int) scrollbar_get((Scrollbar) window_get(canvas, WIN_HORIZONTAL_SCROLLBAR), SCROLL_THICKNESS);
  679.     window_set(canvas, WIN_WIDTH, w, WIN_HEIGHT, h, 0);
  680.     window_set(canvas, CANVAS_WIDTH, hor_size, CANVAS_HEIGHT, ver_size, 0);
  681.     window_set(panel, WIN_WIDTH, w, 0);
  682.     window_fit(frame);
  683. }
  684.  
  685. /*
  686.  * initialization
  687.  */
  688.  
  689. void dump_init()
  690. {
  691.     register Pixrect *pr;
  692.  
  693.     dump_frame = window_create(frame, FRAME,
  694.             FRAME_DONE_PROC,    dump_done,
  695.             0);
  696.     dump_panel = window_create(dump_frame, PANEL, 0);
  697.     pr = panel_button_image(dump_panel, "Done", 0, (Pixfont *) 0);
  698.     (void) panel_create_item(dump_panel, PANEL_BUTTON,
  699.             PANEL_LABEL_IMAGE,    pr,
  700.             PANEL_NOTIFY_PROC,    dump_done,
  701.             0);
  702.     pr = panel_button_image(dump_panel, "Dump", 0, (Pixfont *) 0);
  703.     (void) panel_create_item(dump_panel, PANEL_BUTTON,
  704.             PANEL_LABEL_IMAGE,    pr,
  705.             PANEL_NOTIFY_PROC,    do_dump,
  706.             0);
  707.     /* order of strings is important (see definitions of FORMAT_*) */
  708.     dump_format = panel_create_item(dump_panel, PANEL_CYCLE,
  709.             PANEL_LABEL_STRING,    "Dump format:",
  710.             PANEL_CHOICE_STRINGS,    "Rasterfile format",
  711.                         "Icon format",
  712.                         "Plot format",
  713.                         (char *) 0,
  714.             0);
  715.     dump_file_item = panel_create_item(dump_panel, PANEL_TEXT,
  716.             PANEL_LABEL_X,        ATTR_COL(0),
  717.             PANEL_LABEL_Y,        ATTR_ROW(1),
  718.             PANEL_VALUE_DISPLAY_LENGTH, 30,
  719.             PANEL_LABEL_STRING,    "Dump to file:",
  720.             0);
  721.     window_fit(dump_panel);
  722.     window_fit(dump_frame);
  723. }
  724.  
  725. void options_init()
  726. {
  727.     register Pixrect *pr;
  728.  
  729.     options_frame = window_create(frame, FRAME,
  730.             FRAME_DONE_PROC,    options_done,
  731.             0);
  732.     options_panel = window_create(options_frame, PANEL, 0);
  733.  
  734.     pr = panel_button_image(options_panel, "Done", 0, (Pixfont *) 0);
  735.     (void) panel_create_item(options_panel, PANEL_BUTTON,
  736.             PANEL_LABEL_IMAGE,    pr,
  737.             PANEL_NOTIFY_PROC,    options_done,
  738.             0);
  739.     pr = panel_button_image(options_panel, "Apply", 0, (Pixfont *) 0);
  740.     (void) panel_create_item(options_panel, PANEL_BUTTON,
  741.             PANEL_LABEL_IMAGE,    pr,
  742.             PANEL_NOTIFY_PROC,    apply_options,
  743.             0);
  744.     pr = panel_button_image(options_panel, "Rotate", 0, (Pixfont*) 0);
  745.     (void) panel_create_item(options_panel, PANEL_BUTTON,
  746.             PANEL_NOTIFY_PROC,    turn,
  747.             PANEL_LABEL_IMAGE,    pr,
  748.             0);
  749.     pr = panel_button_image(options_panel, "X Mirror", 0, (Pixfont*) 0);
  750.     (void) panel_create_item(options_panel, PANEL_BUTTON,
  751.             PANEL_NOTIFY_PROC,    mirrorx,
  752.             PANEL_LABEL_IMAGE,    pr,
  753.             0);
  754.     pr = panel_button_image(options_panel, "Y Mirror", 0, (Pixfont*) 0);
  755.     (void) panel_create_item(options_panel, PANEL_BUTTON,
  756.             PANEL_NOTIFY_PROC,    mirrory,
  757.             PANEL_LABEL_IMAGE,    pr,
  758.             0);
  759.     pr = panel_button_image(options_panel, "Fit Canvas", 0, (Pixfont*) 0);
  760.     (void) panel_create_item(options_panel, PANEL_BUTTON,
  761.             PANEL_NOTIFY_PROC,    canvas_fit,
  762.             PANEL_LABEL_IMAGE,    pr,
  763.             0);
  764.     toggle_item = panel_create_item(options_panel, PANEL_TOGGLE,
  765.             PANEL_LAYOUT,        PANEL_HORIZONTAL,
  766.             PANEL_CHOICE_STRINGS,    "Label",
  767.                         "Square",
  768.                         "Reverse",
  769.                         (char *) 0,
  770.             PANEL_TOGGLE_VALUE,    LABEL, make_label,
  771.             PANEL_TOGGLE_VALUE,    SQUARE, square,
  772.             PANEL_TOGGLE_VALUE,    REVERSE, reverse,
  773.             PANEL_NOTIFY_PROC,    toggle_proc,
  774.             0);
  775.     font_item = panel_create_item(options_panel, PANEL_TEXT,
  776.             PANEL_VALUE_DISPLAY_LENGTH, 51,
  777.             PANEL_VALUE_STORED_LENGTH, MAX_NAME_LENGTH,
  778.             PANEL_LABEL_STRING,    "Font name:",
  779.             PANEL_VALUE,        font_name,
  780.             0);
  781.     hor_size_item = panel_create_item(options_panel, PANEL_SLIDER,
  782.             PANEL_LABEL_STRING,    "Horizontal size: ",
  783.             PANEL_VALUE,        hor_size,
  784.             PANEL_MIN_VALUE,    64,
  785.             PANEL_MAX_VALUE,    2048,
  786.             PANEL_SLIDER_WIDTH,    225,
  787.             0);
  788.     ver_size_item = panel_create_item(options_panel, PANEL_SLIDER,
  789.             PANEL_LABEL_STRING,    "Vertical size:   ",
  790.             PANEL_VALUE,        ver_size,
  791.             PANEL_MIN_VALUE,    64,
  792.             PANEL_MAX_VALUE,    2048,
  793.             PANEL_SLIDER_WIDTH,    225,
  794.             0);
  795.     window_fit(options_panel);
  796.     window_fit(options_frame);
  797.     if (square) {
  798.         panel_set(ver_size_item,
  799.             PANEL_SHOW_ITEM,    FALSE,
  800.             0);
  801.         panel_set(hor_size_item,
  802.             PANEL_LABEL_STRING,    "Canvas size:     ",
  803.             0);
  804.     }
  805. }
  806.  
  807. void panel_init()
  808. {
  809.     register Pixrect *pr;
  810.  
  811.     panel = window_create(frame, PANEL, 0);
  812.     pr = panel_button_image(panel, "Next Page", 0, (Pixfont *) 0);
  813.     next_page_item = panel_create_item(panel, PANEL_BUTTON,
  814.             PANEL_NOTIFY_PROC,    nextpage,
  815.             PANEL_LABEL_IMAGE,    pr,
  816.             PANEL_SHOW_ITEM,    FALSE,
  817.             0);
  818.     pr = panel_button_image(panel, "Redraw", 0, (Pixfont *) 0);
  819.     (void) panel_create_item(panel, PANEL_BUTTON,
  820.             PANEL_NOTIFY_PROC,    redraw,
  821.             PANEL_LABEL_IMAGE,    pr,
  822.             0);
  823.     pr = panel_button_image(panel, "Zoom", 0, (Pixfont *) 0);
  824.     (void) panel_create_item(panel, PANEL_BUTTON,
  825.             PANEL_NOTIFY_PROC,    zoom,
  826.             PANEL_LABEL_IMAGE,    pr,
  827.             0);
  828.     pr = panel_button_image(panel, "Options", 0, (Pixfont *) 0);
  829.     (void) panel_create_item(panel, PANEL_BUTTON,
  830.             PANEL_NOTIFY_PROC,    options,
  831.             PANEL_LABEL_IMAGE,    pr,
  832.             0);
  833.     pr = panel_button_image(panel, "Dump", 0, (Pixfont *) 0);
  834.     (void) panel_create_item(panel, PANEL_BUTTON,
  835.             PANEL_NOTIFY_PROC,    dump,
  836.             PANEL_LABEL_IMAGE,    pr,
  837.             0);
  838.     pr = panel_button_image(panel, "Fit Screen", 0, (Pixfont *) 0);
  839.     (void) panel_create_item(panel, PANEL_BUTTON,
  840.             PANEL_NOTIFY_PROC,    fit_screen,
  841.             PANEL_LABEL_IMAGE,    pr,
  842.             0);
  843.     pr = panel_button_image(panel, "Quit", 0, (Pixfont *) 0);
  844.     (void) panel_create_item(panel, PANEL_BUTTON,
  845.             PANEL_NOTIFY_PROC,    quit,
  846.             PANEL_LABEL_IMAGE,    pr,
  847.             0);
  848.     window_fit_height(panel);
  849. }
  850.  
  851. canvas_init()
  852. {
  853.     canvas = window_create(frame, CANVAS,
  854.             CANVAS_AUTO_SHRINK,    FALSE,
  855.             CANVAS_WIDTH,        hor_size,
  856.             CANVAS_HEIGHT,        ver_size,
  857.             CANVAS_RETAINED,    TRUE,
  858.             WIN_VERTICAL_SCROLLBAR,    scrollbar_create(0),
  859.             WIN_HORIZONTAL_SCROLLBAR, scrollbar_create(0),
  860.             0);
  861.     pw = canvas_pixwin(canvas);
  862. }
  863.  
  864. usage(cmd)
  865. char *cmd;
  866. {
  867.     fprintf(stderr, "\
  868. %s recognizes the following options:\n\
  869. \t-c canvas-size\t\t(set size of canvas)\n\
  870. \t-h horizontal-size\t(set horizontal size of canvas)\n\
  871. \t-v vertical-size\t(set vertical size of canvas)\n\
  872. \t-f font-name\t\t(use specified font for labels)\n\
  873. \t-r\t\t\t(rotate 90 degrees)\n\
  874. \t-x\t\t\t(mirror in x axis)\n\
  875. \t-y\t\t\t(mirror in y axis)\n\
  876. \t-l\t\t\t(don't print labels)\n\
  877. \t-s\t\t\t(don't force canvas to be square)\n\
  878. \t-R\t\t\t(display in reverse video)\n\
  879. ", cmd);
  880.     exit(1);
  881. }
  882.  
  883. main(argc, argv)
  884. char **argv;
  885. {
  886.     Cursor cursor;
  887.     register c;
  888.     extern char *optarg;
  889.  
  890.     initplot();
  891.  
  892.     hor_size = ver_size = INIT_CANVAS_SIZE;
  893.     frame = window_create(NULL, FRAME,
  894.             FRAME_LABEL,        "Sunplot",
  895.             FRAME_SUBWINDOWS_ADJUSTABLE, FALSE,
  896.             FRAME_ICON, icon_create(ICON_IMAGE, &sunplot_icon, 0),
  897.             FRAME_ARGC_PTR_ARGV,    &argc, argv,
  898.             0);
  899.     while ((c = getopt(argc, argv, "c:h:v:lsRrxyf:")) != EOF) {
  900.         switch (c) {
  901.         case 'c':
  902.             hor_size = atoi(optarg);
  903.             if (hor_size < 64)
  904.                 hor_size = 64;
  905.             ver_size = hor_size;
  906.             square = TRUE;
  907.             break;
  908.         case 'h':
  909.             hor_size = atoi(optarg);
  910.             if (hor_size < 64)
  911.                 hor_size = 64;
  912.             square = FALSE;
  913.             break;
  914.         case 'v':
  915.             ver_size = atoi(optarg);
  916.             if (ver_size < 64)
  917.                 ver_size = 64;
  918.             square = FALSE;
  919.             break;
  920.         case 'l':
  921.             make_label = !make_label;
  922.             break;
  923.         case 's':
  924.             square = !square;
  925.             break;
  926.         case 'R':
  927.             reverse = !reverse;
  928.             break;
  929.         case 'r':
  930.             turn();
  931.             break;
  932.         case 'x':
  933.             mirrorx();
  934.             break;
  935.         case 'y':
  936.             mirrory();
  937.             break;
  938.         case 'f':
  939.             strcpy(font_name, optarg);
  940.             break;
  941.         default:
  942.             usage(argv[0]);
  943.             /*NOTREACHED*/
  944.         }
  945.     }
  946.     dump_init();
  947.     options_init();
  948.     panel_init();
  949.     canvas_init();
  950.     if (font_name[0]) {
  951.         register char *f = font_name;
  952.  
  953.         if (*f != '/') {
  954.             f = malloc(strlen(font_dir)+strlen(font_name)+1);
  955.             strcpy(f, font_dir);
  956.             strcat(f, font_name);
  957.         }
  958.         font = pf_open(f);
  959.         if (f != font_name)
  960.             free(f);
  961.     }
  962.     if (font == 0) {
  963.         font = pf_default();
  964.         font_name[0] = 0;
  965.     }
  966.  
  967.     fit_screen();
  968.  
  969.     notify_set_input_func(me, input_reader, fileno(stdin));
  970.  
  971.     linemod("solid");
  972.     restartplot();
  973.     cursor = (Cursor) window_get(canvas, WIN_CURSOR);
  974.     cursor_set(cursor,
  975.             CURSOR_OP, reverse ? PIX_SRC^PIX_DST : PIX_SRC|PIX_DST,
  976.             0);
  977.     window_set(canvas, WIN_CURSOR, cursor, 0);
  978.  
  979.     window_main_loop(frame);
  980.  
  981.     exit(0);
  982. }
  983.