summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/window/x11-Xt.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/window/x11-Xt.c')
-rw-r--r--Build/source/texk/web2c/window/x11-Xt.c374
1 files changed, 374 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/window/x11-Xt.c b/Build/source/texk/web2c/window/x11-Xt.c
new file mode 100644
index 00000000000..b7c9c25c405
--- /dev/null
+++ b/Build/source/texk/web2c/window/x11-Xt.c
@@ -0,0 +1,374 @@
+/* x11.c: X11 window interface for Metafont, using Xt. Original by
+ rusty@garnet.berkeley.edu. */
+
+#define EXTERN extern
+#include "../mfd.h"
+
+#ifdef X11WIN /* almost whole file */
+
+/* For wchar_t et al., that the X files might want. */
+#include <kpathsea/systypes.h>
+
+#undef input /* the XWMHints structure has a field named `input' */
+#undef output
+#include <X11/Xlib.h>
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#undef wchar_t
+
+#define PLANE 0
+
+static unsigned int mf_defwidth = 0;
+static unsigned int mf_defheight = 0;
+
+static Display *mf_display;
+static Window mf_window;
+
+static Pixmap mf_pixmap;
+
+static XtAppContext mf_app;
+
+static GC mf_dgc; /* draw gc */
+static GC mf_egc; /* erase gc */
+static GC mf_cgc; /* copy plane gc */
+
+typedef struct
+{
+ unsigned int mf_width, mf_height;
+ Pixel mf_fg, mf_bg;
+} mf_resources_struct;
+
+static mf_resources_struct mf_x11_resources;
+
+
+/* Don't paint anything until we're mapped. */
+static Boolean mf_mapped = False;
+static Boolean mf_awaiting_expose = True;
+
+#ifdef MF_XT_DEBUG
+static int mf_max_x, mf_max_y;
+static int mf_min_x, mf_min_y;
+
+static void mf_checkextent ();
+#endif
+
+static XtResource mf_resources[]
+ = { { "width", "Width", XtRInt, sizeof (int),
+ XtOffset (mf_resources_struct *, mf_width), XtRInt,
+ (XtPointer) & mf_defwidth },
+
+ { "height", "Height", XtRInt, sizeof (int),
+ XtOffset (mf_resources_struct *, mf_height), XtRInt,
+ (XtPointer) &mf_defheight },
+
+ { "foreground", "Foreground", XtRPixel, sizeof (Pixel),
+ XtOffset (mf_resources_struct *, mf_fg),
+ XtRString, (XtPointer) "Black" },
+
+ { "background", "Background", XtRPixel, sizeof (Pixel),
+ XtOffset (mf_resources_struct *, mf_bg), XtRString,
+ (XtPointer) "White" },
+};
+
+/* Maybe someday we'll read options, until then, this is just here for
+ the resources. */
+static XrmOptionDescRec mf_optiondesclist[]
+= { { "-width", "width", XrmoptionSepArg, (XPointer) NULL },
+ { "-height", "height", XrmoptionSepArg, (XPointer) NULL },
+ { "-fg", "foreground", XrmoptionSepArg, (XPointer) NULL },
+ { "-bg", "background", XrmoptionSepArg, (XPointer) NULL },
+};
+
+static void mf_events(void);
+static void mf_mapstatus(Widget w, XtPointer data, XEvent *ev);
+static void mf_newpixmap(unsigned int width, unsigned int height);
+static void mf_redraw(void);
+static void mf_repaint(Widget w, XtPointer data, XEvent *ev);
+
+#include <mfdisplay.h>
+
+/* Return 1 if display opened successfully, else 0. */
+
+int
+mf_x11_initscreen (void)
+{
+ XSetWindowAttributes xwa;
+ Widget mf_toplevel;
+ Widget mf_canvas;
+ XGCValues gcv;
+ Arg args[1];
+ int mf_argc;
+ char *mf_argv[2];
+
+ mf_argv[0] = "mf";
+ mf_argv[1] = NULL;
+ mf_argc = 1;
+
+ mf_toplevel = XtInitialize ("mf", "Metafont",
+ mf_optiondesclist,
+ XtNumber (mf_optiondesclist),
+ &mf_argc, mf_argv);
+
+ XtGetApplicationResources (mf_toplevel, (XtPointer) & mf_x11_resources,
+ mf_resources, XtNumber (mf_resources),
+ NULL, 0);
+
+ if (mf_argc != 1)
+ {
+ fprintf (stderr, "Usage: %s\n", mf_argv[0]);
+ return 0;
+ }
+
+ /* If nothing specified in their resources (e.g., .Xdefaults)
+ then use the values of Metafont's "screen". */
+ if (mf_x11_resources.mf_width == 0)
+ mf_x11_resources.mf_width = screenwidth;
+ if (mf_x11_resources.mf_height == 0)
+ mf_x11_resources.mf_height = screendepth;
+
+ mf_canvas = XtCreateManagedWidget ("canvas", widgetClass, mf_toplevel,
+ NULL, 0);
+
+ XtSetArg (args[0], XtNwidth, mf_x11_resources.mf_width);
+ XtSetValues (mf_canvas, args, 1);
+ XtSetArg (args[0], XtNheight, mf_x11_resources.mf_height);
+ XtSetValues (mf_canvas, args, 1);
+
+ /* for mf_x11_updatescreen() */
+ mf_app = XtWidgetToApplicationContext (mf_canvas);
+
+ XtAddEventHandler (mf_canvas, (Cardinal) ExposureMask, True,
+ (XtEventHandler) mf_repaint, NULL);
+ XtAddEventHandler (mf_canvas, (Cardinal) StructureNotifyMask, True,
+ (XtEventHandler) mf_mapstatus, NULL);
+
+ XtRealizeWidget (mf_toplevel);
+
+ mf_display = XtDisplay (mf_canvas);
+ mf_window = XtWindow (mf_canvas);
+
+ /* Since Metafont isn't your typical x window program that
+ sits in XTMainLoop, if the server supports backing store
+ and save unders this will help keep the output looking
+ nice. */
+ xwa.backing_store = WhenMapped;
+ XChangeWindowAttributes (mf_display, mf_window, CWBackingStore, &xwa);
+
+ gcv.background = mf_x11_resources.mf_bg;
+ gcv.foreground = mf_x11_resources.mf_fg;
+ gcv.function = GXcopy;
+
+ /* copy plane gc */
+ mf_cgc = XCreateGC (mf_display, mf_window,
+ GCForeground | GCBackground | GCFunction, &gcv);
+
+ mf_newpixmap (screenwidth > mf_x11_resources.mf_width
+ ? screenwidth : mf_x11_resources.mf_width,
+ screendepth > mf_x11_resources.mf_height
+ ? screendepth : mf_x11_resources.mf_height);
+
+ return 1;
+}
+
+void
+mf_x11_updatescreen (void)
+{
+ XEvent event;
+
+ mf_events ();
+ while (mf_awaiting_expose)
+ {
+ XtAppNextEvent (mf_app, &event);
+ XtDispatchEvent (&event);
+ }
+ mf_redraw ();
+
+#ifdef MF_XT_DEBUG
+ printf ("max_x=%d, min_x=%d, max_y=%d, min_y=%d\n",
+ mf_max_x, mf_min_x,
+ mf_max_y, mf_min_y);
+#endif
+}
+
+
+void
+mf_x11_blankrectangle(screencol left,
+ screencol right,
+ screenrow top,
+ screenrow bottom)
+{
+ XFillRectangle (mf_display, mf_pixmap, mf_egc, (int) left, (int) top,
+ (int) (right - left + 1), (int) (bottom - top + 1));
+ mf_events ();
+}
+
+void
+mf_x11_paintrow(screenrow row,
+ pixelcolor init_color,
+ transspec tvect,
+ screencol vector_size)
+{
+ GC gc;
+ int col;
+
+ gc = (init_color == 0) ? mf_egc : mf_dgc;
+
+ do
+ {
+ col = *tvect++;
+
+#ifdef MF_XT_DEBUG
+ mf_checkextent (col, *tvect, row);
+#endif /* MF_XT_DEBUG */
+
+ XDrawLine (mf_display, mf_pixmap, gc, col, (int) row,
+ (int) *tvect, (int) row);
+
+ gc = (gc == mf_egc) ? mf_dgc : mf_egc;
+ }
+ while (--vector_size > 0);
+
+ mf_events ();
+}
+
+#ifdef MF_XT_DEBUG
+static void
+mf_checkextent(int x1, int x2, int y)
+{
+ if (x1 < mf_min_x)
+ mf_min_x = x1;
+ if (x1 > mf_max_x)
+ mf_max_x = x1;
+
+ if (x2 < mf_min_x)
+ mf_min_x = x2;
+ if (x2 > mf_max_x)
+ mf_max_x = x2;
+
+ if (y > mf_max_y)
+ mf_max_y = y;
+ if (y < mf_min_y)
+ mf_min_y = y;
+}
+#endif /* MF_XT_DEBUG */
+
+static void
+mf_events (void)
+{
+ XEvent event;
+
+ if (XtAppPending (mf_app) != 0)
+ {
+ while (XtAppPending (mf_app) != 0)
+ {
+ XtAppNextEvent (mf_app, &event);
+ XtDispatchEvent (&event);
+ }
+ }
+}
+
+static void
+mf_newpixmap(unsigned int width, unsigned int height)
+{
+ XGCValues gcv;
+ Pixmap newpixmap;
+
+ /* width == mf_width and height == mf_height
+ the first time mf_newpixmap() is called.
+ */
+ if (width < mf_x11_resources.mf_width && height < mf_x11_resources.mf_height)
+ return;
+
+ newpixmap = XCreatePixmap (mf_display, mf_window, width, height, 1);
+
+ gcv.background = 0;
+ gcv.foreground = 1;
+
+ if (mf_dgc != 0)
+ XFreeGC (mf_display, mf_dgc);
+
+ /* draw gc */
+ gcv.line_width = 1;
+ mf_dgc = XCreateGC (mf_display, newpixmap,
+ GCForeground | GCBackground | GCLineWidth, &gcv);
+
+ if (mf_egc != 0)
+ XFreeGC (mf_display, mf_egc);
+
+ /* erase gc */
+ gcv.foreground = 0;
+ mf_egc = XCreateGC (mf_display, newpixmap,
+ GCForeground | GCBackground | GCLineWidth, &gcv);
+
+ XFillRectangle (mf_display, newpixmap, mf_egc, 0, 0, width, height);
+
+ if (mf_pixmap != 0)
+ {
+ XCopyArea (mf_display, mf_pixmap, newpixmap, mf_dgc, 0, 0,
+ mf_x11_resources.mf_width,
+ mf_x11_resources.mf_height, 0, 0);
+
+ XFreePixmap (mf_display, mf_pixmap);
+ }
+
+ mf_pixmap = newpixmap;
+
+ mf_x11_resources.mf_width = width;
+ mf_x11_resources.mf_height = height;
+}
+
+static void
+mf_repaint(Widget w, XtPointer data, XEvent *ev)
+{
+ if (!mf_mapped || !ev || ev->type != Expose)
+ return;
+
+ /* We are a ``simple application''. */
+ if (ev->xexpose.count == 0)
+ {
+ XEvent event;
+
+ /* skip all excess redraws */
+ while (XCheckTypedEvent (mf_display, Expose, &event) != False)
+ continue;
+
+ mf_redraw ();
+ mf_awaiting_expose = False;
+ }
+}
+
+
+static void
+mf_mapstatus(Widget w, XtPointer data, XEvent *ev)
+{
+ switch (ev->type)
+ {
+ case MapNotify:
+ mf_mapped = True;
+ break;
+
+ case UnmapNotify:
+ mf_mapped = False;
+ break;
+
+ case ConfigureNotify:
+ mf_newpixmap (ev->xconfigure.width, ev->xconfigure.height);
+ mf_redraw ();
+ break;
+ }
+}
+
+
+static void
+mf_redraw (void)
+{
+ XCopyPlane (mf_display, mf_pixmap, mf_window, mf_cgc, 0, 0,
+ mf_x11_resources.mf_width, mf_x11_resources.mf_height,
+ 0, 0, (unsigned long) 1);
+
+ XFlush (mf_display);
+}
+
+#else
+int x11_dummy;
+#endif /* X11WIN */