home *** CD-ROM | disk | FTP | other *** search
/ gondwana.ecr.mu.oz.au/pub/ / Graphics.tar / Graphics / avogl.tar.gz / avogl.tar / vogl / drivers / sun.c < prev    next >
C/C++ Source or Header  |  1992-09-22  |  14KB  |  766 lines

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