home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / unixtex-6.1b-src.tgz / tar.out / contrib / unixtex / web2c / mf / MFwindow / x11-Xt.c < prev   
Encoding:
C/C++ Source or Header  |  1996-09-28  |  8.3 KB  |  374 lines

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