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

  1. #include <stdio.h>
  2. #include "vogle.h"
  3.  
  4. extern char    *getenv();
  5.  
  6. struct vdev    vdevice;
  7.  
  8. static FILE    *fp = NULL;
  9.  
  10. static char    _voutname[128] = "";
  11.  
  12. static int    allocated = 0;
  13.  
  14. /* device-independent function routines */
  15.  
  16. /*
  17.  * voutput
  18.  *
  19.  *    redirect output - only for postscript, hpgl (this is not a feature)
  20.  */
  21. void
  22. voutput(path)
  23.     char    *path;
  24. {
  25.     char    buf[128];
  26.     if ((fp = fopen(path, "w")) == (FILE *)NULL) {
  27.         sprintf(buf, "voutput: couldn't open %s", path);
  28.         verror(buf);
  29.     }
  30.  
  31.     /* should bitch if it's > 128 chars */
  32.  
  33.     strncpy(_voutname, path, 128);
  34. }
  35.  
  36. /*
  37.  * _voutname()
  38.  *
  39.  * return the name of the current voutput file
  40.  */
  41. char *
  42. voutname()
  43. {
  44.     return((char *)&_voutname);
  45. }
  46.  
  47. /*
  48.  * _voutfile
  49.  *
  50.  *    return a pointer to the current output file - designed for internal
  51.  * use only.
  52.  */
  53. FILE *
  54. _voutfile()
  55. {
  56.     if (fp == NULL)
  57.         fp = stdout;
  58.  
  59.     return(fp);
  60. }
  61.  
  62. /*
  63.  * verror
  64.  *
  65.  *    print an error on the graphics device, and then exit. Only called
  66.  * for fatal errors. We assume that stderr is always there.
  67.  *
  68.  */
  69. void
  70. verror(str)
  71.     char    *str;
  72. {
  73. #ifdef MSWIN
  74.     mswin_verror(str);
  75.     if (vdevice.initialised)
  76.         vexit();
  77. #else
  78. #ifdef OS2
  79.     PM_verror(str);
  80.     if (vdevice.initialised)
  81.         vexit();
  82. #else
  83.     if (vdevice.initialised)
  84.         vexit();
  85.  
  86.     fprintf(stderr, "%s\n", str);
  87. #endif
  88. #endif
  89.     exit(1);
  90. }
  91.  
  92. /*
  93.  * getdev
  94.  *
  95.  *    get the appropriate device table structure
  96.  */
  97. static void
  98. getdev(dev)
  99.     char    *dev;
  100. {
  101.     char    *device = "";
  102.     char    buf[100];
  103.  
  104.     if (dev == (char *)NULL || *dev == 0) {
  105.         if ((device = getenv("VDEVICE")) == (char *)NULL)
  106.             device = "";
  107.     } else 
  108.         device = dev;
  109.     
  110. #ifdef TG
  111.     /*
  112.      * We can have one of many device names for Tk Graphic widgets, luckily
  113.      * all tk widgets names start with a leading dot, This should keep
  114.      * them from clashing with other devices names.
  115.      */
  116.     if ((*device == '.') && (_TG_devcpy(device) >= 0))
  117.         /* NULL BODY */ ;
  118.     else
  119. #endif
  120.  
  121. #ifdef PPM
  122.         if (strncmp(device, "p3", 2) == 0)
  123.                 _P3_devcpy();
  124.         else
  125.         if (strncmp(device, "p6", 2) == 0)
  126.                 _P6_devcpy();
  127.         else
  128. #endif
  129.  
  130. #ifdef SUN
  131.     if (strncmp(device, "sun", 3) == 0)
  132.         _SUN_devcpy();
  133.     else
  134. #endif
  135. #ifdef X11
  136.     if (strncmp(device, "X11", 3) == 0)
  137.         _X11_devcpy();
  138.     else
  139. #endif
  140. #ifdef DECX11
  141.     if (strncmp(device, "decX11", 6) == 0)
  142.         _DECX11_devcpy();
  143.     else
  144. #endif
  145. #ifdef NeXT
  146.     if (strncmp(device, "NeXT", 4) == 0)
  147.         _NeXT_devcpy();
  148.     else
  149. #endif
  150. #ifdef LASERWRITER
  151.     if (strncmp(device, "laser", 5) == 0) {
  152.         _LASER_devcpy();
  153.     } else
  154. #endif
  155. #ifdef POSTSCRIPT
  156.     if (strncmp(device, "postscript", 10) == 0) {
  157.         _PS_devcpy();
  158.     } else
  159.     if (strncmp(device, "ppostscript", 11) == 0) {
  160.         _PSP_devcpy();
  161.     } else
  162.     if (strncmp(device, "cps", 3) == 0) {
  163.         _CPS_devcpy();
  164.     } else
  165.     if (strncmp(device, "pcps", 4) == 0) {
  166.         _PCPS_devcpy();
  167.     } else
  168. #endif
  169. #ifdef HPGL
  170.     if (strncmp(device, "hpgla1", 6) == 0)
  171.         _HPGL_A1_devcpy();
  172.     else if (strncmp(device, "hpgla3", 6) == 0)
  173.         _HPGL_A3_devcpy();
  174.     else if (strncmp(device, "hpgla4", 6) == 0)
  175.         _HPGL_A4_devcpy();
  176.     else if (strncmp(device, "hpgla2", 6) == 0 || strncmp(device, "hpgl", 4) == 0)
  177.         _HPGL_A2_devcpy();
  178.     else
  179. #endif
  180. #ifdef DXY
  181.     if (strncmp(device, "dxy", 3) == 0)
  182.         _DXY_devcpy();
  183.     else
  184. #endif
  185. #ifdef HPGT
  186.     if (strncmp(device, "hpgt", 4) == 0)
  187.         _HPGT_devcpy();
  188.     else
  189. #endif
  190. #ifdef GRX
  191.     if (strncmp(device, "grx", 3) == 0)
  192.         _grx_devcpy();
  193.     else
  194. #endif
  195. #ifdef TEK
  196.     if (strncmp(device, "tek", 3) == 0)
  197.         _TEK_devcpy();
  198.     else
  199. #endif
  200. #ifdef HERCULES
  201.     if (strncmp(device, "hercules", 8) == 0)
  202.         _hgc_devcpy();
  203.     else
  204. #endif
  205. #ifdef MSWIN
  206.     if (strncmp(device, "mswin", 5) == 0)
  207.         _mswin_devcpy();
  208.     else
  209. #endif
  210. #ifdef OS2
  211.     if (strncmp(device, "os2pm", 5) == 0)
  212.         _PM_devcpy();
  213.     else
  214. #endif
  215. #ifdef CGA
  216.     if (strncmp(device, "cga", 3) == 0)
  217.         _cga_devcpy();
  218.     else
  219. #endif
  220. #ifdef EGA
  221.     if (strncmp(device, "ega", 3) == 0)
  222.         _ega_devcpy();
  223.     else
  224. #endif
  225. #ifdef VGA
  226.     if (strncmp(device, "vga", 3) == 0)
  227.         _vga_devcpy();
  228.     else
  229. #endif
  230. #ifdef SIGMA
  231.     if (strncmp(device, "sigma", 5) == 0)
  232.         _sigma_devcpy();
  233.     else
  234. #endif
  235.     {
  236.         if (*device == 0)
  237.             sprintf(buf, "vogle: expected the enviroment variable VDEVICE to be set to the desired device.\n");
  238.         else
  239.             sprintf(buf, "vogle: %s is an invalid device type\n", device);
  240.  
  241. #ifdef MSWIN
  242.         mswin_verror(buf);
  243. #else
  244. #ifdef OS2
  245.         PM_verror(buf);
  246. #else
  247.         fputs(buf, stderr);
  248.         fprintf(stderr, "The devices compiled into this library are:\n");
  249. #ifdef TG
  250.         fprintf(stderr, "Tk Graphic widgets\n");
  251. #endif
  252. #ifdef SUN
  253.         fprintf(stderr, "sun\n");
  254. #endif
  255. #ifdef X11
  256.         fprintf(stderr, "X11\n");
  257. #endif
  258. #ifdef DECX11
  259.         fprintf(stderr, "decX11\n");
  260. #endif
  261. #ifdef NeXT
  262.         fprintf(stderr, "NeXT\n");
  263. #endif
  264. #ifdef POSTSCRIPT
  265.         fprintf(stderr, "postscript\n");
  266.         fprintf(stderr, "ppostscript\n");
  267.         fprintf(stderr, "cps\n");
  268.         fprintf(stderr, "pcps\n");
  269. #endif
  270. #ifdef HPGL
  271.         fprintf(stderr, "hpgla1\n");
  272.         fprintf(stderr, "hpgla2 (or hpgl)\n");
  273.         fprintf(stderr, "hpgla3\n");
  274.         fprintf(stderr, "hpgla4\n");
  275. #endif
  276. #ifdef DXY
  277.         fprintf(stderr, "dxy\n");
  278. #endif
  279. #ifdef HPGT
  280.         fprintf(stderr, "hpgt\n");
  281. #endif
  282. #ifdef GRX
  283.         fprintf(stderr, "grx\n");
  284. #endif
  285. #ifdef TEK
  286.         fprintf(stderr, "tek\n");
  287. #endif
  288. #ifdef HERCULES
  289.         fprintf(stderr, "hercules\n");
  290. #endif
  291. #ifdef CGA
  292.         fprintf(stderr, "cga\n");
  293. #endif
  294. #ifdef EGA
  295.         fprintf(stderr, "ega\n");
  296. #endif
  297. #ifdef VGA
  298.         fprintf(stderr, "vga\n");
  299. #endif
  300. #ifdef SIGMA
  301.  
  302.         fprintf(stderr, "sigma\n");
  303. #endif
  304. #ifdef PPM
  305.                 fprintf(stderr, "p3,p6\n");
  306. #endif
  307. #endif
  308. #endif
  309.         exit(1);
  310.     }
  311. }
  312.  
  313. /*
  314.  * vinit
  315.  *
  316.  *     initialise VOGLE
  317.  *
  318.  */
  319. void
  320. vinit(device)
  321.     char    *device;
  322. {
  323.  
  324.     if (vdevice.initialised)
  325.         vexit();
  326.  
  327.     getdev(device);
  328.  
  329.     if (!allocated) {
  330.         allocated = 1;
  331.         vdevice.transmat = (Mstack *)vallocate(sizeof(Mstack));
  332.         vdevice.transmat->back = (Mstack *)NULL;
  333.         vdevice.attr = (Astack *)vallocate(sizeof(Astack));
  334.         vdevice.attr->back = (Astack *)NULL;
  335.         vdevice.viewport = (Vstack *)vallocate(sizeof(Vstack));
  336.         vdevice.viewport->back = (Vstack *)NULL;
  337.     }
  338.  
  339.     vdevice.clipoff = 0;
  340.     vdevice.sync = 1;
  341.     vdevice.upset = 0;
  342.     vdevice.cpW[V_W] = 1.0;            /* never changes */
  343.  
  344.     vdevice.attr->a.font[0] = '\0';
  345.     vdevice.attr->a.fill = 0;
  346.     vdevice.attr->a.hatch = 0;
  347.     vdevice.attr->a.backface = 0;
  348.     vdevice.attr->a.justify = V_LEFT | V_BOTTOM;
  349.     vdevice.attr->a.textcos = 1.0;
  350.     vdevice.attr->a.textsin = 0.0;
  351.     vdevice.attr->a.softtext = 0;
  352.     vdevice.attr->a.fixedwidth = 0;
  353.     vdevice.attr->a.hatchcos = 1.0;
  354.     vdevice.attr->a.hatchsin = 0.0;
  355.     vdevice.attr->a.hatchpitch = 0.1;
  356.     vdevice.attr->a.style = (unsigned char *)NULL;
  357.     vdevice.attr->a.dashp = (unsigned char *)NULL;
  358.     vdevice.attr->a.adist = 0.0;
  359.     vdevice.attr->a.dash = 0.0;
  360.     vdevice.attr->a.exvp = 0;
  361.  
  362.     if ((*vdevice.dev.Vinit)()) {
  363.  
  364.         vdevice.initialised = 1;
  365.         vdevice.inobject = 0;
  366.         vdevice.inpolygon = 0;
  367.  
  368.         if (getenv("VEXPANDVP") != (char *)NULL)
  369.             expandviewport();
  370.  
  371.         viewport(-1.0, 1.0, -1.0, 1.0);
  372.  
  373.         identmatrix(vdevice.transmat->m);
  374.  
  375.         move(0.0, 0.0, 0.0);
  376.  
  377.         if (!hershfont("futura.l")) /* Try a Hershey font */
  378.             font("small");    /* set up default font */
  379.  
  380.         textsize(0.05, 0.05);
  381.     } else {
  382.         fprintf(stderr, "vogle: error while setting up device\n");
  383.         exit(1);
  384.     }
  385.  
  386. }
  387.  
  388. /*
  389.  * Hacky new device changing routines...
  390.  */
  391. #define    DEVSTACK    8
  392. static    Device    vdevstk[DEVSTACK];
  393. static    int    vdevindx = 0;
  394.  
  395. void
  396. pushdev(device)
  397.     char    *device;
  398. {
  399.     /*
  400.      * Save the old vdevice structure
  401.      */
  402.     pushattributes();
  403.     pushviewport();
  404.  
  405.     if (vdevindx < DEVSTACK)
  406.         vdevstk[vdevindx++] = vdevice;
  407.     else
  408.         verror("vogle: pushdev: Device stack overflow");
  409.  
  410.     vdevice.initialised = 0;
  411.  
  412.     getdev(device);
  413.  
  414.     (*vdevice.dev.Vinit)();
  415.  
  416.     vdevice.initialised = 1;
  417.  
  418.     popviewport();
  419.     popattributes();
  420.  
  421. }
  422.  
  423. void
  424. popdev()
  425. {
  426.     /*
  427.      * Restore the old vdevice structure
  428.      */
  429.     pushattributes();
  430.     pushviewport();
  431.  
  432.     (*vdevice.dev.Vexit)();
  433.     if (vdevindx > 0)
  434.         vdevice = vdevstk[--vdevindx];
  435.     else
  436.         verror("vogle: popdev: Device stack underflow");
  437.  
  438.     popviewport();
  439.     popattributes();
  440. }
  441.  
  442. /*
  443.  * vnewdev
  444.  *
  445.  * reinitialize vogle to use a new device but don't change any
  446.  * global attributes like the window and viewport settings.
  447.  */
  448. void
  449. vnewdev(device)
  450.     char    *device;
  451. {
  452.     if (!vdevice.initialised)
  453.         verror("vnewdev: vogle not initialised\n");
  454.  
  455.     pushviewport();    
  456.  
  457.     (*vdevice.dev.Vexit)();
  458.  
  459.     vdevice.initialised = 0;
  460.  
  461.     getdev(device);
  462.  
  463.     (*vdevice.dev.Vinit)();
  464.  
  465.     vdevice.initialised = 1;
  466.  
  467.         /*
  468.          * Need to update font for this device if hardware font is what was
  469.          * being used previously.
  470.          */
  471.  
  472.     if (!strcmp(vdevice.attr->a.font, "small")) {
  473.         if (!(*vdevice.dev.Vfont)(vdevice.dev.small))
  474.             verror("font: unable to open small font");
  475.     } else if (!strcmp(vdevice.attr->a.font, "large")) {
  476.         if (!(*vdevice.dev.Vfont)(vdevice.dev.large))
  477.             verror("font: unable to open large font");
  478.     }
  479.  
  480.     popviewport();
  481. }
  482.  
  483. /*
  484.  * vgetdev
  485.  *
  486.  *    Returns the name of the current vogle device 
  487.  *    in the buffer buf. Also returns a pointer to
  488.  *    the start of buf.
  489.  */
  490. char    *
  491. vgetdev(buf)
  492.     char    *buf;
  493. {
  494.     /*
  495.      * Note no exit if not initialized here - so that vexit
  496.      * can be called before printing the name.
  497.      */
  498.     if (vdevice.dev.devname)
  499.         strcpy(buf, vdevice.dev.devname);
  500.     else
  501.         strcpy(buf, "(no device)");
  502.  
  503.     return(&buf[0]);
  504. }
  505.  
  506.  
  507. /*
  508.  * getkey
  509.  *
  510.  *    returns the next key pressed.
  511.  */
  512. #ifndef GRX    /* Has it's own getkey */
  513. int
  514. getkey()
  515. {
  516.     if (!vdevice.initialised)
  517.         verror("getkey: vogle not initialised\n");
  518.  
  519.     return((*vdevice.dev.Vgetkey)());
  520. }
  521. #endif
  522.  
  523. /*
  524.  * checkkey
  525.  *
  526.  *    returns true if a key has been hit, or 0 otherwise
  527.  *    (doesn't wait around like getkey)
  528.  */
  529. int
  530. checkkey()
  531. {
  532.     if (!vdevice.initialised)
  533.         verror("checkkey: vogle not initialised\n");
  534.  
  535.     return((*vdevice.dev.Vcheckkey)());
  536. }
  537.  
  538. /*
  539.  * locator
  540.  *
  541.  *    returns the current position of the crosshair or equivalent
  542.  * in world coordinates, and the mouse buttons pressed (if any).
  543.  */
  544. int
  545. locator(wx, wy)
  546.     float    *wx, *wy;
  547. {
  548.     int    a, b, c;
  549.  
  550.     if (!vdevice.initialised)
  551.         verror("locator: vogle not initialised");
  552.  
  553.     c = (*vdevice.dev.Vlocator)(&a, &b);
  554.     VtoWxy((float)a, (float)b, wx, wy);
  555.  
  556.     return(c);
  557. }
  558.  
  559. /*
  560.  * slocator
  561.  *
  562.  *    returns the current position of the crosshair or equivalent
  563.  * in screen coordinates, and the mouse buttons pressed (if any).
  564.  */
  565. int
  566. slocator(wx, wy)
  567.     float    *wx, *wy;
  568. {
  569.     int    a, b, c;
  570.     float    sx, sy;
  571.  
  572.     if (!vdevice.initialised)
  573.         verror("slocator: vogle not initialised");
  574.  
  575.     c = (*vdevice.dev.Vlocator)(&a, &b);
  576.     sx = vdevice.sizeX;
  577.     sy = vdevice.sizeY;
  578.  
  579.     *wx = a / (0.5 * sx) - 1.0;
  580.     *wy = b / (0.5 * sy) - 1.0;
  581.  
  582.     return(c);
  583. }
  584.  
  585. /*
  586.  * clear
  587.  *
  588.  *    clears the screen to the current colour, excepting devices
  589.  * like a laser printer where it flushes the page.
  590.  *
  591.  */
  592. void
  593. clear()
  594. {
  595.     Token    *tok;
  596.  
  597.     if (!vdevice.initialised)
  598.         verror("clear: vogle not initialised");
  599.  
  600.     if (vdevice.inobject) {
  601.         tok = newtokens(1);
  602.         tok->i = CLEAR;
  603.  
  604.         return;
  605.     }
  606.  
  607.     (*vdevice.dev.Vclear)();
  608. }
  609.  
  610. /*
  611.  * vexit
  612.  *
  613.  *    exit the vogle system
  614.  *
  615.  */
  616. void
  617. vexit()
  618. {
  619.     if (!vdevice.initialised)
  620.         verror("vexit: vogle not initialised");
  621.  
  622.     (*vdevice.dev.Vexit)();
  623.  
  624.     vdevice.initialised = 0;
  625.     fp = stdout;
  626. }
  627.  
  628. /*
  629.  * color
  630.  *
  631.  *    set the current colour to colour index number i.
  632.  *
  633.  */
  634. void
  635. color(i)
  636.     int    i;
  637. {
  638.     Token    *tok;
  639.  
  640.     if (!vdevice.initialised)
  641.         verror("color: vogle not initialised");
  642.  
  643.     if (vdevice.inobject) {
  644.         tok = newtokens(2);
  645.  
  646.         tok[0].i = COLOR;
  647.         tok[1].i = i;
  648.         return;
  649.     }
  650.  
  651.     vdevice.attr->a.color = i;
  652.     (*vdevice.dev.Vcolor)(i);
  653. }
  654.  
  655. /*
  656.  * mapcolor
  657.  *
  658.  *    set the color of index i.
  659.  */
  660. void
  661. mapcolor(i, r, g, b)
  662.     int    i;
  663.     short    r, g, b;
  664. {
  665.     Token    *tok;
  666.  
  667.     if (!vdevice.initialised)
  668.         verror("mapcolor: vogle not initialised");
  669.  
  670.     if (vdevice.inobject) {
  671.         tok = newtokens(5);
  672.  
  673.         tok[0].i = MAPCOLOR;
  674.         tok[1].i = i;
  675.         tok[2].i = r;
  676.         tok[3].i = g;
  677.         tok[4].i = b;
  678.  
  679.         return;
  680.     }
  681.  
  682.     (*vdevice.dev.Vmapcolor)(i, r, g, b);
  683. }
  684.  
  685. /*
  686.  * getdepth
  687.  *
  688.  *    Returns the number if bit planes on a device.
  689.  */
  690. int
  691. getdepth()
  692. {
  693.     if (!vdevice.initialised)
  694.         verror("getdepth: vogle not initialised\n");
  695.  
  696.     return(vdevice.depth);
  697. }
  698.  
  699. /*
  700.  * vsetflush
  701.  *
  702.  * Controls flushing of the display - we can get considerable
  703.  * Speed up's under X11 using this...
  704.  */
  705. void
  706. vsetflush(yn)
  707.     int    yn;
  708. {
  709.     vdevice.sync = yn;
  710. }
  711.  
  712. /*
  713.  * vflush
  714.  *
  715.  * Explicitly call the device flushing routine...
  716.  * This is enabled for object so that you can force an update
  717.  * in the middle of an object, as objects have flushing off
  718.  * while they are drawn anyway.
  719.  */
  720. void
  721. vflush()
  722. {
  723.     Token    *tok;
  724.  
  725.     if (!vdevice.initialised)
  726.         verror("vflush: vogl not initialised");
  727.  
  728.     if (vdevice.inobject) {
  729.         tok = newtokens(1);
  730.         tok->i = VFLUSH;
  731.  
  732.         return;
  733.     }
  734.  
  735.     (*vdevice.dev.Vsync)();
  736. }
  737.  
  738. /*
  739.  * linewidth
  740.  *
  741.  *    Because it's so difficult to do this device independently,
  742.  *    (it looks so different on each device) we will just have 
  743.  *    THICK(1) or THIN(0).
  744.  */
  745. void
  746. linewidth(w)
  747.     int    w;
  748. {
  749.     (*vdevice.dev.Vsetlw)(w);
  750. }
  751.