home *** CD-ROM | disk | FTP | other *** search
/ gondwana.ecr.mu.oz.au/pub/ / Graphics.tar / Graphics / voglw.zip / drivers.c < prev    next >
C/C++ Source or Header  |  1997-02-13  |  14KB  |  853 lines

  1. #include <stdio.h>
  2. #include "vogl.h"
  3. #include "vodevice.h"
  4.  
  5. extern char    *getenv();
  6.  
  7. struct vdev    vdevice;
  8.  
  9. static FILE    *fp = stdout;
  10.  
  11. static int    allocated = 0;
  12.  
  13. void        gexit();
  14.  
  15. /* device-independent function routines */
  16.  
  17. /*
  18.  * voutput
  19.  *
  20.  *    redirect output - only for postscript, hpgl (this is not a feature)
  21.  */
  22. void
  23. voutput(path)
  24.     char    *path;
  25. {
  26.     char    buf[128];
  27.  
  28.     if ((fp = fopen(path, "w")) == (FILE *)NULL) {
  29.         sprintf(buf, "voutput: couldn't open %s", path);
  30.         verror(buf);
  31.     }
  32. }
  33.  
  34. /*
  35.  * _voutfile
  36.  *
  37.  *    return a pointer to the current output file - designed for internal
  38.  * use only.
  39.  */
  40. FILE *
  41. _voutfile()
  42. {
  43.     return(fp);
  44. }
  45.  
  46. /*
  47.  * verror
  48.  *
  49.  *    print an error on the graphics device, and then exit. Only called
  50.  * for fatal errors. We assume that stderr is always there.
  51.  *
  52.  */
  53. void
  54. verror(str)
  55.     char    *str;
  56. {
  57. #ifdef MSWIN
  58.     mswin_verror(str);
  59.     if (vdevice.initialised)
  60.         gexit();
  61. #else
  62.     if (vdevice.initialised)
  63.         gexit();
  64.  
  65.     fprintf(stderr, "%s\n", str);
  66. #endif
  67.     exit(1);
  68. }
  69.  
  70. void
  71. viniterror(str)
  72.     char    *str;
  73. {
  74.     fprintf(stderr, "%s: vogl not initialised\n", str);
  75.     exit(1);
  76. }
  77.  
  78. /*
  79.  * gexit
  80.  *
  81.  *    exit the vogl/vogle system
  82.  *
  83.  */
  84. void
  85. gexit()
  86. {
  87.     if (!vdevice.initialised)
  88.         verror("gexit: vogl not initialised");
  89.  
  90.     (*vdevice.dev.Vexit)();
  91.  
  92.     vdevice.devname = (char *)NULL;
  93.     vdevice.initialised = 0;
  94.     fp = stdout;
  95. }
  96.  
  97. /*
  98.  * getdevice
  99.  *
  100.  *    get the appropriate device table structure
  101.  */
  102. static void
  103. getdevice(device)
  104.     char    *device;
  105. {
  106.     char    buf[100];
  107. #ifdef SUN
  108.     if (strncmp(device, "sun", 3) == 0)
  109.         _SUN_devcpy();
  110.     else
  111. #endif
  112. #ifdef PIXRECT
  113.     if (strncmp(device, "pixrect", 7) == 0)
  114.         _PIXRECT_devcpy();
  115.     else
  116. #endif
  117. #ifdef X11
  118.     if (strncmp(device, "X11", 3) == 0)
  119.         _X11_devcpy();
  120.     else
  121. #endif
  122. #ifdef DECX11
  123.     if (strncmp(device, "decX11", 6) == 0)
  124.         _DECX11_devcpy();
  125.     else
  126. #endif
  127. #ifdef NeXT
  128.     if (strncmp(device, "NeXT", 4) == 0)
  129.         _NeXT_devcpy();
  130.     else
  131. #endif
  132. #ifdef POSTSCRIPT
  133.     if (strncmp(device, "postscript", 10) == 0) {
  134.         _PS_devcpy();
  135.     } else
  136.     if (strncmp(device, "ppostscript", 11) == 0) {
  137.         _PSP_devcpy();
  138.     } else
  139.     if (strncmp(device, "cps", 3) == 0) {
  140.         _CPS_devcpy();
  141.     } else
  142.     if (strncmp(device, "pcps", 4) == 0) {
  143.         _PCPS_devcpy();
  144.     } else
  145. #endif
  146. #ifdef HPGL
  147.     if (strncmp(device, "hpgla1", 6) == 0)
  148.         _HPGL_A1_devcpy();
  149.     else if (strncmp(device, "hpgla3", 6) == 0)
  150.         _HPGL_A3_devcpy();
  151.     else if (strncmp(device, "hpgla4", 6) == 0)
  152.         _HPGL_A4_devcpy();
  153.     else if (strncmp(device, "hpgla2", 6) == 0 || strncmp(device, "hpgl", 4) == 0)
  154.         _HPGL_A2_devcpy();
  155.     else
  156. #endif
  157. #ifdef DXY
  158.     if (strncmp(device, "dxy", 3) == 0)
  159.         _DXY_devcpy();
  160.     else
  161. #endif
  162. #ifdef TEK
  163.     if (strncmp(device, "tek", 3) == 0)
  164.         _TEK_devcpy();
  165.     else
  166. #endif
  167. #ifdef GRX
  168.     if (strncmp(device, "grx", 3) == 0)
  169.         _grx_devcpy();
  170.     else
  171. #endif
  172. #ifdef HERCULES
  173.     if (strncmp(device, "hercules", 8) == 0)
  174.         _hgc_devcpy();
  175.     else
  176. #endif
  177. #ifdef MSWIN
  178.     if (strncmp(device, "mswin", 5) == 0)
  179.         _mswin_devcpy();
  180.     else
  181. #endif
  182. #ifdef CGA
  183.     if (strncmp(device, "cga", 3) == 0)
  184.         _cga_devcpy();
  185.     else
  186. #endif
  187. #ifdef EGA
  188.     if (strncmp(device, "ega", 3) == 0)
  189.         _ega_devcpy();
  190.     else
  191. #endif
  192. #ifdef VGA
  193.     if (strncmp(device, "vga", 3) == 0)
  194.         _vga_devcpy();
  195.     else
  196. #endif
  197. #ifdef SIGMA
  198.     if (strncmp(device, "sigma", 5) == 0)
  199.         _sigma_devcpy();
  200.     else
  201. #endif
  202.     {
  203.         if (*device == 0)
  204.             sprintf(buf, "vogl: expected the enviroment variable VDEVICE to be set to the desired device.\n");
  205.         else
  206.             sprintf(buf, "vogl: %s is an invalid device type\n", device);
  207. #ifdef MSWIN
  208.         mswin_verror(buf);
  209. #else
  210.         fputs(buf, stderr);
  211.         fprintf(stderr, "The devices compiled into this library are:\n");
  212. #endif
  213. #ifdef SUN
  214.         fprintf(stderr, "sun\n");
  215. #endif
  216. #ifdef PIXRECT
  217.         fprintf(stderr, "pixrect\n");
  218. #endif
  219. #ifdef X11
  220.         fprintf(stderr, "X11\n");
  221. #endif
  222. #ifdef DECX11
  223.         fprintf(stderr, "decX11\n");
  224. #endif
  225. #ifdef NeXT
  226.         fprintf(stderr, "NeXT\n");
  227. #endif
  228. #ifdef POSTSCRIPT
  229.         fprintf(stderr, "postscript\n");
  230.         fprintf(stderr, "ppostscript\n");
  231.         fprintf(stderr, "cps\n");
  232.         fprintf(stderr, "pcps\n");
  233. #endif
  234. #ifdef HPGL
  235.         fprintf(stderr, "hpgla1\n");
  236.         fprintf(stderr, "hpgla2 (or hpgl)\n");
  237.         fprintf(stderr, "hpgla3\n");
  238.         fprintf(stderr, "hpgla4\n");
  239. #endif
  240. #ifdef DXY
  241.         fprintf(stderr, "dxy\n");
  242. #endif
  243. #ifdef TEK
  244.         fprintf(stderr, "tek\n");
  245. #endif
  246. #ifdef HERCULES
  247.         fprintf(stderr, "hercules\n");
  248. #endif
  249. #ifdef CGA
  250.         fprintf(stderr, "cga\n");
  251. #endif
  252. #ifdef EGA
  253.         fprintf(stderr, "ega\n");
  254. #endif
  255. #ifdef VGA
  256.         fprintf(stderr, "vga\n");
  257. #endif
  258. #ifdef SIGMA
  259.         fprintf(stderr, "sigma\n");
  260. #endif
  261. #ifdef GRX
  262.         fprintf(stderr, "grx\n");
  263. #endif
  264.         exit(1);
  265.     }
  266. }
  267.  
  268. /*
  269.  * vinit
  270.  *
  271.  *     Just set the device name. ginit and winopen are basically
  272.  * the same as the VOGLE the vinit function.
  273.  *
  274.  */
  275. void
  276. vinit(device)
  277.     char    *device;
  278. {
  279.     vdevice.devname = device;
  280. }
  281.  
  282. /*
  283.  * winopen
  284.  *
  285.  *    use the more modern winopen call (this really calls ginit),
  286.  * we use the title if we can
  287.  */
  288. long
  289. winopen(title)
  290.     char    *title;
  291. {
  292.     vdevice.wintitle = title;
  293.  
  294.     ginit();
  295.  
  296.     return(1L);
  297. }
  298.  
  299. /*
  300.  * ginit
  301.  *
  302.  *    by default we check the environment variable, if nothing
  303.  * is set we use the value passed to us by the vinit call.
  304.  */
  305. void
  306. ginit()
  307. {
  308.     char    *dev;
  309.     int    i;
  310.  
  311.     if (vdevice.devname == (char *)NULL) {
  312.         if ((dev = getenv("VDEVICE")) == (char *)NULL)
  313.             getdevice("");
  314.         else
  315.             getdevice(dev);
  316.     } else 
  317.         getdevice(vdevice.devname);
  318.  
  319.     if (vdevice.initialised)
  320.         gexit();
  321.  
  322.     if (!allocated) {
  323.         allocated = 1;
  324.         deflinestyle(0, 0xffff);
  325.         vdevice.transmat = (Mstack *)vallocate(sizeof(Mstack));
  326.         vdevice.transmat->back = (Mstack *)NULL;
  327.         vdevice.attr = (Astack *)vallocate(sizeof(Astack));
  328.         vdevice.attr->back = (Astack *)NULL;
  329.         vdevice.viewport = (Vstack *)vallocate(sizeof(Vstack));
  330.         vdevice.viewport->back = (Vstack *)NULL;
  331.         vdevice.bases = (Matrix *)vallocate(sizeof(Matrix) * 10);
  332.         vdevice.enabled = (char *)vallocate(MAXDEVTABSIZE);
  333.     }
  334.  
  335.     for (i = 0; i < MAXDEVTABSIZE; i++)
  336.         vdevice.enabled[i] = 0;
  337.  
  338.     /* NOTE:
  339.      * There is a slight behaviour change from previous versions of VOGL
  340.      * if you define FIRST_REDRAW... you always get a REDRAW event as the
  341.      * first event in the queue.
  342.      */
  343. #define FIRST_REDRAW 1
  344. #ifdef FIRST_REDRAW
  345.     /*
  346.      * Arrange for a REDRAW to be the first thing in the queue...
  347.          * (winopen always enters a REDRAW in the queue on a real SGI).
  348.      */
  349.     vdevice.alreadyread = TRUE;
  350.     vdevice.data = 0;
  351.     vdevice.devno = REDRAW;
  352.     vdevice.enabled[REDRAW / 8] |= (1 << (REDRAW & 0x7));
  353. #else
  354.     vdevice.alreadyread = FALSE;
  355.     vdevice.data = 0;
  356.     vdevice.devno = 0;
  357. #endif
  358.     vdevice.kbdmode = vdevice.mouseevents = vdevice.kbdevents = 0;
  359.  
  360.     vdevice.concave = 0;
  361.     vdevice.clipoff = 0;
  362.     vdevice.sync = 1;
  363.     vdevice.cpW[V_W] = 1.0;            /* never changes */
  364.  
  365.     vdevice.maxfontnum = 2;
  366.  
  367.     vdevice.attr->a.lw = 1;
  368.     vdevice.attr->a.fontnum = 0;
  369.     vdevice.attr->a.mode = 0;
  370.     vdevice.attr->a.backface = 0;
  371.  
  372.     if ((*vdevice.dev.Vinit)()) {
  373.         vdevice.initialised = 1;
  374.  
  375.         vdevice.inobject = 0;
  376.         vdevice.inpolygon = 0;
  377.  
  378.         viewport((Screencoord)0, (Screencoord)vdevice.sizeSx - 1,
  379.             (Screencoord)0, (Screencoord)vdevice.sizeSy - 1);
  380.  
  381.         ortho2(0.0, (Coord)(vdevice.sizeSx - 1), 0.0, (Coord)(vdevice.sizeSy - 1));
  382.  
  383.         move(0.0, 0.0, 0.0);
  384.  
  385.         font(0);    /* set up default font */
  386.  
  387.     } else {
  388.         fprintf(stderr, "vogl: error while setting up device\n");
  389.         exit(1);
  390.     }
  391.  
  392.     setlinestyle(0);
  393. }
  394.  
  395. /*
  396.  * gconfig
  397.  *
  398.  *    thankfully a noop.
  399.  */
  400. void
  401. gconfig()
  402. {
  403. }
  404.  
  405. /*
  406.  * Hacky new device changing routines...
  407.  */
  408. #define    DEVSTACK    8
  409. static    VDevice    vdevstk[DEVSTACK];
  410. static    int    vdevindx = 0;
  411.  
  412. void
  413. pushdev(device)
  414.     char    *device;
  415. {
  416.     /*
  417.      * Save the old vdevice structure
  418.      */
  419.     pushattributes();
  420.     pushviewport();
  421.  
  422.     if (vdevindx < DEVSTACK)
  423.         vdevstk[vdevindx++] = vdevice;
  424.     else
  425.         verror("vogl: pushdev: Device stack overflow");
  426.  
  427.     vdevice.initialised = 0;
  428.  
  429.     getdev(device);
  430.  
  431.     (*vdevice.dev.Vinit)();
  432.  
  433.     vdevice.initialised = 1;
  434.  
  435.     popviewport();
  436.     popattributes();
  437. }
  438.  
  439. void
  440. popdev()
  441. {
  442.     /*
  443.      * Restore the old vdevice structure
  444.      */
  445.     pushattributes();
  446.     pushviewport();
  447.  
  448.     (*vdevice.dev.Vexit)();
  449.     if (vdevindx > 0)
  450.         vdevice = vdevstk[--vdevindx];
  451.     else
  452.         verror("vogl: popdev: Device stack underflow");
  453.  
  454.     popviewport();
  455.     popattributes();
  456. }
  457. /*
  458.  * vnewdev
  459.  *
  460.  * reinitialize vogl to use a new device but don't change any
  461.  * global attributes like the window and viewport settings.
  462.  */
  463. void
  464. vnewdev(device)
  465.     char    *device;
  466. {
  467.     if (!vdevice.initialised)
  468.         verror("vnewdev: vogl not initialised\n");
  469.  
  470.     pushviewport();    
  471.  
  472.     (*vdevice.dev.Vexit)();
  473.  
  474.     vdevice.initialised = 0;
  475.  
  476.     getdevice(device);
  477.  
  478.     (*vdevice.dev.Vinit)();
  479.  
  480.     vdevice.initialised = 1;
  481.  
  482.     /*
  483.      * Need to update font for this device...
  484.      */
  485.     font(vdevice.attr->a.fontnum);
  486.  
  487.     popviewport();
  488. }
  489.  
  490. /*
  491.  * vgetdev
  492.  *
  493.  *    Returns the name of the current vogl device 
  494.  *    in the buffer buf. Also returns a pointer to
  495.  *    the start of buf.
  496.  */
  497. char    *
  498. vgetdev(buf)
  499.     char    *buf;
  500. {
  501.     /*
  502.      * Note no exit if not initialized here - so that gexit
  503.      * can be called before printing the name.
  504.      */
  505.     if (vdevice.dev.devname)
  506.         strcpy(buf, vdevice.dev.devname);
  507.     else
  508.         strcpy(buf, "(no device)");
  509.  
  510.     return(&buf[0]);
  511. }
  512.  
  513. /*
  514.  * getvaluator
  515.  *
  516.  *    similar to the VOGLE locator only it returns either x (MOUSEX) or y (MOUSEY).
  517.  */
  518. long
  519. getvaluator(dev)
  520.     Device    dev;
  521. {
  522.     int    a, b, c;
  523.  
  524.     if (!vdevice.initialised)
  525.         verror("getvaluator: vogl not initialised");
  526.  
  527.     c = (*vdevice.dev.Vlocator)(&a, &b);
  528.  
  529.     if (c != -1) {
  530.         if (dev == MOUSEX)
  531.             return((long)a);
  532.         else 
  533.             return((long)b);
  534.     }
  535.  
  536.     return(-1);
  537. }
  538.  
  539. /*
  540.  * getbutton
  541.  *
  542.  *    returns the up (or down) state of a button. 1 means down, 0 up,
  543.  * -1 invalid.
  544.  */
  545. Boolean
  546. getbutton(dev)
  547.     Device    dev;
  548. {
  549.     int    a, b, c;
  550.  
  551.     if (dev < 256) {
  552.         c = (*vdevice.dev.Vcheckkey)();
  553.         if (c >= 'a' && c <= 'z')
  554.             c = c - 'a' + 'A';
  555.         if (c == dev)
  556.             return(1);
  557.         return(0);
  558.     } else if (dev < 261) {
  559.         c = (*vdevice.dev.Vlocator)(&a, &b);
  560.         if (c & 0x01 && dev == MOUSE3)
  561.             return(1);
  562.         if (c & 0x02 && dev == MOUSE2)
  563.             return(1);
  564.         if (c & 0x04 && dev == MOUSE1)
  565.             return(1);
  566.         return(0);
  567.     }
  568.  
  569.     return(-1);
  570. }
  571.  
  572. /*
  573.  * Get the values of the valuators in devs and put them into vals
  574.  */
  575. void 
  576. getdev(n, devs, vals)
  577.     long n;
  578.     Device devs[];
  579.     short vals[];
  580. {
  581.     int    i;
  582.  
  583.     for( i=0; i < n; i++)
  584.         vals[i] = (short)getvaluator(devs[i]);
  585. }
  586.  
  587.  
  588. /*
  589.  * clear
  590.  *
  591.  *    clears the screen to the current colour, excepting devices
  592.  * like a laser printer where it flushes the page.
  593.  *
  594.  */
  595. void
  596. clear()
  597. {
  598.     Token    *tok;
  599.  
  600.     if (!vdevice.initialised)
  601.         verror("clear: vogl not initialised");
  602.  
  603.     if (vdevice.inobject) {
  604.         tok = newtokens(1);
  605.         tok->i = CLEAR;
  606.  
  607.         return;
  608.     }
  609.  
  610.     (*vdevice.dev.Vclear)();
  611. }
  612.  
  613. /*
  614.  * colorf
  615.  *
  616.  *    set the current colour to colour index given by
  617.  * the rounded value of f.
  618.  *
  619.  */
  620. void
  621. colorf(f)
  622.     float    f;
  623. {
  624.     color((int)(f + 0.5));
  625. }
  626.  
  627. /*
  628.  * color
  629.  *
  630.  *    set the current colour to colour index number i.
  631.  *
  632.  */
  633. void
  634. color(i)
  635.     int    i;
  636. {
  637.     Token    *tok;
  638.  
  639.     if (!vdevice.initialised)
  640.         verror("color: vogl not initialised");
  641.  
  642.     if (vdevice.inobject) {
  643.         tok = newtokens(2);
  644.  
  645.         tok[0].i = COLOR;
  646.         tok[1].i = i;
  647.         return;
  648.     }
  649.  
  650.     vdevice.attr->a.color = i;
  651.     (*vdevice.dev.Vcolor)(i);
  652. }
  653.  
  654. long
  655. getcolor()
  656. {
  657.     return((long)vdevice.attr->a.color);
  658. }
  659.  
  660. /*
  661.  * mapcolor
  662.  *
  663.  *    set the color of index i.
  664.  */
  665. void
  666. mapcolor(i, r, g, b)
  667.     Colorindex    i;
  668.     short        r, g, b;
  669. {
  670.     Token    *tok;
  671.  
  672.     if (!vdevice.initialised)
  673.         verror("mapcolor: vogl not initialised");
  674.  
  675.     if (vdevice.inobject) {
  676.         tok = newtokens(5);
  677.  
  678.         tok[0].i = MAPCOLOR;
  679.         tok[1].i = i;
  680.         tok[2].i = r;
  681.         tok[3].i = g;
  682.         tok[4].i = b;
  683.  
  684.         return;
  685.     }
  686.  
  687.     (*vdevice.dev.Vmapcolor)(i, r, g, b);
  688. }
  689.  
  690. /*
  691.  * getplanes
  692.  *
  693.  *    Returns the number if bit planes on a device.
  694.  */
  695. long
  696. getplanes()
  697. {
  698.     if (!vdevice.initialised)
  699.         verror("getdepth: vogl not initialised\n");
  700.  
  701.     return((long)vdevice.depth);
  702. }
  703.  
  704. /*
  705.  * reshapeviewport
  706.  *
  707.  *    Simply sets the viewport to the size of the current window
  708.  */
  709. void
  710. reshapeviewport()
  711. {
  712.     viewport(0, vdevice.sizeSx - 1, 0, vdevice.sizeSy - 1);
  713. }
  714.  
  715. /*
  716.  * winconstraints
  717.  *        - does nothing
  718.  */
  719. void
  720. winconstraints()
  721. {
  722. }
  723.  
  724. /*
  725.  * keepaspect
  726.  *        - does nothing
  727.  */
  728. void
  729. keepaspect()
  730. {
  731. }
  732.  
  733. /*
  734.  * shademodel
  735.  *        - does nothing
  736.  */
  737. void
  738. shademodel(model)
  739.     long    model;
  740. {
  741. }
  742.  
  743. /*
  744.  * getgdesc
  745.  *
  746.  *    Inquire about some stuff....
  747.  */
  748. long
  749. getgdesc(inq)
  750.     long    inq;
  751. {    
  752.     /*
  753.      * How can we know before the device is inited??
  754.      */
  755.  
  756.     switch (inq) {
  757.     case GD_XPMAX:
  758.         if (vdevice.initialised)
  759.             return((long)vdevice.sizeSx);
  760.         else
  761.             return(500L);    /* A bullshit number */
  762.     case GD_YPMAX:
  763.         if (vdevice.initialised)
  764.             return((long)vdevice.sizeSy);
  765.         else
  766.             return(500L);
  767.     default:
  768.         return(-1L);
  769.     }
  770. }
  771.  
  772. /*
  773.  * foregound
  774.  *         Dummy - does nothing.
  775.  */
  776. void
  777. foreground()
  778. {
  779. }
  780.  
  781. /*
  782.  * vsetflush
  783.  *
  784.  * Controls flushing of the display - we can get considerable
  785.  * Speed up's under X11 using this...
  786.  */
  787. void
  788. vsetflush(yn)
  789.     int    yn;
  790. {
  791.     vdevice.sync = yn;
  792. }
  793.  
  794. /*
  795.  * vflush
  796.  *
  797.  * Explicitly call the device flushing routine...
  798.  * This is enabled for object so that you can force an update
  799.  * in the middle of an object, as objects have flushing off
  800.  * while they are drawn anyway.
  801.  */
  802. void
  803. vflush()
  804. {
  805.     Token    *tok;
  806.  
  807.     if (!vdevice.initialised)
  808.         verror("vflush: vogl not initialised");
  809.  
  810.     if (vdevice.inobject) {
  811.         tok = newtokens(1);
  812.         tok->i = VFLUSH;
  813.  
  814.         return;
  815.     }
  816.  
  817.     (*vdevice.dev.Vsync)();
  818. }
  819.  
  820.  
  821. /* 
  822.  * getorigin
  823.  *
  824.  *    Returns the origin of the window. This is a dummy.
  825.  */
  826. void
  827. getorigin(x, y)
  828.     long    *x, *y;
  829. {
  830.     *x = *y = 0;
  831. }
  832.  
  833. /*
  834.  * getsize
  835.  *
  836.  *    Returns the approximate size of the window (some window managers
  837.  *    stuff around with your borders).
  838.  */
  839. void
  840. getsize(x, y)
  841.     long    *x, *y;
  842. {
  843.     *x = (long)vdevice.sizeSx;
  844.     *y = (long)vdevice.sizeSy;
  845. }
  846.  
  847. winattach()
  848. {}
  849.  
  850. winset()
  851. {}
  852.  
  853.