home *** CD-ROM | disk | FTP | other *** search
/ gondwana.ecr.mu.oz.au/pub/ / Graphics.tar / Graphics / VOGLE.ZIP / VOGLE / DRIVERS / SUN.C < prev    next >
C/C++ Source or Header  |  2000-02-11  |  17KB  |  928 lines

  1.  
  2. /*
  3.  * Vogl/Vogle driver for Sun using sunview.
  4.  *
  5.  */
  6. /*
  7.  * define VOGLE for VOGLE library or leave blank for VOGL library
  8.  */
  9. #define VOGLE 1
  10.  
  11. #include <stdio.h>
  12.  
  13. #include <suntool/sunview.h>
  14. #include <suntool/canvas.h>
  15. #include <fcntl.h>
  16. #include <errno.h>
  17.  
  18. #ifdef SUN_3_5
  19. #define event_action    event_id
  20. #endif
  21.  
  22. #ifdef VOGLE
  23. #include "vogle.h"
  24. #else
  25. #include "vogl.h"
  26. #endif
  27.  
  28. #define    CMAPSIZE    256
  29. #define    STDFONTDIR    "/usr/lib/fonts/fixedwidthfonts/"
  30.  
  31. #define MIN(x,y)    ((x) < (y) ? (x) : (y))
  32.  
  33. #define OP_WHITE    (PIX_SRC | PIX_COLOR(7) | PIX_DONTCLIP)
  34. #define OP_BLACK    (PIX_SRC | PIX_COLOR(0) | PIX_DONTCLIP)
  35. #define COL_WHITE    7
  36. #define COL_BLACK    0
  37.  
  38. static Pixwin    *pw_tmp, *pw;
  39.  
  40. #ifdef BASE_COL_SET
  41. static Pixwin    *pw0;
  42. #endif
  43.  
  44. static Pixrect    *backb;
  45. static Pixfont    *font_id;
  46. static int    wfd, blanket_win;
  47. static int    oldflags;
  48. static int    pwfd, h, w;
  49. static int    colour;
  50. static Rect    wrect;
  51.  
  52. static char    use_sunview_canvas = 0;
  53.  
  54. #define    DASHED        1
  55. #define    FATLINES    2
  56. static unsigned char    lineflags = 0;
  57.  
  58. static Pr_brush    brush = {1};
  59. static Pr_texture    *t = (Pr_texture *)NULL;
  60. static Pr_texture    tex = {
  61.                 (short *)NULL,    
  62.                 0,
  63.                 {1, 1, 1, 0},
  64.                 0,
  65.             };
  66.  
  67. /*
  68.  * default colour map
  69.  */
  70.  
  71. static int    colnum = 8;
  72. static u_char   red[CMAPSIZE] = {
  73.             0, 255, 0, 255, 0, 255, 0, 255, 0,
  74.         },
  75.         green[CMAPSIZE] = {
  76.             0, 0, 255, 255, 0, 0, 255, 255, 0,
  77.         },
  78.         blue[CMAPSIZE] = {
  79.             0, 0, 0, 0, 255, 255, 255, 255, 0,
  80.         };
  81.  
  82. /*
  83.  * redisplay
  84.  *
  85.  *    redisplay the window.
  86.  */
  87. static void
  88. redisplay()
  89. {
  90.     pw_damaged(pw);
  91.  
  92.     pw_repairretained(pw);
  93.  
  94.     pw_donedamaged(pw);
  95. }
  96.  
  97. /*
  98.  * To be called from a resize procedure from withing sunview
  99.  */
  100. vo_sunview_canvas_size(sw, sh)
  101.     int    sw, sh;
  102. {
  103.     w = sw;
  104.         h = sh;
  105.  
  106.         vdevice.sizeX = vdevice.sizeY = MIN(h, w);
  107.         vdevice.sizeSx = w;
  108.         vdevice.sizeSy = h;
  109.  
  110.     if (pw->pw_prretained) {
  111.         mem_destroy(pw->pw_prretained);
  112.         backb = pw->pw_prretained = mem_create(w, h, vdevice.depth);
  113.     }
  114. }
  115.  
  116. /*
  117.  * vo_sunview_canvas
  118.  *
  119.  *     Tells VOGLE/VOGL to use a supplied sunview pixwin
  120.  */
  121. vo_sunview_canvas(canvas, cw, ch)
  122.     Canvas    canvas;
  123.     int    cw, ch;
  124. {
  125.     pw = canvas_pixwin(canvas);
  126.     use_sunview_canvas = 1;
  127.  
  128.     w = cw;
  129.     h = ch;
  130.  
  131.     vdevice.sizeX = vdevice.sizeY = MIN(h, w);
  132.     vdevice.sizeSx = w;
  133.     vdevice.sizeSy = h;
  134.  
  135.     vdevice.depth = pw->pw_pixrect->pr_depth;
  136.     if (!pw->pw_prretained)    /* Make us retained */
  137.         backb = pw->pw_prretained = mem_create(w, h, vdevice.depth);
  138.  
  139.     /* 
  140.      *  Set up the color map.  
  141.      */
  142.  
  143.     if (vdevice.depth > 1) {
  144.         pw_setcmsname(pw, "vogle");
  145.         pw_putcolormap(pw, 0, colnum, red, green, blue);
  146.     }
  147.  
  148.     wfd = (int)window_get(canvas, WIN_FD);
  149.  
  150.     /*
  151.      * Set non-blocking input for window.
  152.     oldflags = fcntl(wfd, F_GETFL, 0);
  153.     if (fcntl(wfd, F_SETFL, FNDELAY) < 0) {
  154.         perror("F_SETFL");
  155.         exit(1);
  156.     }
  157.      */
  158.  
  159.  
  160.     pw_batch_on(pw);
  161.  
  162. #ifndef VOGLE
  163.     vdevice.devname = "sun";
  164. #endif
  165.  
  166.     return(1);
  167. }
  168.  
  169. /*
  170.  * SUN_init
  171.  *
  172.  *    initialises drawing canvas to occupy current window
  173.  */
  174. SUN_init()
  175. {
  176.     int        i, prefx, prefy, prefxs, prefys, bw;
  177.     char        name[WIN_NAMESIZE];
  178.     Inputmask    imk, imp;
  179.     int        rootfd;
  180.  
  181.     if (use_sunview_canvas)
  182.         return(1);
  183.  
  184.     pw = (Pixwin *)NULL;
  185.  
  186. #ifdef BASE_COL_SET
  187.     pw0 = pw;
  188. #endif
  189.  
  190.     /*
  191.      * get the gfx win so we have some default sizes to use
  192.      */
  193.     we_getgfxwindow(name);
  194.     pwfd = open(name, 2);
  195.     win_getrect(pwfd, &wrect);
  196.     
  197.         /*
  198.          * Get the input masks of the base window...
  199.          */
  200.         win_get_pick_mask(pwfd, &imp);
  201.         win_get_kbd_mask(pwfd, &imk);
  202.  
  203.  
  204.     /*
  205.      * get a new window (either going to be a blanket window or
  206.      * a window in it's own right)
  207.      */
  208.     if ((wfd = win_getnewwindow()) == -1) {
  209.         fprintf(stderr, "No new windows!\n");
  210.         exit(1);
  211.     }
  212.  
  213.     getprefposandsize(&prefx, &prefy, &prefxs, &prefys);
  214.  
  215.     if (prefx > -1) {
  216.         wrect.r_left = prefx;
  217.         wrect.r_top = prefy;
  218.     }
  219.  
  220.     if (prefxs > -1) {
  221.         wrect.r_width = prefxs;
  222.         wrect.r_height = prefys;
  223.     }
  224.  
  225.     w = wrect.r_width;
  226.     h = wrect.r_height;
  227.  
  228.     bw = 3;
  229.     if (prefx > -1 || prefxs > -1) {
  230.         /*
  231.          * Make room for a 3 pixel border
  232.          */
  233.         if (wrect.r_left <= 2)
  234.             wrect.r_left = 0;
  235.         else
  236.             wrect.r_left -= bw;
  237.  
  238.         if (wrect.r_top <= 2)
  239.             wrect.r_top = 0;
  240.         else
  241.             wrect.r_top -= bw;
  242.  
  243.         wrect.r_width += 2 * bw;
  244.         wrect.r_height += 2 * bw;
  245.  
  246.         win_setrect(wfd, &wrect);
  247.  
  248.         /*
  249.          * get the parent (probably full screen window)
  250.          * so we can size our window to any size we like
  251.          * on the screen.
  252.          */
  253.         we_getparentwindow(name);
  254.         rootfd = open(name, 2);
  255.  
  256.         win_setlink(wfd, WL_PARENT, win_fdtonumber(rootfd));
  257.         win_setlink(wfd, WL_COVERED, WIN_NULLLINK);
  258.         win_insert(wfd);
  259.  
  260.         wmgr_top(wfd, rootfd);
  261.  
  262.         pw = pw_open(wfd);
  263.  
  264. #ifdef BASE_COL_SET
  265.         /*
  266.          * Get the pixrect for the window that we started in
  267.          * so we can set it's colourmap as well
  268.          */
  269.         pw0 = pw_open(pwfd);
  270. #endif
  271.  
  272.         close(rootfd);
  273.         blanket_win = 0;
  274.     } else {
  275.         win_insertblanket(wfd, pwfd);
  276.         pw = pw_region(pw_open(wfd), 0, 0, w, h);
  277.         blanket_win = 1;
  278.     }
  279.  
  280.     /*
  281.      * Set non-blocking input for window.
  282.      */
  283.     oldflags = fcntl(wfd, F_GETFL, 0);
  284.     if (fcntl(wfd, F_SETFL, FNDELAY) < 0) {
  285.         perror("F_SETFL");
  286.         exit(1);
  287.     }
  288.  
  289.     /*
  290.      * Setup the input masks for window.
  291.      */
  292.  
  293.     win_set_kbd_mask(wfd, &imk);
  294.         win_set_pick_mask(wfd, &imp);
  295.  
  296.     vdevice.depth = pw->pw_pixrect->pr_depth;
  297.  
  298.     /* 
  299.      *  Set up the color map.  
  300.      */
  301.  
  302.     if (vdevice.depth > 1) {
  303.         pw_setcmsname(pw, "vogle");
  304.         pw_putcolormap(pw, 0, colnum, red, green, blue);
  305. #ifdef BASE_COL_SET
  306.         if (pw0 != (Pixwin *)NULL) {
  307.             pw_setcmsname(pw0, "vogle");
  308.             pw_putcolormap(pw0, 0, colnum, red, green, blue);
  309.         }
  310. #endif
  311.     }
  312.  
  313.     if (prefx > -1 || prefxs > -1) {
  314.         /*
  315.          * Draw the border...
  316.          */
  317.         int    x0, y0, x1, y1;
  318.  
  319.         x0 = y0 = 0;
  320.         x1 = wrect.r_width - 1;
  321.         y1 = 0;
  322.         pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
  323.         pw_vector(pw, x0 + 2, y0 + 2, x1 - 2, y1 + 2, OP_WHITE, COL_WHITE);
  324.         pw_vector(pw, x0 + 1, y0 + 1, x1 - 1, y1 + 1, OP_BLACK, COL_BLACK);
  325.         x0 = x1;
  326.         y0 = y1;
  327.         x1 = x0;
  328.         y1 = wrect.r_height - 1;
  329.         pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
  330.         pw_vector(pw, x0 - 2, y0 + 2, x1 - 2, y1 - 2, OP_WHITE, COL_WHITE);
  331.         pw_vector(pw, x0 - 1, y0 + 1, x1 - 1, y1 - 1, OP_BLACK, COL_BLACK);
  332.         x0 = x1;
  333.         y0 = y1;
  334.         x1 = 0;
  335.         y1 = wrect.r_height - 1;
  336.         pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
  337.         pw_vector(pw, x0 - 2, y0 - 2, x1 + 2, y1 - 2, OP_WHITE, COL_WHITE);
  338.         pw_vector(pw, x0 - 1, y0 - 1, x1 + 1, y1 - 1, OP_BLACK, COL_BLACK);
  339.         x0 = x1;
  340.         y0 = y1;
  341.         x1 = 0;
  342.         y1 = 0;
  343.         pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
  344.         pw_vector(pw, x0 + 2, y0 - 2, x1 + 2, y1 + 2, OP_WHITE, COL_WHITE);
  345.         pw_vector(pw, x0 + 1, y0 - 1, x1 + 1, y1 + 1, OP_BLACK, COL_BLACK);
  346.         pw_tmp = pw;
  347.         pw = pw_region(pw_tmp, 3, 3, w, h);
  348.         pw_close(pw_tmp);
  349.     }
  350.  
  351.  
  352.     backb = pw->pw_prretained = mem_create(w, h, vdevice.depth);
  353.  
  354.     signal(SIGWINCH, redisplay);
  355.  
  356.     /*
  357.      *  Let VOGLE/VOGL know about the window size.
  358.      */
  359.         vdevice.sizeX = vdevice.sizeY = MIN(w, h);
  360.     vdevice.sizeSx = w;
  361.     vdevice.sizeSy = h;
  362.  
  363.     /*
  364.      * Set up batching.....(for speed and "pseudo" double buffering)
  365.      */
  366.     pw_batch_on(pw);
  367.  
  368.     return(1);
  369. }
  370.  
  371. /*
  372.  * SUN_exit
  373.  *
  374.  *    cleans up before returning the window to normal.
  375.  */
  376. SUN_exit()
  377. {
  378.     long    nbytes;
  379.     int    i;
  380.     Event    event;
  381.  
  382.     if (use_sunview_canvas)
  383.         return(1);
  384.  
  385.     /*
  386.      * Flush all events for this window.
  387.      *
  388.      * While doing non-blocking input input_readevent returns -1 and
  389.      * errno == EWOULDBLOCK when everything has been read, so if 
  390.      * errno != EWOULDBLOCK then something naughty happened...
  391.      */
  392.     while (input_readevent(wfd, &event) >= 0)
  393.         ;
  394.  
  395.     if (errno != EWOULDBLOCK) {
  396.         perror("SUN_exit(flushing), input_readevent");
  397.         exit();
  398.     }
  399.  
  400.     /*
  401.      * reset wfd to blocking input.
  402.      */
  403.     if (fcntl(wfd, F_SETFL, oldflags) < 0) {
  404.         perror("oldflags, F_SETFL");
  405.         exit(1);
  406.     }
  407.  
  408.     if (blanket_win)
  409.         win_removeblanket(wfd);
  410.     else 
  411.         win_remove(wfd);
  412.  
  413.     signal(SIGWINCH, SIG_DFL);
  414.  
  415.     return(1);
  416. }
  417.  
  418. /*
  419.  * SUN_draw
  420.  *
  421.  *    draws a line from the current graphics position to (x, y).
  422.  *
  423.  * Note: (0, 0) is defined as the top left of the window on a sun (easy
  424.  * to forget).
  425.  */
  426. SUN_draw(x, y)
  427.     int    x, y;
  428. {
  429.     if (!lineflags)    /* If thin and solid */
  430.         pw_vector(pw, vdevice.cpVx, vdevice.sizeSy - vdevice.cpVy, x, vdevice.sizeSy - y, PIX_SRC | PIX_COLOR(colour), colour);
  431.     else    /* Fat and/or dashed */
  432.         pw_line(pw, vdevice.cpVx, vdevice.sizeSy - vdevice.cpVy, x, vdevice.sizeSy - y, &brush, t, PIX_SRC | PIX_COLOR(colour));
  433.  
  434.     if (vdevice.sync)
  435.         pw_show(pw);
  436. }
  437.  
  438. /*
  439.  * SUN_getkey
  440.  *
  441.  *    grab a character from the keyboard.
  442.  */
  443. int
  444. SUN_getkey()
  445. {
  446.     Event    event;
  447.  
  448.     pw_show(pw);
  449.  
  450.     do {
  451.         while ((input_readevent(wfd, &event) < 0) && (errno == EWOULDBLOCK))
  452.         ;    /* Nothing to read - wait for something */
  453.         
  454.     } while (!event_is_ascii(&event));    /* Wait for a key press */
  455.  
  456.     return(event_action(&event));
  457. }
  458.  
  459. /*
  460.  * SUN_checkkey
  461.  *
  462.  *    Check if a keyboard key has been hit. If so return it.
  463.  */
  464. static Event *saved_event;
  465.  
  466. int
  467. SUN_checkkey()
  468. {
  469.     static Event    event;
  470.     
  471.     if(saved_event == &event)
  472.         saved_event = NULL;
  473.  
  474.     if (saved_event && event_is_ascii(saved_event)) {
  475.         Event *tmp = saved_event;
  476.  
  477.         saved_event = NULL;
  478.         return(event_action(tmp));
  479.     }
  480.  
  481.     saved_event = NULL;
  482.  
  483.     if (input_readevent(wfd, &event) < 0) {
  484.         if (errno == EWOULDBLOCK) {
  485.             return(0);
  486.         } else {
  487.             perror("SUN_checkkey, input_readevent");
  488.             exit(1);
  489.         }
  490.     } else if (event_is_ascii(&event))
  491.         return(event_action(&event));
  492.     else
  493.         saved_event = &event;
  494.  
  495.     return(0);
  496. }
  497.         
  498.  
  499. /*
  500.  * SUN_locator
  501.  *
  502.  *    return the window location of the cursor, plus which mouse button,
  503.  * if any, is been pressed.
  504.  */
  505. int
  506. SUN_locator(wx, wy)
  507.     int    *wx, *wy;
  508. {
  509.     int    but;
  510.     static Event    event;
  511.     
  512.     if (vdevice.sync)
  513.         pw_show(pw);
  514.  
  515.     but = 0;
  516.  
  517.     *wx = win_get_vuid_value(wfd, LOC_X_ABSOLUTE);
  518.     *wy = (int)vdevice.sizeSy - win_get_vuid_value(wfd, LOC_Y_ABSOLUTE);
  519.  
  520.     /* This used to work under 4.0 but not longer ..... Maybe
  521.      * SUN don't want us to use sunview anymore?
  522.      */
  523.     if (win_get_vuid_value(wfd, BUT(1)))
  524.         but |= 1;
  525.  
  526.     if (win_get_vuid_value(wfd, BUT(2)))
  527.         but |= 2;
  528.  
  529.     if (win_get_vuid_value(wfd, BUT(3)))
  530.         but |= 3;
  531.  
  532.     
  533.     if (use_sunview_canvas)
  534.         return(but);
  535.  
  536.     if (saved_event == &event) /*Don't Re-use a previously rejected event*/
  537.         saved_event = NULL;
  538.  
  539.     if (saved_event && event_is_button(saved_event) && event_is_down(saved_event)) {
  540.         if (event_action(saved_event) == MS_LEFT)
  541.             but |= 1;
  542.         if (event_action(saved_event) == MS_MIDDLE)
  543.             but |= 2;
  544.         if (event_action(saved_event) == MS_RIGHT)
  545.             but |= 4;
  546.  
  547.         saved_event = NULL;
  548.         return(but);
  549.     }
  550.  
  551.  
  552.     if (input_readevent(wfd, &event) < 0) {
  553.         if (errno == EWOULDBLOCK) {
  554.             return(0);
  555.         } else {
  556.             perror("SUN_locator, input_readevent");
  557.             exit(1);
  558.         }
  559.     } else if (event_is_button(&event) && event_is_down(&event)) {
  560.             if (event_action(&event) == MS_LEFT)
  561.                 but |= 1;
  562.             if (event_action(&event) == MS_MIDDLE)
  563.                 but |= 2;
  564.             if (event_action(&event) == MS_RIGHT)
  565.                 but |= 4;
  566.     } else
  567.         saved_event = &event;
  568.  
  569.     return(but);
  570. }
  571.  
  572. #ifdef VOGLE
  573. /*
  574.  * SUN_clear
  575.  *
  576.  *    Clear the screen to current colour
  577.  */
  578. SUN_clear()
  579. {
  580.     pw_writebackground(pw, 0, 0, w, h, PIX_SRC | PIX_COLOR(colour) | PIX_DONTCLIP);
  581.  
  582.     if (vdevice.sync)
  583.         pw_show(pw);
  584. }
  585.  
  586. #else
  587.  
  588. /*
  589.  * SUN_clear
  590.  *
  591.  *    Clear the viewport to current colour
  592.  */
  593. SUN_clear()
  594. {
  595.         unsigned int    vw = vdevice.maxVx - vdevice.minVx;
  596.         unsigned int    vh = vdevice.maxVy - vdevice.minVy;
  597.  
  598.     pw_writebackground(pw, 
  599.         vdevice.minVx, vdevice.sizeSy - vdevice.maxVy, 
  600.         vw, vh,
  601.         PIX_SRC | PIX_COLOR(colour) | PIX_DONTCLIP
  602.     );
  603.  
  604.     if (vdevice.sync)
  605.         pw_show(pw);
  606. }
  607.  
  608. #endif
  609.  
  610. /*
  611.  * SUN_color
  612.  *
  613.  *    set the current drawing color index.
  614.  */
  615. SUN_color(ind)
  616.         int    ind;
  617. {
  618.     colour = ind;
  619. }
  620.  
  621. /*
  622.  * SUN_mapcolor
  623.  *
  624.  *    change index i in the color map to the appropriate r, g, b, value.
  625.  */
  626. SUN_mapcolor(i, r, g, b)
  627.     int    i;
  628.     int    r, g, b;
  629. {
  630.     int    j;
  631.  
  632.     if (i >= 255 || vdevice.depth == 1)
  633.         return(-1);
  634.  
  635.     if (i >= colnum)
  636.         colnum = i;
  637.  
  638.     red[i] = r;
  639.     green[i] = g;
  640.     blue[i] = b;
  641.  
  642.     red[255] = (u_char)~red[0];
  643.     green[255] = (u_char)~green[0];
  644.     blue[255] = (u_char)~blue[0];
  645.  
  646.     pw_putcolormap(pw, 0, colnum, red, green, blue);
  647. #ifdef BASE_COL_SET
  648.     pw_putcolormap(pw0, 0, colnum, red, green, blue);
  649. #endif
  650. }
  651.     
  652. /*
  653.  * SUN_font
  654.  *
  655.  *   Set up a hardware font. Return 1 on success 0 otherwise.
  656.  *
  657.  */
  658. SUN_font(fontfile)
  659.         char    *fontfile;
  660. {
  661.     char    name[BUFSIZ];
  662.  
  663.     if (font_id != (Pixfont *)NULL)
  664.         pf_close(font_id);
  665.  
  666.     if ((font_id = pf_open(fontfile)) == NULL)
  667.         if (*fontfile != '/') {
  668.             strcpy(name, STDFONTDIR);
  669.             strcat(name, fontfile);
  670.             if ((font_id = pf_open(name)) == NULL)
  671.                 return(0);
  672.         } else 
  673.             return(0);
  674.  
  675.     vdevice.hheight = font_id->pf_defaultsize.y;
  676.     vdevice.hwidth = font_id->pf_defaultsize.x;
  677.  
  678.     return(1);
  679. }
  680.  
  681. /* 
  682.  * SUN_char
  683.  *
  684.  *     outputs one char - is more complicated for other devices
  685.  */
  686. SUN_char(c)
  687.     char    c;
  688. {
  689.     char    *s = " ";
  690.  
  691.     s[0] = c;
  692.     pw_ttext(pw, vdevice.cpVx, (int)(vdevice.sizeSy - vdevice.cpVy), PIX_SRC | PIX_COLOR(colour), font_id, s);
  693.  
  694.     if (vdevice.sync)
  695.         pw_show(pw);
  696. }
  697.  
  698. /*
  699.  * SUN_string
  700.  *
  701.  *    Display a string at the current drawing position.
  702.  */
  703. SUN_string(s)
  704.         char    s[];
  705. {
  706.     pw_ttext(pw, vdevice.cpVx, (int)(vdevice.sizeSy - vdevice.cpVy), PIX_SRC | PIX_COLOR(colour), font_id, s);
  707.  
  708.     if (vdevice.sync)
  709.         pw_show(pw);
  710. }
  711.  
  712. /*
  713.  * SUN_fill
  714.  *
  715.  *    fill a polygon
  716.  */
  717. SUN_fill(n, x, y)
  718.     int    n, x[], y[];
  719. {
  720.     struct    pr_pos    vlist[128];
  721.     int    i, npnts;
  722.  
  723.     if (n > 128)
  724.         verror("vogle: more than 128 points in a polygon");
  725.  
  726.     npnts = n;
  727.  
  728.     for (i = 0; i < n; i++) {
  729.         vlist[i].x = x[i];
  730.         vlist[i].y = vdevice.sizeSy - y[i];
  731.     }
  732.  
  733.     pw_polygon_2(pw, 0, 0, 1, &npnts, vlist, PIX_SRC | PIX_COLOR(colour) | PIX_DONTCLIP, (Pixwin *)NULL, 0, 0);
  734.  
  735.     vdevice.cpVx = x[n-1];
  736.     vdevice.cpVy = y[n-1];
  737.  
  738. /*
  739.     if (vdevice.sync)
  740.         pw_show(pw);
  741. */
  742. }
  743.  
  744. /*
  745.  * SUN_backb
  746.  *
  747.  *    swap to memory only drawing (backbuffer) - a little slow but it
  748.  * works on everything. 
  749.  */
  750. SUN_backb()
  751. {
  752.     /*
  753.      * Batching is already on....
  754.      */
  755.     return(0);
  756. }
  757.  
  758. /*
  759.  * SUN_swapb
  760.  *
  761.  *    swap the front and back buffers.
  762.  */
  763. SUN_swapb()
  764. {
  765.     if (vdevice.inbackbuffer)
  766.         pw_show(pw);
  767.  
  768.     return(0);
  769. }
  770.  
  771. /*
  772.  * SUN_frontb
  773.  *
  774.  *    draw in the front buffer
  775.  */
  776. SUN_frontb()
  777. {
  778.     /*
  779.      * Make it visible anyway....
  780.      */
  781.     pw_show(pw);
  782. }
  783.  
  784. /*
  785.  * SUN_sync
  786.  *
  787.  *    Syncronise the display with what we thing has been output
  788.  */
  789. SUN_sync()
  790. {
  791.     pw_show(pw);
  792. }
  793.  
  794. /*
  795.  * SUN_setls
  796.  *
  797.  *    Set the line style....
  798.  */
  799. SUN_setls(lss)
  800.     int    lss;
  801. {
  802.     
  803.     unsigned ls = lss;
  804.     static short    dashes[17];
  805.  
  806.     int    i, n, a, b, offset;
  807.  
  808.     if (ls == 0xffff) {
  809.         lineflags &= ~DASHED;
  810.         t = (Pr_texture *)NULL;
  811.         return;
  812.     }
  813.  
  814.     lineflags |= DASHED;
  815.  
  816.     for (i = 0; i < 16; i++)
  817.         dashes[i] = 0;
  818.  
  819.     for (i = 0; i < 16; i++)    /* Over 16 bits */
  820.         if ((ls & (1 << i)))
  821.             break;
  822.  
  823.     offset = i;
  824.  
  825. #define    ON    1
  826. #define    OFF    0
  827.         
  828.     a = b = OFF;
  829.     if (ls & (1 << 0))
  830.         a = b = ON;
  831.  
  832.     n = 0;
  833.     for (i = 0; i < 16; i++) {    /* Over 16 bits */
  834.         if (ls & (1 << i))
  835.             a = ON;
  836.         else
  837.             a = OFF;
  838.  
  839.         if (a != b) {
  840.             b = a;
  841.             n++;
  842.         }
  843.         dashes[n]++;
  844.     }
  845.     n++;
  846.     dashes[n] = 0;
  847.  
  848.     tex.pattern = &dashes[0];
  849.     tex.offset = offset;
  850.     t = &tex;
  851. }
  852.  
  853. #ifndef VOGLE
  854. /*
  855.  * SUN_setlw
  856.  *
  857.  *    Set the line style....
  858.  */
  859. SUN_setlw(lw)
  860.     int    lw;
  861. {
  862.     if (lw > 1) {
  863.         lineflags |= FATLINES;
  864.         brush.width = lw;
  865.     } else
  866.         lineflags &= ~FATLINES;
  867. }
  868.  
  869. #else
  870. /*
  871.  * SUN_setlw
  872.  *
  873.  *    Set the line style....
  874.  */
  875. SUN_setlw(lw)
  876.     int    lw;
  877. {
  878.     if (lw == 1) {
  879.         lineflags |= FATLINES;
  880.         brush.width = 3;
  881.     } else {
  882.         lineflags &= ~FATLINES;
  883.         brush.width = 1;
  884.     }
  885. }
  886.  
  887. #endif
  888.  
  889. /*
  890.  * the device entry
  891.  */
  892. static DevEntry sundev = {
  893.     "sun",
  894.     "screen.b.16",
  895.     "screen.b.12",
  896.     SUN_backb,
  897.     SUN_char,
  898.     SUN_checkkey,
  899.     SUN_clear,
  900.     SUN_color,
  901.     SUN_draw,
  902.     SUN_exit,
  903.     SUN_fill,
  904.     SUN_font,
  905.     SUN_frontb,
  906.     SUN_getkey,
  907.     SUN_init,
  908.     SUN_locator,
  909.     SUN_mapcolor,
  910. #ifndef VOGLE
  911.     SUN_setls,
  912. #endif
  913.     SUN_setlw,
  914.     SUN_string,
  915.     SUN_swapb,
  916.     SUN_sync
  917. };
  918.  
  919. /*
  920.  * _SUN_devcpy
  921.  *
  922.  *    copy the sun device into vdevice.dev.
  923.  */
  924. _SUN_devcpy()
  925. {
  926.     vdevice.dev = sundev;
  927. }
  928.