home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / tex / texsrc3 / Src / mf / MFwindow / c / x11-Xt < prev   
Encoding:
Text File  |  1991-03-22  |  7.2 KB  |  363 lines

  1. /*
  2.  * X11 window interface for Metafont, using Xt.
  3.  * (rusty@garnet.berkeley.edu)
  4.  */
  5.  
  6. #define    EXTERN    extern
  7. #include "../mfd.h"
  8.  
  9. #ifdef    X11WIN
  10. #include <X11/Xlib.h>
  11. #include <X11/Xutil.h>
  12. #include <X11/Intrinsic.h>
  13. #include <X11/StringDefs.h>
  14.  
  15. # define PLANE    0
  16.  
  17. static int        mf_defwidth =    0;
  18. static int        mf_defheight =    0;
  19.  
  20. static Display        *mf_display;
  21. static Window        mf_window;
  22.  
  23. static Pixmap        mf_pixmap;
  24.  
  25. static XtAppContext    mf_app;
  26.  
  27. static GC        mf_dgc;        /* draw gc */
  28. static GC        mf_egc;        /* erase gc */
  29. static GC        mf_cgc;        /* copy plane gc */
  30.  
  31. static Pixel        mf_fg, mf_bg;
  32. static unsigned int    mf_width, mf_height;
  33.  
  34. static Boolean        mf_mapped;
  35.  
  36. static int        mf_max_x, mf_max_y;
  37. static int        mf_min_x, mf_min_y;
  38.  
  39. static XtResource mf_resources[] = {
  40.     { "width", "Width", XtRInt, sizeof(int),
  41.           (Cardinal) &mf_width, XtRInt, (caddr_t) &mf_defwidth },
  42.     { "height", "Height", XtRInt, sizeof(int),
  43.           (Cardinal) &mf_height, XtRInt, (caddr_t) &mf_defheight },
  44.     { "foreground", "Foreground", XtRPixel, sizeof(Pixel),
  45.           (Cardinal) &mf_fg, XtRString, (caddr_t) "Black" },
  46.     { "background", "Background", XtRPixel, sizeof(Pixel),
  47.           (Cardinal) &mf_bg, XtRString, (caddr_t) "White" },
  48. };
  49.  
  50. static XrmOptionDescRec mf_optiondesclist[] = {
  51. {"-width",    "width",    XrmoptionSepArg,     (caddr_t) NULL},
  52. {"-height",    "height",    XrmoptionSepArg,    (caddr_t) NULL},
  53. {"-fg",        "foreground",    XrmoptionSepArg,    (caddr_t) NULL},
  54. {"-bg",        "background",    XrmoptionSepArg,    (caddr_t) NULL},
  55. };
  56.  
  57. static void mf_events();
  58. static void mf_newpixmap ();
  59. static void mf_repaint();
  60. static void mf_mapstatus();
  61. static void mf_redraw();
  62.  
  63.  
  64. /* return 1 if display opened successfully, else 0 */
  65. int
  66. mf_x11_initscreen() {
  67.     XSetWindowAttributes    xwa;
  68.     Widget            mf_toplevel;
  69.     Widget            mf_canvas;
  70.     XGCValues        gcv;
  71.     Arg            args[1];
  72.     int            mf_argc;
  73.     char            *mf_argv[2];
  74.  
  75.     mf_argv[0] = "mf";
  76.     mf_argv[1] = NULL;
  77.     mf_argc = 1;
  78.  
  79.     mf_toplevel = XtInitialize("mf", "Metafont",
  80.                    mf_optiondesclist,
  81.                    XtNumber(mf_optiondesclist),
  82.                    &mf_argc, mf_argv);
  83.  
  84.     XtGetApplicationResources(mf_toplevel, 0,
  85.                   mf_resources, XtNumber(mf_resources),
  86.                   NULL, 0 );
  87.  
  88.  
  89.     if (mf_argc != 1) {
  90.         (void) fprintf(stderr, "Usage: %s\n", mf_argv[0]);
  91.         exit(1);
  92.     }
  93.  
  94.     /*
  95.      * if nothing specified in their resources/.Xdefaults
  96.      * then use the values of metafont's "screen".
  97.      */
  98.     if (mf_width == 0)
  99.         mf_width = screenwidth;
  100.     if (mf_height == 0)
  101.         mf_height = screendepth;
  102.  
  103.     mf_canvas = XtCreateManagedWidget("canvas", widgetClass, mf_toplevel,
  104.                       NULL, 0);
  105.  
  106.     XtSetArg(args[0], XtNwidth, mf_width);
  107.     XtSetValues(mf_canvas, args, 1);
  108.     XtSetArg(args[0], XtNheight, mf_height);
  109.     XtSetValues(mf_canvas, args, 1);
  110.  
  111.     /* for mf_x11_updatescreen() */
  112.     mf_app = XtWidgetToApplicationContext(mf_canvas);
  113.  
  114.     XtAddEventHandler(mf_canvas, (Cardinal) ExposureMask, True, 
  115.               mf_repaint, NULL);
  116.     XtAddEventHandler(mf_canvas, (Cardinal) StructureNotifyMask, True, 
  117.               mf_mapstatus, NULL);
  118.  
  119.     XtRealizeWidget(mf_toplevel);
  120.  
  121.     mf_display = XtDisplay(mf_canvas);
  122.     mf_window = XtWindow(mf_canvas);
  123.  
  124.     /*
  125.      * since metafont isn't your typical x window program that
  126.      * sits in xt_main_loop, if the server supports backing store
  127.      * and save unders this will help keep the output looking
  128.      * nice.
  129.      */
  130.     xwa.backing_store = Always;
  131.     xwa.save_under = True;
  132.     XChangeWindowAttributes(mf_display, mf_window,
  133.                 CWBackingStore|CWSaveUnder, &xwa);
  134.  
  135.     gcv.background = mf_bg;
  136.     gcv.foreground = mf_fg;
  137.     gcv.function = GXcopy;
  138.  
  139.     /* copy plane gc */
  140.     mf_cgc = XCreateGC(mf_display, mf_window,
  141.                GCForeground|GCBackground|GCFunction, &gcv);
  142.  
  143.     mf_newpixmap(screenwidth > mf_width ? screenwidth : mf_width,
  144.              screendepth > mf_height ? screendepth : mf_height);
  145.  
  146.     return(1);
  147. }
  148.  
  149. /* make sure the screen is up to date */
  150. void
  151. mf_x11_updatescreen() {
  152.     XEvent        event;
  153.  
  154.     mf_events();
  155.     mf_redraw();
  156.  
  157. #ifdef notdef
  158.     printf("max_x=%d, min_x=%d, max_y=%d, min_y=%d\n",
  159.            mf_max_x, mf_min_x,
  160.            mf_max_y, mf_min_y);
  161. #endif
  162. }
  163.  
  164. void
  165. mf_x11_blankrectangle(left, right, top, bottom)
  166.     screencol    left, right;
  167.     screenrow    top, bottom;
  168. {
  169.     extern void    mf_events();
  170.  
  171.     XFillRectangle(mf_display, mf_pixmap, mf_egc, (int) left, (int) top,
  172.                (int) (right - left + 1), (int) (bottom - top + 1));
  173.  
  174.     mf_events();
  175. }
  176.  
  177. void
  178. mf_x11_paintrow(row, init_color, tvect, vector_size)
  179.     screenrow        row;
  180.     pixelcolor        init_color;
  181.     transspec        tvect;
  182.     register screencol    vector_size;
  183. {
  184.     extern void        mf_checkextent();
  185.     Pixel            color;
  186.     GC            gc;
  187.     int            col;
  188.  
  189.     gc = (init_color == 0) ? mf_egc : mf_dgc;
  190.  
  191.     do {
  192.         col = *tvect++;
  193.  
  194. # ifdef MF_XT_DEBUG
  195.         mf_checkextent(col, (*tvect -1), row);
  196. # endif /* MF_XT_DEBUG */
  197.  
  198.         XDrawLine(mf_display, mf_pixmap, gc, col, (int) row,
  199.               (int) (*tvect - 1), (int) row);
  200.  
  201.         gc = (gc == mf_egc) ? mf_dgc : mf_egc;
  202.     } while (--vector_size > 0);
  203.  
  204.     mf_events();
  205. }
  206.  
  207. # ifdef MF_XT_DEBUG
  208. static void
  209. mf_checkextent(x1, x2, y) {
  210.     if (x1 < mf_min_x)
  211.         mf_min_x = x1;
  212.     if (x1 > mf_max_x)
  213.         mf_max_x = x1;
  214.  
  215.     if (x2 < mf_min_x)
  216.         mf_min_x = x2;
  217.     if (x2 > mf_max_x)
  218.         mf_max_x = x2;
  219.  
  220.     if (y > mf_max_y)
  221.         mf_max_y = y;
  222.     if (y < mf_min_y)
  223.         mf_min_y = y;
  224. }
  225. # endif /* MF_XT_DEBUG */
  226.  
  227. static void
  228. mf_events() {
  229.     XEvent    event;
  230.  
  231.     if (XtAppPending(mf_app) != 0) {
  232.         while (XtAppPending(mf_app) != 0) {
  233.             XtAppNextEvent(mf_app, &event);
  234.             XtDispatchEvent(&event);
  235.         }
  236.         /* mf_redraw(); */
  237.     }
  238. }
  239.  
  240. static void
  241. mf_newpixmap(width, height)
  242.     unsigned int        width, height;
  243. {
  244.     XGCValues        gcv;
  245.     Pixmap            newpixmap;
  246.  
  247.     /*
  248.      * width == mf_width and height == mf_height
  249.      * the first time mf_newpixmap() is called.
  250.      */
  251.     if ((width < mf_width) && (height < mf_height))
  252.         return;
  253.  
  254.     newpixmap = XCreatePixmap(mf_display, mf_window,
  255.                   width, height, 1);
  256.  
  257.     gcv.background = 0;
  258.     gcv.foreground = 1;
  259.  
  260.     if (mf_dgc != 0)
  261.         XFreeGC(mf_display, mf_dgc);
  262.  
  263.     /* draw gc */
  264.     gcv.line_width = 1;
  265.     mf_dgc = XCreateGC(mf_display, newpixmap,
  266.                GCForeground|GCBackground|GCLineWidth, &gcv);
  267.  
  268.     if (mf_egc != 0)
  269.         XFreeGC(mf_display, mf_egc);
  270.  
  271.     /* erase gc */
  272.     gcv.foreground = 0;
  273.     mf_egc = XCreateGC(mf_display, newpixmap,
  274.                GCForeground|GCBackground|GCLineWidth, &gcv);
  275.  
  276.     XFillRectangle(mf_display, newpixmap, mf_egc, 0, 0, width, height);
  277.  
  278.     if (mf_pixmap != 0) {
  279.         XCopyArea(mf_display, mf_pixmap, newpixmap, mf_dgc, 0, 0,
  280.               mf_width, mf_height, 0, 0);
  281.  
  282.         XFreePixmap(mf_display, mf_pixmap);
  283.     }
  284.  
  285.     mf_pixmap = newpixmap;
  286.  
  287.     mf_width = width;
  288.     mf_height = height;
  289. }
  290.  
  291. /*ARGSUSED*/
  292. static void 
  293. mf_repaint(w, data, ev)
  294.     Widget        w;
  295.     caddr_t        data;
  296.     XEvent        *ev;
  297. {
  298.     extern void    mf_redraw();
  299.  
  300.     if (! mf_mapped)
  301.         return;
  302.  
  303.     if (ev == NULL)
  304.         return;
  305.  
  306.     if (ev->type != Expose)
  307.         return;
  308.  
  309.     /* we are a "simple application" */
  310.     if (ev->xexpose.count == 0) {
  311.         XEvent    event;
  312.  
  313.         /* skip all excess redraws */
  314.         while (XCheckTypedEvent(mf_display, Expose, &event) != False)
  315.             continue;
  316.  
  317.         mf_redraw();
  318.     }
  319. }
  320.  
  321. /*ARGSUSED*/
  322. static void 
  323. mf_mapstatus(w, data, ev)
  324.     Widget        w;
  325.     caddr_t        data;
  326.     XEvent        *ev;
  327. {
  328.     extern void    mf_redraw();
  329.     extern void    mf_newpixmap();
  330.  
  331.     if (ev->type == MapNotify) {
  332.         mf_mapped = True;
  333.  
  334.         return;
  335.     }
  336.  
  337.     if (ev->type == UnmapNotify) {
  338.         mf_mapped = False;
  339.  
  340.         return;
  341.     }
  342.  
  343.     if (ev->type == ConfigureNotify) {
  344.         mf_newpixmap(ev->xconfigure.width, ev->xconfigure.height);
  345.         mf_redraw();
  346.  
  347.         return;
  348.     }
  349. }
  350.  
  351. static void
  352. mf_redraw() {
  353.     XCopyPlane(mf_display, mf_pixmap, mf_window, mf_cgc, 0, 0,
  354.            mf_width, mf_height,
  355.            0, 0, (unsigned long) 1);
  356.  
  357.     XFlush(mf_display);
  358. }
  359.  
  360. #else
  361. int x11_dummy;
  362. #endif /* X11WIN */
  363.