diff x11window.c @ 3:5a977ccbc7a9 default tip

Empty changelog
author darius
date Sat, 06 Dec 1997 05:41:29 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/x11window.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,2532 @@
+/* $Id: x11window.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
+
+
+/* x11window.c
+ *
+ * Kevin P. Smith  6/11/89
+ * Much modified by Jerry Frain and Joe Young
+ */
+
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#ifdef RFCURSORS
+#include <X11/Xmu/CurUtil.h>
+#endif
+#include <X11/cursorfont.h>
+#include <assert.h>
+#include <string.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+
+#define INVALID_POSITION	-10000	/* gotta be a big negative */
+/* XFIX speedup */
+#define MAXCACHE	128
+
+/* changes too good to risk leaving out, by Richard Caley (rjc@cstr.ed.ac.uk)*/
+#define RJC
+#define FOURPLANEFIX
+
+/*
+#define NORMAL_FONT	"-*-fixed-medium-r-*-*-10-*-*-*-*-*-*-*"
+#define BOLD_FONT	"-*-fixed-medium-r-*-*-10-*-*-*-*-*-*-*"
+#define ITALIC_FONT	"-*-fixed-medium-r-*-*-10-*-*-*-*-*-*-*"
+*/
+
+#define NORMAL_FONT	"6x10"
+#define BOLD_FONT	"6x10"
+#define BOLD_FONT2	"-*-clean-bold-r-normal--10-100-75-75-c-60-*"
+#define ITALIC_FONT	"6x10"
+#define ITALIC_FONT2	"-*-clean-bold-r-normal--10-100-75-75-c-60-*"
+#define BIG_FONT	"-adobe-helvetica-bold-r-normal--34-*-*-*-*-*-*-*"
+#define IND_FONT        "-*-clean-bold-r-normal--10-100-75-75-c-60-*"
+/*#define BOLD_FONT2	"-schumacher-clean-bold-r-normal--10-100-75-75-c-60-iso8859-1"
+#define ITALIC_FONT2	"-misc-fixed-medium-i-normal--10-100-75-75-c-60-iso8859-1"
+#define BIG_FONT	"-adobe-helvetica-bold-r-normal--34-*-*-*-*-*-*-*"
+*/
+
+static char *_nfonts[] = {
+    NORMAL_FONT,
+    "-*-clean-medium-r-normal--10-100-75-75-c-60-*",
+    "fixed",
+    NULL,
+};
+static char *_bfonts[] = {
+    BOLD_FONT,
+    "-*-clean-bold-r-normal--10-100-75-75-c-60-*",
+    "fixed",
+    NULL,
+};
+static char *_ifonts[] = {
+    ITALIC_FONT,
+    "-*-clean-bold-r-normal--10-100-75-75-c-60-*",
+    "fixed",
+    NULL,
+};
+static char *_bgfonts[] = {
+    BIG_FONT,
+    "-*-lucidatypewriter-*-*-*-*-40-*-*-*-*-*-*-*",
+    "fixed",
+    NULL,
+};
+
+#define FONTS 4
+#define BITGC 4
+
+#define WHITE   0
+#define BLACK   1
+#define RED     2
+#define GREEN   3
+#define YELLOW  4
+#define CYAN    5
+#define GREY	6
+
+static int zero = 0;
+static int one = 1;
+static int two = 2;
+static int three = 3;
+
+int     controlkey = 0;
+#define	BillsScrewyAltMask	(Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)
+int     altkey = 0;
+int     W_FastClear = 0;
+#ifdef CONTINUOUS_MOUSE
+int     buttonDown = 0;
+#endif				/* CONTINUOUS_MOUSE */
+Display *W_Display;
+Window  W_Root;
+Colormap W_Colormap;
+int     W_Screen;
+#ifdef FOURPLANEFIX
+Visual *W_Visual;
+#endif
+W_Font  W_BigFont = (W_Font) & zero, W_RegularFont = (W_Font) & one;
+W_Font  W_HighlightFont = (W_Font) & two, W_UnderlineFont = (W_Font) & three;
+W_Color W_White = WHITE, W_Black = BLACK, W_Red = RED, W_Green = GREEN;
+W_Color W_Yellow = YELLOW, W_Cyan = CYAN, W_Grey = GREY;
+int     W_Textwidth, W_Textheight;
+char   *getdefault();
+char   *strdup();
+
+int     W_in_message = 0;	/* jfy -- for Jerry's warp message hack */
+
+#ifdef RJC
+extern W_Window baseWin;
+static XClassHint class_hint = {
+    "netrek", "Netrek",
+};
+
+static XWMHints wm_hint = {
+    InputHint | StateHint,
+    True,
+    WithdrawnState,
+    None,
+    None,
+    0, 0,
+    None,
+    None,
+};
+
+static XSizeHints wm_size_hint;
+#endif				/* RJC */
+
+static W_Event W_myevent;
+static int W_isEvent = 0;
+
+struct fontInfo {
+    XFontStruct *fontstruct;
+    int     baseline;
+};
+
+struct colors {
+    char   *name;
+    GC      contexts[FONTS + 1];
+    Pixmap  pixmap;
+    long    pixelValue;
+};
+
+struct icon {
+    Window  window;
+    Pixmap  bitmap;
+    int     width, height;
+    Pixmap  pixmap;
+};
+
+#define WIN_GRAPH	1
+#define WIN_TEXT	2
+#define WIN_MENU	3
+#define WIN_SCROLL	4
+
+struct window {
+    Window  window;
+    int     type;
+    char   *data;
+    int     mapped;
+    int     width, height;
+    char   *name;
+    Cursor  cursor;
+#ifdef SHORT_PACKETS
+    int     insensitive;
+#endif
+#if 0
+    W_Callback handle_keydown;
+    W_Callback handle_keyup;
+    W_Callback handle_button;
+    W_Callback handle_expose;
+#endif				/* 0 */
+};
+
+struct stringList {
+    char   *string;
+    W_Color color;
+    struct stringList *next;
+};
+
+struct menuItem {
+    char   *string;
+    W_Color color;
+    W_Font  font;
+};
+
+struct colors colortable[] = {
+    {"white"},
+    {"black"},
+    {"red"},
+    {"green"},
+    {"yellow"},
+    {"cyan"},
+    {"light grey"}
+};
+
+struct windowlist {
+    struct window *window;
+    struct windowlist *next;
+};
+
+#define HASHSIZE 29
+#define hash(x) (((int) (x)) % HASHSIZE)
+
+struct windowlist *hashtable[HASHSIZE];
+struct fontInfo fonts[FONTS];
+
+struct window *newWindow();
+#ifndef NeXT
+#ifndef __STDC__
+char   *malloc();
+#endif
+#endif				/* NeXT */
+short  *x11tox10bits();
+
+struct window myroot;
+
+#define NCOLORS (sizeof(colortable)/sizeof(colortable[0]))
+#define W_Void2Window(win) ((win) ? (struct window *) (win) : &myroot)
+#define W_Window2Void(window) ((W_Window) (window))
+#define W_Void2Icon(bit) ((struct icon *) (bit))
+#define W_Icon2Void(bit) ((W_Icon) (bit))
+#define fontNum(font) (*((int *) font))
+#define TILESIDE 16
+
+#define WIN_EDGE 5		/* border on l/r edges of text windows */
+#define MENU_PAD 4		/* border on t/b edges of text windows */
+#define MENU_BAR 2		/* width of menu bar */
+
+static unsigned char gray[] = {
+    0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
+    0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
+    0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
+    0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55
+};
+
+static unsigned char striped[] = {
+    0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
+    0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f,
+    0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
+    0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0
+};
+
+static unsigned char solid[] = {
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
+/* Prototypes */
+/*static int _myerror P((Display *d , XErrorEvent *e ));*/
+static void GetFonts P((void));
+static XFontStruct *find_font P((char *oldf, char **fonts));
+static void GetColors P((void));
+static void FlushClearAreaCache P((Window win));
+static int W_SpNextEvent P((W_Event * wevent));
+static void FlushLineCache P((Window win, int color));
+static void FlushPointCache P((Window win, int color));
+static struct window *findWindow P((Window window));
+static void addToHash P((struct window * win));
+static void AddToScrolling P((struct window * win, W_Color color, char *str, int len));
+static void redrawScrolling P((struct window * win));
+static void resizeScrolling P((struct window * win, int width, int height));
+static void redrawMenu P((struct window * win));
+static void redrawMenuItem P((struct window * win, int n));
+static void changeMenuItem P((struct window * win, int n, W_Color color, char *str, int len, W_Font font));
+/*static void W_SetTransientForHint P((W_Window w , W_Window pw ));*/
+static void checkGeometry P((char *name, int *x, int *y, int *width, int *height));
+static void checkParent P((char *name, W_Window * parent));
+static void checkCursor P((char *name, char *cursname, Cursor * cursor));
+static void findMouse P((int *x, int *y));
+#ifdef AUTOKEY
+static void W_Flush P((void));
+#endif				/* AUTOKEY */
+static void deleteWindow P((struct window * window));
+
+/* X debugging */
+#if 0
+static int
+_myerror(d, e)
+    Display *d;
+    XErrorEvent *e;
+{
+    abort();
+}
+#endif				/* 0 */
+
+void
+W_Initialize(str)
+    char   *str;
+{
+    int     i;
+
+#ifdef DEBUG
+    printf("Initializing...\n");
+#endif
+    for (i = 0; i < HASHSIZE; i++) {
+	hashtable[i] = NULL;
+    }
+    if ((W_Display = XOpenDisplay(str)) == NULL) {
+	fprintf(stderr, "Cannot open display \"%s\"\n", str ? str : "(null)");
+	EXIT(1);
+    }
+#if 0
+    /* tmp */
+    XSynchronize(W_Display, True);
+    XSetErrorHandler(_myerror);
+#endif
+
+    W_Root = DefaultRootWindow(W_Display);
+#ifdef FOURPLANEFIX
+    W_Visual = DefaultVisual(W_Display, DefaultScreen(W_Display));
+#endif
+    W_Screen = DefaultScreen(W_Display);
+    W_Colormap = DefaultColormap(W_Display, W_Screen);
+    myroot.window = W_Root;
+    myroot.type = WIN_GRAPH;
+    GetFonts();
+    GetColors();
+}
+
+static void
+GetFonts()
+{
+    Font    regular, italic, bold, big;
+    int     i;
+    XGCValues values;
+    XFontStruct *fontinfo;
+    char   *fontname;
+
+    fontname = getdefault("font");
+    if (fontname == NULL)
+	fontname = NORMAL_FONT;
+    fontinfo = XLoadQueryFont(W_Display, fontname);
+    if (fontinfo == NULL) {
+	fontinfo = find_font(fontname, _nfonts);
+    }
+    if (fontinfo == NULL) {
+	printf("netrek: Can't find any fonts!\n");
+	EXIT(1);
+    }
+    regular = fontinfo->fid;
+    W_Textwidth = fontinfo->max_bounds.width;
+    W_Textheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent;
+    fonts[1].baseline = fontinfo->max_bounds.ascent;
+    fonts[1].fontstruct = fontinfo;
+
+    fontname = getdefault("boldfont");
+    if (fontname == NULL) {
+	if (DisplayCells(W_Display, W_Screen) <= 4)
+	    fontname = BOLD_FONT2;
+	else
+	    fontname = BOLD_FONT;
+    }
+    fontinfo = XLoadQueryFont(W_Display, fontname);
+    if (fontinfo == NULL) {
+	fontinfo = find_font(fontname, _bfonts);
+    }
+    if (fontinfo == NULL) {
+	bold = regular;
+	fonts[2].baseline = fonts[1].baseline;
+	fonts[2].fontstruct = fonts[1].fontstruct;
+    } else {
+	bold = fontinfo->fid;
+	fonts[2].baseline = fontinfo->max_bounds.ascent;
+	fonts[2].fontstruct = fontinfo;
+	if (fontinfo->max_bounds.width > W_Textwidth)
+	    W_Textwidth = fontinfo->max_bounds.width;
+	if (fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent > W_Textheight)
+	    W_Textheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent;
+    }
+
+    fontname = getdefault("italicfont");
+    if (fontname == NULL) {
+	if (DisplayCells(W_Display, W_Screen) <= 4)
+	    fontname = ITALIC_FONT2;
+	else
+	    fontname = ITALIC_FONT;
+    }
+    fontinfo = XLoadQueryFont(W_Display, fontname);
+    if (fontinfo == NULL) {
+	fontinfo = find_font(fontname, _ifonts);
+    }
+    if (fontinfo == NULL) {
+	italic = regular;
+	fonts[3].baseline = fonts[1].baseline;
+	fonts[3].fontstruct = fonts[1].fontstruct;
+    } else {
+	italic = fontinfo->fid;
+	fonts[3].baseline = fontinfo->max_bounds.ascent;
+	fonts[3].fontstruct = fontinfo;
+	if (fontinfo->max_bounds.width > W_Textwidth)
+	    W_Textwidth = fontinfo->max_bounds.width;
+	if (fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent > W_Textheight)
+	    W_Textheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent;
+    }
+
+    fontname = getdefault("bigfont");
+    if (fontname == NULL)
+	fontname = BIG_FONT;
+    fontinfo = XLoadQueryFont(W_Display, fontname);
+    if (fontinfo == NULL) {
+	fontinfo = find_font(fontname, _bgfonts);
+    }
+    if (fontinfo == NULL) {
+	big = regular;
+	fonts[0].baseline = fonts[1].baseline;
+	fonts[0].fontstruct = fonts[1].fontstruct;
+    } else {
+	big = fontinfo->fid;
+	fonts[0].baseline = fontinfo->max_bounds.ascent;
+	fonts[0].fontstruct = fontinfo;
+    }
+    for (i = 0; i < NCOLORS; i++) {
+	values.font = big;
+	colortable[i].contexts[0] = XCreateGC(W_Display, W_Root, GCFont, &values);
+	XSetGraphicsExposures(W_Display, colortable[i].contexts[0], False);
+	values.font = regular;
+	colortable[i].contexts[1] = XCreateGC(W_Display, W_Root, GCFont, &values);
+	XSetGraphicsExposures(W_Display, colortable[i].contexts[1], False);
+	values.font = bold;
+	colortable[i].contexts[2] = XCreateGC(W_Display, W_Root, GCFont, &values);
+	XSetGraphicsExposures(W_Display, colortable[i].contexts[2], False);
+	values.font = italic;
+	colortable[i].contexts[3] = XCreateGC(W_Display, W_Root, GCFont, &values);
+	XSetGraphicsExposures(W_Display, colortable[i].contexts[3], False);
+	{
+	    static char dl[] = {1, 4};
+	    XSetLineAttributes(W_Display, colortable[i].contexts[3],
+			       0, LineOnOffDash, CapButt, JoinMiter);
+	    XSetDashes(W_Display, colortable[i].contexts[3], 0, dl, 2);
+	}
+	values.function = GXor;
+	colortable[i].contexts[BITGC] = XCreateGC(W_Display, W_Root, GCFunction, &values);
+	XSetGraphicsExposures(W_Display, colortable[i].contexts[BITGC], False);
+    }
+}
+
+static XFontStruct *
+find_font(oldf, fonts)
+    char   *oldf, **fonts;
+{
+    XFontStruct *fi;
+    char  **f;
+    fprintf(stderr, "netrek: Can't find font %s.  Trying others...\n",
+	    oldf);
+    for (f = fonts; *f; f++) {
+	if (strcmp(*f, oldf) != 0) {
+	    if ((fi = XLoadQueryFont(W_Display, *f)))
+		return fi;
+	}
+    }
+    printf("Error - can't find any font!\n");
+    return NULL;
+}
+
+#ifdef FOURPLANEFIX
+static unsigned short extrared[8] = {0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xb0, 0xc0};
+static unsigned short extragreen[8] = {0x40, 0x60, 0x80, 0xa0, 0xb0, 0xc0, 0x00, 0x20};
+static unsigned short extrablue[8] = {0x80, 0xa0, 0xb0, 0xc0, 0x00, 0x20, 0x40, 0x60};
+#endif
+
+int
+W_Mono()
+{
+    return forceMono;
+}
+
+static void
+GetColors()
+{
+    int     i, j;
+    XColor  foo;
+    int     white, black;
+    unsigned long pixel;
+    unsigned long planes[3];
+    char    defaultstring[100];
+    char   *defaults;
+#ifdef FOURPLANEFIX
+    unsigned long extracolors[8];
+    XColor  colordef;
+#endif
+    extern int forceMono;
+    forceMono = booleanDefault("forcemono", forceMono);
+
+    if ((DisplayCells(W_Display, W_Screen) <= 4) || forceMono) {
+	forceMono = 1;
+	white = WhitePixel(W_Display, W_Screen);
+	black = BlackPixel(W_Display, W_Screen);
+	for (i = 0; i < NCOLORS; i++) {
+	    if (i != W_Black) {
+		colortable[i].pixelValue = white;
+	    } else {
+		colortable[i].pixelValue = black;
+	    }
+	    if (i == W_Red) {
+		colortable[i].pixmap = XCreatePixmapFromBitmapData
+		    (W_Display,
+		     W_Root, (char *) striped, TILESIDE, TILESIDE,
+		     white, black,
+		     DefaultDepth(W_Display, W_Screen));
+	    } else if (i == W_Yellow) {
+		colortable[i].pixmap = XCreatePixmapFromBitmapData
+		    (W_Display,
+		     W_Root, (char *) gray, TILESIDE, TILESIDE,
+		     white, black,
+		     DefaultDepth(W_Display, W_Screen));
+	    } else {
+		colortable[i].pixmap = XCreatePixmapFromBitmapData
+		    (W_Display,
+		     W_Root, (char *) solid, TILESIDE, TILESIDE,
+		     colortable[i].pixelValue,
+		     colortable[i].pixelValue,
+		     DefaultDepth(W_Display, W_Screen));
+	    }
+
+	    /*
+	       We assume white is 0 or 1, and black is 0 or 1. We adjust
+	       graphics function based upon who is who.
+	    */
+	    if (white == 0) {	/* Black is 1 */
+		XSetFunction(W_Display, colortable[i].contexts[BITGC], GXand);
+	    }
+	}
+    } else if (DefaultVisual(W_Display, W_Screen)->class == TrueColor) {
+/* Stuff added by sheldon@iastate.edu 5/28/93
+ * This is supposed to detect a TrueColor display, and then do a lookup of
+ * the colors in default colormap, instead of creating new colormap
+ */
+	for (i = 0; i < NCOLORS; i++) {
+	    sprintf(defaultstring, "color.%s", colortable[i].name);
+
+	    defaults = getdefault(defaultstring);
+	    if (defaults == NULL)
+		defaults = colortable[i].name;
+	    XParseColor(W_Display, W_Colormap, defaults, &foo);
+	    XAllocColor(W_Display, W_Colormap, &foo);
+	    colortable[i].pixelValue = foo.pixel;
+	    colortable[i].pixmap = XCreatePixmapFromBitmapData(W_Display,
+	    W_Root, (char *) solid, TILESIDE, TILESIDE, foo.pixel, foo.pixel,
+					 DefaultDepth(W_Display, W_Screen));
+	}
+    } else {
+#ifdef FOURPLANEFIX
+	if (!XAllocColorCells(W_Display, W_Colormap, False, planes, 3,
+			      &pixel, 1)) {
+	    /* couldn't allocate 3 planes, make a new colormap */
+	    W_Colormap = XCreateColormap(W_Display, W_Root, W_Visual, AllocNone);
+	    if (!XAllocColorCells(W_Display, W_Colormap, False, planes, 3,
+				  &pixel, 1)) {
+		fprintf(stderr, "Cannot create new colormap\n");
+		EXIT(1);
+	    }
+	    /*
+	       and fill it with at least 8 more colors so when mouse is
+	       inside netrek windows, use might be able to see his other
+	       windows
+	    */
+	    if (XAllocColorCells(W_Display, W_Colormap, False, NULL, 0,
+				 extracolors, 8)) {
+		colordef.flags = DoRed | DoGreen | DoBlue;
+		for (i = 0; i < 8; i++) {
+		    colordef.pixel = extracolors[i];
+		    colordef.red = extrared[i] << 8;
+		    colordef.green = extragreen[i] << 8;
+		    colordef.blue = extrablue[i] << 8;
+		    XStoreColor(W_Display, W_Colormap, &colordef);
+		}
+	    }
+	}
+#else
+	XAllocColorCells(W_Display, W_Colormap, False, planes, 3, &pixel, 1);
+#endif
+	for (i = 0; i < NCOLORS; i++) {
+	    /*
+	       strcpy(defaultstring, "color.%s", colortable[i].name);
+	    */
+	    sprintf(defaultstring, "color.%s", colortable[i].name);
+
+	    defaults = getdefault(defaultstring);
+	    if (defaults == NULL)
+		defaults = colortable[i].name;
+	    XParseColor(W_Display, W_Colormap, defaults, &foo);
+	    /*
+	       Black must be the color with all the planes off. That is the
+	       only restriction I concerned myself with in the following case
+	       statement.
+	    */
+	    switch (i) {
+	    case WHITE:
+		foo.pixel = pixel | planes[0] | planes[1] | planes[2];
+		break;
+	    case BLACK:
+		foo.pixel = pixel;
+		break;
+	    case RED:
+		foo.pixel = pixel | planes[0];
+		break;
+	    case CYAN:
+		foo.pixel = pixel | planes[1];
+		break;
+	    case YELLOW:
+		foo.pixel = pixel | planes[2];
+		break;
+	    case GREY:
+		foo.pixel = pixel | planes[0] | planes[1];
+		break;
+	    case GREEN:
+		foo.pixel = pixel | planes[1] | planes[2];
+		break;
+	    }
+	    XStoreColor(W_Display, W_Colormap, &foo);
+	    colortable[i].pixelValue = foo.pixel;
+	    colortable[i].pixmap = XCreatePixmapFromBitmapData(W_Display,
+	    W_Root, (char *) solid, TILESIDE, TILESIDE, foo.pixel, foo.pixel,
+					 DefaultDepth(W_Display, W_Screen));
+	}
+    }
+    for (i = 0; i < NCOLORS; i++) {
+	for (j = 0; j < FONTS + 1; j++) {
+	    XSetForeground(W_Display, colortable[i].contexts[j],
+			   colortable[i].pixelValue);
+	    XSetBackground(W_Display, colortable[i].contexts[j],
+			   colortable[W_Black].pixelValue);
+	}
+    }
+}
+
+void
+W_RenameWindow(window, str)
+    W_Window window;
+    char   *str;
+{
+    XStoreName(W_Display, ((struct window *) window)->window, str);
+}
+
+static  W_Window
+w_MakeWindow(name, x, y, width, height, parent,
+	     cursname, border, color, wsort)
+    char   *name;
+    int     x, y, width, height;
+    W_Window parent;
+    char   *cursname;
+    int     border;
+    W_Color color;
+    int     wsort;		/* WIN_? */
+{
+    int     gx, gy;
+    struct window *newwin;
+    Window  wparent;
+    Cursor  cursor;
+    XSetWindowAttributes attrs;
+    int     pwidth, pheight;	/* pixel width and height */
+
+
+    checkGeometry(name, &gx, &gy, &width, &height);
+    if (gx != INVALID_POSITION)
+	x = gx;
+    if (gy != INVALID_POSITION)
+	y = gy;
+
+    checkParent(name, &parent);
+    wparent = W_Void2Window(parent)->window;
+
+    checkCursor(name, cursname, &cursor);
+    attrs.cursor = cursor;
+
+    attrs.border_pixel = colortable[color].pixelValue;
+    attrs.background_pixel = colortable[W_Black].pixelValue;
+
+    if (wsort == WIN_TEXT || wsort == WIN_SCROLL || wsort == WIN_MENU) {
+	pwidth = width * W_Textwidth + WIN_EDGE * 2;
+	if (wsort == WIN_MENU)
+	    pheight = height * (W_Textheight + MENU_PAD * 2 + MENU_BAR) - MENU_BAR;
+	else
+	    pheight = height * W_Textheight + MENU_PAD * 2;
+    } else {
+	pwidth = width;
+	pheight = height;
+    }
+
+    switch (wsort) {
+    case WIN_TEXT:
+    case WIN_MENU:
+	attrs.event_mask = KeyPressMask | ButtonPressMask | ExposureMask | ButtonReleaseMask;
+	attrs.do_not_propagate_mask = ExposureMask | KeyPressMask | ButtonPressMask;
+	break;
+    case WIN_GRAPH:
+	attrs.event_mask = KeyPressMask | ButtonPressMask | ExposureMask | LeaveWindowMask | ButtonReleaseMask | ButtonMotionMask;
+	attrs.do_not_propagate_mask = ExposureMask;
+	break;
+    case WIN_SCROLL:
+	attrs.event_mask = ResizeRedirectMask | ExposureMask | KeyPressMask | ButtonReleaseMask | ButtonPressMask;
+	attrs.do_not_propagate_mask = ResizeRedirectMask | ExposureMask;
+	break;
+    default:
+	fprintf(stderr, "x11window.c: w_MakeWindow: unknown wsort %d\n", wsort);
+    }
+
+#ifdef AUTOKEY
+    if (attrs.event_mask & KeyPressMask)
+	attrs.event_mask |= KeyReleaseMask;
+#endif				/* AUTOKEY */
+
+    if (strcmp(name, "netrek_icon") == 0)	/* icon should not select for
+						   input */
+	attrs.event_mask = ExposureMask;
+    if (strcmp(name, "wait_icon") == 0)	/* same here [BDyess] */
+	attrs.event_mask = ExposureMask;
+
+    if (strcmp(name, "info") == 0)	/* make info window passthru [BDyess] */
+	attrs.event_mask = ExposureMask;
+
+    newwin = newWindow
+	(XCreateWindow(W_Display, wparent, x, y, pwidth, pheight, border,
+		       CopyFromParent, InputOutput, CopyFromParent,
+		       CWBackPixel | CWBorderPixel | CWEventMask |
+		       (cursor ? CWCursor : 0),
+		       &attrs),
+	 wsort);
+
+    newwin->cursor = cursor;
+
+    {
+	char   *s;
+
+	if (0 == strcmp(name, "wait"))
+	    s = serverName;
+	else if (0 == strcmp(name, "Motd"))
+	    s = "Motd - [f] forward, [b] back, [tab] sysdefs, [space] unmap";
+	else if (0 == strcmp(name, "netrek")) {
+	    if (!title) {
+		char    buf[80];
+		sprintf(buf, "Netrek  @  %s", serverName);
+		s = buf;
+	    } else {
+		/* but title on command line will override */
+		/* from -h arg */
+		s = title;
+	    }
+	} else
+	    s = name;
+
+	XStoreName(W_Display, newwin->window, s);
+    }
+
+    wm_size_hint.width = wm_size_hint.min_width =
+	wm_size_hint.max_width = wm_size_hint.base_width = pwidth;
+    wm_size_hint.min_height = wm_size_hint.height =
+	wm_size_hint.max_height = wm_size_hint.base_height = pheight;
+    wm_size_hint.flags = USSize | PMinSize | PMaxSize | PBaseSize;
+    if (gx > INVALID_POSITION || gy > INVALID_POSITION) {
+	wm_size_hint.flags |= USPosition;
+	wm_size_hint.x = x;
+	wm_size_hint.y = y;
+    }
+    XSetWMNormalHints(W_Display, newwin->window, &wm_size_hint);
+
+    class_hint.res_name = name;
+    class_hint.res_class = "Netrek";
+    XSetClassHint(W_Display, newwin->window, &class_hint);
+
+    XSetWMHints(W_Display, newwin->window, &wm_hint);
+
+    if (((wparent == W_Root &&
+	  baseWin != NULL &&
+	  strcmp(name, "wait") != 0)
+	 || wsort == WIN_MENU) &&
+	strcmp(name, "MetaServer List") != 0 &&
+	strcmp(name, "Motd") != 0) {
+	XSetTransientForHint(W_Display, newwin->window,
+			     W_Void2Window(baseWin)->window);
+    }
+    newwin->name = strdup(name);
+    newwin->width = width;
+    newwin->height = height;
+    if (wsort == WIN_MENU) {
+	int     i;
+	struct menuItem *items;
+	items = (struct menuItem *) malloc(height * sizeof(struct menuItem));
+	for (i = 0; i < height; i++) {
+	    items[i].string = NULL;
+	    items[i].color = W_White;
+	    items[i].font = W_RegularFont;
+	}
+	newwin->data = (char *) items;
+    } else {
+	newwin->data = 0;
+    }
+
+    if (wparent != W_Root)
+	if (checkMapped(name))
+	    W_MapWindow(W_Window2Void(newwin));
+
+#ifdef DEBUG
+    printf("New graphics window %d, child of %d\n", newwin, parent);
+#endif
+
+#ifdef FOURPLANEFIX
+    XSetWindowColormap(W_Display, newwin->window, W_Colormap);
+#endif
+
+    return (W_Window2Void(newwin));
+}
+
+
+
+
+W_Window
+W_MakeWindow(name, x, y, width, height, parent, cursname, border, color)
+    char   *name;
+    int     x, y, width, height;
+    W_Window parent;
+    char   *cursname;
+    int     border;
+    W_Color color;
+{
+    return w_MakeWindow(name, x, y, width, height, parent,
+			cursname, border, color, WIN_GRAPH);
+}
+
+void
+W_ChangeBorder(window, color)
+    W_Window window;
+    int     color;
+{
+#ifdef DEBUG
+    printf("Changing border of %d\n", window);
+#endif
+
+    /* fix inexplicable color bug */
+    if (DisplayCells(W_Display, W_Screen) <= 2)
+	XSetWindowBorderPixmap(W_Display, W_Void2Window(window)->window,
+			       colortable[color].pixmap);
+    else
+	XSetWindowBorder(W_Display, W_Void2Window(window)->window,
+			 colortable[color].pixelValue);
+}
+
+void
+W_MapWindow(window)
+    W_Window window;
+{
+    struct window *win;
+
+#ifdef DEBUG
+    printf("Mapping %d\n", window);
+#endif
+    win = W_Void2Window(window);
+    if (win->mapped)
+	return;
+    win->mapped = 1;
+    XMapRaised(W_Display, win->window);
+}
+
+void
+W_UnmapWindow(window)
+    W_Window window;
+{
+    struct window *win;
+
+#ifdef DEBUG
+    printf("UnMapping %d\n", window);
+#endif
+    win = W_Void2Window(window);
+    if (win->mapped == 0)
+	return;
+    win->mapped = 0;
+    XUnmapWindow(W_Display, win->window);
+}
+
+int
+W_IsMapped(window)
+    W_Window window;
+{
+    struct window *win;
+
+    win = W_Void2Window(window);
+    if (win == NULL)
+	return (0);
+    return (win->mapped);
+}
+
+void
+W_FillArea(window, x, y, width, height, color)
+    W_Window window;
+    int     x, y, width, height;
+    W_Color color;
+{
+    struct window *win;
+
+#ifdef DEBUG
+    printf("Clearing (%d %d) x (%d %d) with %d on %d\n", x, y, width, height,
+	   color, window);
+#endif
+    win = W_Void2Window(window);
+    switch (win->type) {
+    case WIN_GRAPH:
+	XFillRectangle(W_Display, win->window, colortable[color].contexts[0],
+		       x, y, width, height);
+	break;
+    default:
+	XFillRectangle(W_Display, win->window, colortable[color].contexts[0],
+		    WIN_EDGE + x * W_Textwidth, MENU_PAD + y * W_Textheight,
+		       width * W_Textwidth, height * W_Textheight);
+    }
+}
+
+/* XFIX */
+
+static XRectangle _rcache[MAXCACHE];
+static int _rcache_index;
+
+static void
+FlushClearAreaCache(win)
+    Window  win;
+{
+    XFillRectangles(W_Display, win, colortable[backColor].contexts[0],
+		    _rcache, _rcache_index);
+    _rcache_index = 0;
+}
+
+/* local window only */
+void
+W_CacheClearArea(window, x, y, width, height)
+    W_Window window;
+    int     x, y, width, height;
+{
+    Window  win = W_Void2Window(window)->window;
+    register XRectangle *r;
+
+    if (_rcache_index == MAXCACHE)
+	FlushClearAreaCache(win);
+
+    r = &_rcache[_rcache_index++];
+    r->x = (short) x;
+    r->y = (short) y;
+    r->width = (unsigned short) width;
+    r->height = (unsigned short) height;
+}
+
+void
+W_FlushClearAreaCache(window)
+    W_Window window;
+{
+    Window  win = W_Void2Window(window)->window;
+
+    if (_rcache_index)
+	FlushClearAreaCache(win);
+}
+
+/* XFIX: clears now instead of filling. */
+void
+W_ClearArea(window, x, y, width, height)
+    W_Window window;
+    int     x, y, width, height;
+{
+    struct window *win;
+
+#ifdef DEBUG
+    printf("Clearing (%d %d) x (%d %d) with %d on %d\n", x, y, width, height,
+	   color, window);
+#endif
+    win = W_Void2Window(window);
+    switch (win->type) {
+    case WIN_GRAPH:
+	/* XFIX: changed */
+	XClearArea(W_Display, win->window, x, y, width, height, False);
+	break;
+    default:
+	/* XFIX: changed */
+	XClearArea(W_Display, win->window, WIN_EDGE + x * W_Textwidth,
+		   MENU_PAD + y * W_Textheight, width * W_Textwidth, height * W_Textheight, False);
+	break;
+    }
+}
+
+void
+W_ClearWindow(window)
+    W_Window window;
+{
+#ifdef DEBUG
+    printf("Clearing %d\n", window);
+#endif
+    XClearWindow(W_Display, W_Void2Window(window)->window);
+}
+
+void
+W_GetEvent(wevent)
+    W_Event *wevent;
+{
+/* blocks until an event is received [BDyess] */
+    XEvent  event;
+
+    if (W_isEvent) {
+	*wevent = W_myevent;
+	W_isEvent = 0;
+	return;
+    }
+    XNextEvent(W_Display, &event);
+    XPutBackEvent(W_Display, &event);
+    W_SpNextEvent(wevent);
+}
+
+int
+W_EventsPending()
+{
+    if (W_isEvent)
+	return (1);
+    while (XPending(W_Display) || buttonDown) {
+	if (W_SpNextEvent(&W_myevent)) {
+	    W_isEvent = 1;
+	    return (1);
+	}
+    }
+    return (0);
+}
+
+void
+W_NextEvent(wevent)
+    W_Event *wevent;
+{
+    if (W_isEvent) {
+	*wevent = W_myevent;
+	W_isEvent = 0;
+	return;
+    }
+    while (W_SpNextEvent(wevent) == 0);
+}
+
+static int
+W_SpNextEvent(wevent)
+    W_Event *wevent;
+{
+    XEvent  event;
+    XKeyEvent *key;
+    XButtonEvent *button;
+    XExposeEvent *expose;
+    XResizeRequestEvent *resize;
+    char    ch;
+    struct window *win;
+#ifdef CONTINUOUS_MOUSE
+    static W_Event buttonEvent;
+    static int delay, cupd = -1;
+#endif				/* CONTINUOUS_MOUSE */
+
+#ifdef DEBUG
+    printf("Getting an event...\n");
+#endif
+    key = (XKeyEvent *) & event;
+    button = (XButtonEvent *) & event;
+    expose = (XExposeEvent *) & event;
+    resize = (XResizeRequestEvent *) & event;
+    for (;;) {
+	if (XPending(W_Display))
+	    XNextEvent(W_Display, &event);
+#ifdef CONTINUOUS_MOUSE
+	else if (buttonDown) {
+	    if (continuousMouse && allowContinuousMouse) {
+		if (cupd != udcounter) {
+		    cupd = udcounter;
+		    if (delay == 0) {
+			bcopy(&buttonEvent, wevent, sizeof(W_Event));
+			delay = clickDelay;
+		    } else {
+			delay--;
+			wevent->type = -1;
+		    }
+		} else
+		    wevent->type = -1;
+		exitInputLoop = 1;
+	    } else {
+		wevent->type = -1;
+		buttonDown = 0;
+	    }
+	    return (1);
+	}
+#endif
+	else
+	    return (0);
+	/*
+	   printf("read an event %d\n", event.type);
+	*/
+	win = findWindow(key->window);
+	if (win == NULL)
+	    return (0);
+	if ((event.type == KeyPress || event.type == ButtonPress) &&
+	    win->type == WIN_MENU) {
+	    if (key->y % (W_Textheight + MENU_PAD * 2 + MENU_BAR) >=
+		W_Textheight + MENU_PAD * 2)
+		return (0);
+	    key->y = key->y / (W_Textheight + MENU_PAD * 2 + MENU_BAR);
+	}
+	switch ((int) event.type) {
+	case LeaveNotify:	/* for message window -- jfy */
+	    if (win == (struct window *) messagew) {
+		W_in_message = 0;
+	    }
+	    return (0);
+	    break;
+	case KeyPress:
+	    if (key->state & ControlMask) {
+		controlkey = 1;
+		key->state &= ~ControlMask;
+	    } else
+		controlkey = 0;
+	    if (key->state & BillsScrewyAltMask) {
+		altkey = 1;
+		key->state &= ~BillsScrewyAltMask;
+	    } else
+		altkey = 0;
+	    if (XLookupString(key, &ch, 1, NULL, NULL) > 0) {
+		wevent->type = W_EV_KEY;
+		wevent->Window = W_Window2Void(win);
+		wevent->x = key->x;
+		wevent->y = key->y;
+		if (controlkey)
+		    wevent->key = (int) ch + 128;
+		else if (altkey)
+		    wevent->key = (int) ch + 256;
+		else
+		    wevent->key = ch;
+		return (1);
+	    }
+	    return (0);
+	    break;
+#ifdef AUTOKEY
+	case KeyRelease:
+	    if (XLookupString(key, &ch, 1, NULL, NULL) > 0) {
+		wevent->type = W_EV_KEY_OFF;
+		wevent->Window = W_Window2Void(win);
+		wevent->x = key->x;
+		wevent->y = key->y;
+		wevent->key = ch;
+		return (1);
+	    }
+	    return (0);
+	    break;
+#endif				/* AUTOKEY */
+	case ButtonPress:
+	    wevent->type = W_EV_BUTTON;
+	    wevent->Window = W_Window2Void(win);
+	    wevent->x = button->x;
+	    wevent->y = button->y;
+	    switch (button->button & 0xf) {
+	    case Button3:
+		wevent->key = W_RBUTTON;
+		break;
+	    case Button1:
+		wevent->key = W_LBUTTON;
+		break;
+	    case Button2:
+		wevent->key = W_MBUTTON;
+		break;
+	    }
+	    if (key->state & ControlMask)
+		wevent->key += 6;
+	    if (key->state & ShiftMask)
+		wevent->key += 3;
+	    if (key->state & BillsScrewyAltMask)
+		wevent->key += 12;	/* alt */
+#ifdef CONTINUOUS_MOUSE
+	    if (continuousMouse && allowContinuousMouse &&
+		(wevent->Window == w || wevent->Window == mapw) &&
+	    /*
+	       buttonRepeatMask allows only certain buttons to repeat
+	       [BDyess]
+	    */
+		(1 << (wevent->key) & buttonRepeatMask)) {
+		buttonDown = 1;
+		exitInputLoop = 1;
+		delay = clickDelay;
+		bcopy(wevent, &buttonEvent, sizeof(W_Event));
+	    }
+	    return (1);
+	case ButtonRelease:
+	    /* bcopy(&buttonEvent,wevent,sizeof(W_Event)); */
+	    wevent->type = -1;
+	    buttonDown = 0;
+	    return (1);
+	case MotionNotify:
+	    /*
+	       the !buttonDown ensures that if you press a button and then
+	       press another, release just the second, and then move the
+	       mouse that nothing happens.
+	    */
+	    if (!(continuousMouse && allowContinuousMouse) || !buttonDown) {
+		wevent->type = -1;
+		return (1);
+	    }
+	    wevent->type = W_EV_BUTTON;
+	    wevent->Window = W_Window2Void(win);
+	    wevent->x = button->x;
+	    wevent->y = button->y;
+	    wevent->key = buttonEvent.key;
+	    bcopy(wevent, &buttonEvent, sizeof(W_Event));
+	    if (cupd == udcounter)
+		wevent->type = -1;
+	    else
+		cupd = udcounter;
+
+	    return (1);
+#else
+	    return (1);
+#endif				/* CONTINUOUS_MOUSE */
+	case Expose:
+	    if (expose->count != 0)
+		return (0);
+	    if (win->type == WIN_SCROLL) {
+		redrawScrolling(win);
+		return (0);
+	    }
+	    if (win->type == WIN_MENU) {
+		redrawMenu(win);
+		return (0);
+	    }
+	    wevent->type = W_EV_EXPOSE;
+	    wevent->Window = W_Window2Void(win);
+	    return (1);
+	case ResizeRequest:
+	    resizeScrolling(win, resize->width, resize->height);
+	    break;
+	default:
+	    return (0);
+	    break;
+	}
+    }
+}
+
+void
+W_MakeLine(window, x0, y0, x1, y1, color)
+    W_Window window;
+    int     x0, y0, x1, y1;
+    W_Color color;
+{
+    Window  win;
+
+#ifdef DEBUG
+    printf("Line on %d\n", window);
+#endif
+    win = W_Void2Window(window)->window;
+    XDrawLine(W_Display, win, colortable[color].contexts[0], x0, y0, x1, y1);
+}
+
+void
+W_DrawPoint(window, x, y, color)
+    W_Window window;
+    int     x, y;
+    W_Color color;
+{
+    Window  win;
+
+#ifdef DEBUG
+    printf("Point on %d\n", window);
+#endif
+    win = W_Void2Window(window)->window;
+    XDrawPoint(W_Display, win, colortable[color].contexts[0], x, y);
+}
+
+/* XFIX */
+
+static XSegment _lcache[NCOLORS][MAXCACHE];
+static int _lcache_index[NCOLORS];
+
+static void
+FlushLineCache(win, color)
+    Window  win;
+    int     color;
+{
+    XDrawSegments(W_Display, win, colortable[color].contexts[0],
+		  _lcache[color], _lcache_index[color]);
+    _lcache_index[color] = 0;
+}
+
+/* for local window only */
+void
+W_CacheLine(window, x0, y0, x1, y1, color)
+    W_Window window;
+    int     x0, y0, x1, y1, color;
+{
+    Window  win = W_Void2Window(window)->window;
+    register XSegment *s;
+
+    if (_lcache_index[color] == MAXCACHE)
+	FlushLineCache(win, color);
+
+    s = &_lcache[color][_lcache_index[color]++];
+    s->x1 = (short) x0;
+    s->y1 = (short) y0;
+    s->x2 = (short) x1;
+    s->y2 = (short) y1;
+}
+
+void
+W_FlushLineCaches(window)
+    W_Window window;
+{
+    Window  win = W_Void2Window(window)->window;
+    register i;
+    for (i = 0; i < NCOLORS; i++) {
+	if (_lcache_index[i])
+	    FlushLineCache(win, i);
+    }
+}
+
+static XPoint _pcache[NCOLORS][MAXCACHE];
+static int _pcache_index[NCOLORS];
+
+static void
+FlushPointCache(win, color)
+    Window  win;
+    int     color;
+{
+    XDrawPoints(W_Display, win, colortable[color].contexts[0],
+		_pcache[color], _pcache_index[color], CoordModeOrigin);
+    _pcache_index[color] = 0;
+}
+
+void
+W_CachePoint(window, x, y, color)
+    W_Window window;
+    int     x, y, color;
+{
+    Window  win = W_Void2Window(window)->window;
+    register XPoint *p;
+
+    if (_pcache_index[color] == MAXCACHE)
+	FlushPointCache(win, color);
+
+    p = &_pcache[color][_pcache_index[color]++];
+    p->x = (short) x;
+    p->y = (short) y;
+}
+
+void
+W_FlushPointCaches(window)
+    W_Window window;
+{
+    Window  win = W_Void2Window(window)->window;
+    register i;
+    for (i = 0; i < NCOLORS; i++) {
+	if (_pcache_index[i])
+	    FlushPointCache(win, i);
+    }
+}
+
+void
+W_MakeTractLine(window, x0, y0, x1, y1, color)
+    W_Window window;
+    int     x0, y0, x1, y1;
+    W_Color color;
+{
+    Window  win;
+
+#ifdef DEBUG
+    printf("Line on %d\n", window);
+#endif
+    win = W_Void2Window(window)->window;
+    XDrawLine(W_Display, win, colortable[color].contexts[3], x0, y0, x1, y1);
+}
+
+void
+W_DrawSectorHighlight(window, x, y, w, h, color)
+    W_Window window;
+    int     x, y, w, h;
+    W_Color color;
+{
+    Window  win;
+#ifdef YUCK
+    XRectangle r[2];
+
+    r[0].x = (short) x;
+    r[0].y = (short) y;
+    r[0].width = (unsigned short) w;
+    r[0].height = (unsigned short) h;
+    r[1].x = (short) x + 2;
+    r[1].y = (short) y + 2;
+    r[1].width = (unsigned short) w - 4;
+    r[1].height = (unsigned short) h - 4;
+
+    win = W_Void2Window(window)->window;
+    XDrawRectangles(W_Display, win, colortable[color].contexts[3],
+		    r, 2);
+#else
+    XRectangle r[1];
+
+    r[0].x = (short) x + 2;
+    r[0].y = (short) y + 2;
+    r[0].width = (unsigned short) w - 4;
+    r[0].height = (unsigned short) h - 4;
+
+    win = W_Void2Window(window)->window;
+    XDrawRectangles(W_Display, win, colortable[color].contexts[3],
+		    r, 1);
+#endif
+}
+
+void
+W_WriteTriangle(window, x, y, s, t, color)
+    W_Window window;
+    int     x, y, s;
+    int     t;
+    W_Color color;
+{
+    struct window *win = W_Void2Window(window);
+    XPoint  points[3];
+
+    if (t == 0) {
+	points[0].x = x;
+	points[0].y = y;
+	points[1].x = x + s;
+	points[1].y = y - s;
+	points[2].x = x - s;
+	points[2].y = y - s;
+    } else {
+	points[0].x = x;
+	points[0].y = y;
+	points[1].x = x + s;
+	points[1].y = y + s;
+	points[2].x = x - s;
+	points[2].y = y + s;
+    }
+
+
+    XFillPolygon(W_Display, win->window, colortable[color].contexts[0],
+		 points, 3, Convex, CoordModeOrigin);
+}
+
+void
+W_WriteText(window, x, y, color, str, len, font)
+    W_Window window;
+    int     x, y, len;
+    W_Color color;
+    W_Font  font;
+    char   *str;
+{
+    struct window *win;
+    int     addr;
+
+    if (!font)
+	font = W_RegularFont;
+#ifdef DEBUG
+    printf("Text for %d @ (%d, %d) in %d: [%s]\n", window, x, y, color, str);
+#endif
+    win = W_Void2Window(window);
+    switch (win->type) {
+    case WIN_GRAPH:
+	addr = fonts[fontNum(font)].baseline;
+	XDrawImageString(W_Display, win->window,
+	  colortable[color].contexts[fontNum(font)], x, y + addr, str, len);
+	break;
+    case WIN_SCROLL:
+	if (y<0) {
+	  XCopyArea(W_Display, win->window, win->window,
+
+		    colortable[W_White].contexts[0], WIN_EDGE, MENU_PAD,
+		    win->width * W_Textwidth, (win->height - 1) * W_Textheight,
+		    WIN_EDGE, MENU_PAD+W_Textheight);
+	  XClearArea(W_Display, win->window,
+		     WIN_EDGE, MENU_PAD,
+		     W_Textwidth * win->width, W_Textheight, False);
+	  XDrawImageString(W_Display, win->window,
+			   colortable[color].contexts[1],
+			   WIN_EDGE, MENU_PAD + fonts[1].baseline,
+			   str, len);
+	} else {
+	  XCopyArea(W_Display, win->window, win->window,
+		    colortable[W_White].contexts[0], WIN_EDGE, MENU_PAD + W_Textheight,
+		    win->width * W_Textwidth, (win->height - 1) * W_Textheight,
+		    WIN_EDGE, MENU_PAD);
+	  XClearArea(W_Display, win->window,
+		     WIN_EDGE, MENU_PAD + W_Textheight * (win->height - 1),
+		     W_Textwidth * win->width, W_Textheight, False);
+	  XDrawImageString(W_Display, win->window,
+			   colortable[color].contexts[1],
+			   WIN_EDGE, MENU_PAD + W_Textheight * (win->height - 1) + fonts[1].baseline,
+			   str, len);
+	}
+	AddToScrolling(win, color, str, len);
+	break;
+    case WIN_MENU:
+	changeMenuItem(win, y, color, str, len, font);
+	break;
+    default:
+	addr = fonts[fontNum(font)].baseline;
+	XDrawImageString(W_Display, win->window,
+			 colortable[color].contexts[fontNum(font)],
+	     x * W_Textwidth + WIN_EDGE, MENU_PAD + y * W_Textheight + addr,
+			 str, len);
+	break;
+    }
+}
+
+void
+W_MaskText(window, x, y, color, str, len, font)
+    W_Window window;
+    int     x, y, len;
+    W_Color color;
+    W_Font  font;
+    char   *str;
+{
+    struct window *win;
+    int     addr;
+
+    addr = fonts[fontNum(font)].baseline;
+#ifdef DEBUG
+    printf("TextMask for %d @ (%d, %d) in %d: [%s]\n", window, x, y, color, str);
+#endif
+    win = W_Void2Window(window);
+    XDrawString(W_Display, win->window,
+	  colortable[color].contexts[fontNum(font)], x, y + addr, str, len);
+}
+
+W_Icon
+W_StoreBitmap(width, height, data, window)
+    int     width, height;
+    W_Window window;
+    char   *data;
+{
+    struct icon *newicon;
+    struct window *win;
+
+#ifdef DEBUG
+    printf("Storing bitmap for %d (%d x %d)\n", window, width, height);
+    fflush(stdout);
+#endif
+    win = W_Void2Window(window);
+    newicon = (struct icon *) malloc(sizeof(struct icon));
+    newicon->width = width;
+    newicon->height = height;
+    newicon->bitmap = XCreateBitmapFromData(W_Display, win->window,
+					    data, width, height);
+    newicon->window = win->window;
+    newicon->pixmap = 0;
+    return (W_Icon2Void(newicon));
+}
+
+void
+W_FreeBitmap(bit)
+    W_Icon  bit;
+{
+    struct icon *icon;
+    icon = W_Void2Icon(bit);
+    XFreePixmap(W_Display, icon->bitmap);
+    free(icon);
+}
+
+void
+W_WriteBitmap(x, y, bit, color)
+    int     x, y;
+    W_Icon  bit;
+    W_Color color;
+{
+    struct icon *icon;
+
+    icon = W_Void2Icon(bit);
+#ifdef DEBUG
+    printf("Writing bitmap to %d\n", icon->window);
+#endif
+
+    XCopyPlane(W_Display, icon->bitmap, icon->window,
+	 colortable[color].contexts[BITGC], 0, 0, icon->width, icon->height,
+	       x, y, 1);
+
+}
+
+void
+W_WriteWinBitmap(win, x, y, bit, color)
+    W_Window win;
+    int     x, y;
+    W_Icon  bit;
+    W_Color color;
+{
+    struct icon *icon;
+    Window  original;
+
+    icon = W_Void2Icon(bit);
+    original = icon->window;
+    icon->window = W_Void2Window(win)->window;
+    W_WriteBitmap(x, y, bit, color);
+    icon->window = original;
+    return;
+}
+
+void
+W_TileWindow(window, bit)
+    W_Window window;
+    W_Icon  bit;
+{
+    Window  win;
+    struct icon *icon;
+
+#ifdef DEBUG
+    printf("Tiling window %d\n", window);
+#endif
+    icon = W_Void2Icon(bit);
+    win = W_Void2Window(window)->window;
+
+    if (icon->pixmap == 0) {
+	icon->pixmap = XCreatePixmap(W_Display, W_Root,
+	      icon->width, icon->height, DefaultDepth(W_Display, W_Screen));
+	XCopyPlane(W_Display, icon->bitmap, icon->pixmap,
+	   colortable[W_White].contexts[0], 0, 0, icon->width, icon->height,
+		   0, 0, 1);
+    }
+    XSetWindowBackgroundPixmap(W_Display, win, icon->pixmap);
+    XClearWindow(W_Display, win);
+
+    /*
+       if (icon->pixmap==0) { icon->pixmap=XMakePixmap(icon->bitmap,
+       colortable[W_White].pixelValue, colortable[W_Black].pixelValue); }
+       XChangeBackground(win, icon->pixmap); XClear(win);
+    */
+}
+
+void
+W_UnTileWindow(window)
+    W_Window window;
+{
+    Window  win;
+
+#ifdef DEBUG
+    printf("Untiling window %d\n", window);
+#endif
+    win = W_Void2Window(window)->window;
+
+    XSetWindowBackground(W_Display, win, colortable[W_Black].pixelValue);
+    XClearWindow(W_Display, win);
+}
+
+W_Window
+W_MakeTextWindow(name, x, y, width, height, parent, cursname, border)
+    char   *name;
+    int     x, y, width, height;
+    W_Window parent;
+    char   *cursname;
+    int     border;
+{
+    return w_MakeWindow(name, x, y, width, height,
+			parent, cursname, border, W_White, WIN_TEXT);
+}
+
+struct window *
+newWindow(window, type)
+    Window  window;
+    int     type;
+{
+    struct window *newwin;
+
+    newwin = (struct window *) malloc(sizeof(struct window));
+    newwin->window = window;
+    newwin->type = type;
+    newwin->mapped = 0;
+    newwin->insensitive = 0;
+    addToHash(newwin);
+    return (newwin);
+}
+
+
+static struct window *
+findWindow(window)
+    Window  window;
+{
+    struct windowlist *entry;
+
+    entry = hashtable[hash(window)];
+    while (entry != NULL) {
+	if (entry->window->window == window)
+	    return (entry->window);
+	entry = entry->next;
+    }
+    return (NULL);
+}
+
+static void
+addToHash(win)
+    struct window *win;
+{
+    struct windowlist **new;
+
+#ifdef DEBUG
+    printf("Adding to %d\n", hash(win->window));
+#endif
+    new = &hashtable[hash(win->window)];
+    while (*new != NULL) {
+	new = &((*new)->next);
+    }
+    *new = (struct windowlist *) malloc(sizeof(struct windowlist));
+    (*new)->next = NULL;
+    (*new)->window = win;
+}
+
+W_Window
+W_MakeScrollingWindow(name, x, y, width, height, parent, cursname, border)
+    char   *name;
+    int     x, y, width, height;
+    W_Window parent;
+    char   *cursname;
+    int     border;
+{
+    return w_MakeWindow(name, x, y, width, height, parent, cursname,
+			border, W_White, WIN_SCROLL);
+}
+
+/* Add a string to the string list of the scrolling window.
+ */
+static void
+AddToScrolling(win, color, str, len)
+    struct window *win;
+    W_Color color;
+    char   *str;
+    int     len;
+{
+    struct stringList **strings;
+    char   *newstring;
+    int     count;
+
+    strings = (struct stringList **) & (win->data);
+    count = 0;
+    while ((*strings) != NULL) {
+	count++;
+	strings = &((*strings)->next);
+    }
+    (*strings) = (struct stringList *) malloc(sizeof(struct stringList));
+    (*strings)->next = NULL;
+    (*strings)->color = color;
+    newstring = (char *) malloc(len + 1);
+    strncpy(newstring, str, len);
+    newstring[len] = 0;
+    (*strings)->string = newstring;
+    if (count >= 100) {		/* Arbitrary large size. */
+	struct stringList *temp;
+
+	temp = (struct stringList *) win->data;
+	free(temp->string);
+	temp = temp->next;
+	free((char *) win->data);
+	win->data = (char *) temp;
+    }
+}
+
+#ifdef SHORT_PACKETS
+void
+W_SetSensitive(w, v)
+    W_Window w;
+    int     v;
+{
+    struct window *win = W_Void2Window(w);
+
+    win->insensitive = !v;
+
+    if (win->type == WIN_SCROLL)
+	redrawScrolling(win);
+}
+#endif
+
+static void
+redrawScrolling(win)
+    struct window *win;
+{
+    int     count;
+    struct stringList *list;
+    int     y;
+
+    XClearWindow(W_Display, win->window);
+    count = 0;
+    list = (struct stringList *) win->data;
+    while (list != NULL) {
+	list = list->next;
+	count++;
+    }
+    list = (struct stringList *) win->data;
+    while (count > win->height) {
+	list = list->next;
+	count--;
+    }
+    y = (win->height - count) * W_Textheight + fonts[1].baseline;
+    if (count == 0)
+	return;
+    while (list != NULL) {
+	XDrawImageString(W_Display, win->window,
+			 colortable[list->color].contexts[1],
+		WIN_EDGE, MENU_PAD + y, list->string, strlen(list->string));
+	list = list->next;
+	y = y + W_Textheight;
+    }
+}
+
+static void
+resizeScrolling(win, width, height)
+    struct window *win;
+    int     width, height;
+{
+    win->height = (height - MENU_PAD * 2) / W_Textheight;
+    win->width = (width - WIN_EDGE * 2) / W_Textwidth;
+    XResizeWindow(W_Display, win->window, win->width * W_Textwidth + WIN_EDGE * 2,
+		  win->height * W_Textheight + MENU_PAD * 2);
+}
+
+W_Window
+W_MakeMenu(name, x, y, width, height, parent, border)
+    char   *name;
+    int     x, y, width, height;
+    W_Window parent;
+    int     border;
+{
+    return w_MakeWindow(name, x, y, width, height, parent,
+			"left_ptr", border, W_White, WIN_MENU);
+}
+
+static void
+redrawMenu(win)
+    struct window *win;
+{
+    int     count;
+
+    for (count = 1; count < win->height; count++) {
+	XFillRectangle(W_Display, win->window,
+		       colortable[W_Grey].contexts[0],
+	  0, count * (W_Textheight + MENU_PAD * 2) + (count - 1) * MENU_BAR,
+		       win->width * W_Textwidth + WIN_EDGE * 2, MENU_BAR);
+    }
+    for (count = 0; count < win->height; count++) {
+	redrawMenuItem(win, count);
+    }
+}
+
+static void
+redrawMenuItem(win, n)
+    struct window *win;
+    int     n;
+{
+    struct menuItem *items;
+    int     addr;
+
+    items = (struct menuItem *) win->data;
+
+    XFillRectangle(W_Display, win->window,
+		   colortable[W_Black].contexts[0],
+	  WIN_EDGE, n * (W_Textheight + MENU_PAD * 2 + MENU_BAR) + MENU_PAD,
+		   win->width * W_Textwidth, W_Textheight);
+    if (items[n].string) {
+	addr = fonts[fontNum(items[n].font)].baseline;
+	XDrawImageString(W_Display, win->window,
+		colortable[items[n].color].contexts[fontNum(items[n].font)],
+			 WIN_EDGE,
+	     n * (W_Textheight + MENU_PAD * 2 + MENU_BAR) + MENU_PAD + addr,
+			 items[n].string, strlen(items[n].string));
+    }
+}
+
+static void
+changeMenuItem(win, n, color, str, len, font)
+    struct window *win;
+    int     n;
+    W_Color color;
+    char   *str;
+    int     len;
+    W_Font  font;
+{
+    struct menuItem *items;
+    char   *news;
+
+    items = (struct menuItem *) win->data;
+    if (items[n].string) {
+	free(items[n].string);
+    }
+    news = malloc(len + 1);
+    strncpy(news, str, len);
+    news[len] = 0;
+    items[n].string = news;
+    items[n].color = color;
+    items[n].font = font;
+    redrawMenuItem(win, n);
+    XFlush(W_Display);
+}
+
+static  Cursor
+make_cursor(bits, mask, width, height, xhot, yhot)
+    char   *bits, *mask;
+    int     width, height, xhot, yhot;
+{
+    Pixmap  cursbits;
+    Pixmap  cursmask;
+    XColor  whiteCol, blackCol;
+    Cursor  curs;
+
+    whiteCol.pixel = colortable[W_White].pixelValue;
+    XQueryColor(W_Display, W_Colormap, &whiteCol);
+    blackCol.pixel = colortable[W_Black].pixelValue;
+    XQueryColor(W_Display, W_Colormap, &blackCol);
+
+    cursbits = XCreateBitmapFromData(W_Display, DefaultRootWindow(W_Display),
+				     bits, width, height);
+    cursmask = XCreateBitmapFromData(W_Display, DefaultRootWindow(W_Display),
+				     mask, width, height);
+
+    curs = XCreatePixmapCursor(W_Display, cursbits, cursmask,
+			       &whiteCol, &blackCol, xhot, yhot);
+
+    XFreePixmap(W_Display, cursbits);
+    XFreePixmap(W_Display, cursmask);
+    return curs;
+}
+
+#ifdef TCURSORS
+#if 1
+
+void
+W_DefineTCrossCursor(window)
+    W_Window window;
+{
+    return;
+}
+
+void
+W_DefineTextCursor(window)
+    W_Window window;
+{
+    static Cursor new = 0;
+    struct window *win = W_Void2Window(window);
+    XColor  f, b;
+
+    if (!new) {
+	f.pixel = colortable[W_Yellow].pixelValue;
+	b.pixel = colortable[W_Black].pixelValue;
+
+	XQueryColor(W_Display, W_Colormap, &f);
+	XQueryColor(W_Display, W_Colormap, &b);
+
+	new = XCreateFontCursor(W_Display, XC_xterm);
+
+	XRecolorCursor(W_Display, new, &f, &b);
+    }
+    XDefineCursor(W_Display, win->window, new);
+
+    return;
+}
+
+void
+W_RevertCursor(window)
+    W_Window window;
+{
+    struct window *win = W_Void2Window(window);
+
+    XDefineCursor(W_Display, win->window, win->cursor);
+
+    return;
+}
+
+void
+W_DefineCursor(window, width, height, bits, mask, xhot, yhot)
+    W_Window window;
+    int     width, height, xhot, yhot;
+    char   *bits, *mask;
+{
+    return;
+}
+
+#else
+
+#ifdef YUCK
+void
+W_DefineTCrossCursor(window)
+    W_Window window;
+{
+    static
+    Cursor  new;
+    struct window *win = W_Void2Window(window);
+    static
+    XColor  f, b;
+
+    if (new) {
+	XDefineCursor(W_Display, win->window, new);
+	return;
+    }
+    f.pixel = colortable[W_White].pixelValue;
+    b.pixel = colortable[W_Black].pixelValue;
+
+    XQueryColor(W_Display, W_Colormap, &f);
+    XQueryColor(W_Display, W_Colormap, &b);
+
+    new = XCreateFontCursor(W_Display, XC_tcross);
+    XRecolorCursor(W_Display, new, &f, &b);
+    XDefineCursor(W_Display, win->window, new);
+}
+
+#else
+W_DefineTCrossCursor(window)
+    W_Window window;
+{
+    W_DefineCursor(window, cross_width, cross_height,
+		   cross_bits, crossmask_bits, cross_x_hot, cross_y_hot);
+}
+
+#endif
+
+void
+W_DefineTextCursor(window)
+    W_Window window;
+{
+    static
+    Cursor  new;
+    struct window *win = W_Void2Window(window);
+    XColor  f, b;
+
+    if (new) {
+	XDefineCursor(W_Display, win->window, new);
+	return;
+    }
+    f.pixel = colortable[W_Yellow].pixelValue;
+    b.pixel = colortable[W_Black].pixelValue;
+
+    XQueryColor(W_Display, W_Colormap, &f);
+    XQueryColor(W_Display, W_Colormap, &b);
+
+    new = XCreateFontCursor(W_Display, XC_xterm);
+    XRecolorCursor(W_Display, new, &f, &b);
+    XDefineCursor(W_Display, win->window, new);
+}
+
+void
+W_DefineCursor(window, width, height, bits, mask, xhot, yhot)
+    W_Window window;
+    int     width, height, xhot, yhot;
+    char   *bits, *mask;
+{
+    static char *oldbits = NULL;
+    static Cursor curs;
+    struct window *win;
+
+#ifdef DEBUG
+    printf("Defining cursor for %d\n", window);
+#endif
+    win = W_Void2Window(window);
+    if (!oldbits || oldbits != bits) {
+	oldbits = bits;
+	curs = make_cursor(bits, mask, width, height, xhot, yhot);
+    }
+    XDefineCursor(W_Display, win->window, curs);
+}
+#endif
+#endif
+
+void
+W_Beep()
+{
+    XBell(W_Display, 0);
+}
+
+int
+W_WindowWidth(window)
+    W_Window window;
+{
+    return (W_Void2Window(window)->width);
+}
+
+int
+W_WindowHeight(window)
+    W_Window window;
+{
+    return (W_Void2Window(window)->height);
+}
+
+int
+W_Socket()
+{
+    return (ConnectionNumber(W_Display));
+}
+
+void
+W_DestroyWindow(window)
+    W_Window window;
+{
+    struct window *win;
+
+#ifdef DEBUG
+    printf("Destroying %d\n", window);
+#endif
+    win = W_Void2Window(window);
+    deleteWindow(win);
+    XDestroyWindow(W_Display, win->window);
+    free((char *) win);
+}
+
+static void
+deleteWindow(window)
+    struct window *window;
+{
+    struct windowlist **rm;
+    struct windowlist *temp;
+
+    rm = &hashtable[hash(window->window)];
+    while (*rm != NULL && (*rm)->window != window) {
+	rm = &((*rm)->next);
+    }
+    if (*rm == NULL) {
+	printf("Attempt to delete non-existent window!\n");
+	return;
+    }
+    temp = *rm;
+    *rm = temp->next;
+    free((char *) temp);
+}
+
+void
+W_SetIconWindow(main, icon)
+    W_Window main;
+    W_Window icon;
+{
+    XWMHints hints;
+
+    XSetIconName(W_Display, W_Void2Window(icon)->window, W_Void2Window(main)->name);
+
+    hints.flags = IconWindowHint;
+    hints.icon_window = W_Void2Window(icon)->window;
+    XSetWMHints(W_Display, W_Void2Window(main)->window, &hints);
+}
+
+static void
+checkGeometry(name, x, y, width, height)
+    char   *name;
+    int    *x, *y, *width, *height;
+/* fixed so that it handles negative positions 12/21/93          */
+/* note that this is NOT standard X syntax, but it was requested */
+/* and it's how BRM-Hadley works.                       [BDyess] */
+{
+    char   *adefault;
+    char    buf[100];
+    char   *s;
+
+#ifdef RJC
+    *x = *y = INVALID_POSITION;
+#endif				/* RJC */
+
+    sprintf(buf, "%s.geometry", name);
+    adefault = getdefault(buf);
+    if (adefault == NULL)
+	return;
+    /* geometry should be of the form 502x885+1+1, 502x885, or +1+1 */
+    s = adefault;
+    if (*s != '+' && *s != '-') {
+	while (*s != 'x' && *s != 0)
+	    s++;
+	*width = atoi(adefault);
+	if (*s == 0)
+	    return;
+	s++;
+	adefault = s;
+	while (*s != '+' && *s != '-' && *s != 0)
+	    s++;
+	*height = atoi(adefault);
+	if (*s == 0)
+	    return;
+    }
+    adefault = s;
+    s++;
+    if (*s == '-')
+	s++;			/* for the case where they have wxh+-x+y */
+    while (*s != '+' && *s != '-' && *s != 0)
+	s++;
+    *x = atoi(adefault + 1);
+    if (*adefault == '-')
+	*x = -*x;
+    if (*s == 0)
+	return;
+    *y = atoi(s + 1);
+    if (*s == '-')
+	*y = -*y;
+    /* printf("width: %d, height: %d, x: %d, y: %d\n",*width, *height,*x,*y); */
+    return;
+}
+
+static void
+checkParent(name, parent)
+    char   *name;
+    W_Window *parent;
+{
+    char   *adefault;
+    char    buf[100];
+    int     i;
+    struct windowlist *windows;
+
+    sprintf(buf, "%s.parent", name);
+    adefault = getdefault(buf);
+    if (adefault == NULL)
+	return;
+    /* parent must be name of other window or "root" */
+    if (strcmpi(adefault, "root") == 0) {
+	*parent = W_Window2Void(&myroot);
+	return;
+    }
+    for (i = 0; i < HASHSIZE; i++) {
+	windows = hashtable[i];
+	while (windows != NULL) {
+	    if (strcmpi(adefault, windows->window->name) == 0) {
+		*parent = W_Window2Void(windows->window);
+		return;
+	    }
+	    windows = windows->next;
+	}
+    }
+}
+
+#ifdef YUCK
+#define cross_width 15
+#define cross_height 15
+#define cross_x_hot 7
+#define cross_y_hot 7
+static unsigned char cross_bits[] = {
+    0x00, 0x00, 0xc0, 0x01, 0xa0, 0x02, 0x00, 0x00, 0x80, 0x00, 0x04, 0x10, 0x82, 0x20, 0x56,
+0x35, 0x82, 0x20, 0x04, 0x10, 0x80, 0x00, 0x00, 0x00, 0xa0, 0x02, 0xc0, 0x01, 0x00, 0x00};
+static unsigned char crossmask_bits[] = {
+    0xe0, 0x03, 0xf0, 0x07, 0xf0, 0x07, 0xf0, 0x07, 0xce, 0x39, 0xcf, 0x79, 0xff, 0x7f, 0xff,
+0x7f, 0xff, 0x7f, 0xcf, 0x79, 0xce, 0x39, 0xf0, 0x07, 0xf0, 0x07, 0xf0, 0x07, 0xe0, 0x03};
+#else
+#define cross_width 16
+#define cross_height 16
+#define cross_x_hot 7
+#define cross_y_hot 7
+static unsigned char cross_bits[] = {
+    0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xc0, 0x01, 0x80, 0x00,
+    0x10, 0x04, 0x3f, 0x7e, 0x10, 0x04, 0x80, 0x00, 0xc0, 0x01, 0x80, 0x00,
+0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00};
+static unsigned char crossmask_bits[] = {
+    0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xe0, 0x03, 0xd0, 0x05,
+    0xbf, 0x7e, 0x7f, 0x7f, 0xbf, 0x7e, 0xd0, 0x05, 0xe0, 0x03, 0xc0, 0x01,
+0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0x00, 0x00};
+#endif
+
+static void
+checkCursor(name, cursname, cursor)
+    char   *name;
+    char   *cursname;
+    Cursor *cursor;
+{
+    char    buf[100];
+    unsigned cnum;
+    char   *adefault;
+
+    *cursor = 0;
+
+    sprintf(buf, "%s.cursor", name);
+    adefault = getdefault(buf);
+    if (adefault == NULL)
+	adefault = cursname;
+    if (adefault == NULL)
+	return;
+
+#ifdef RFCURSORS
+    cnum = XmuCursorNameToIndex(adefault);
+    if (cnum != -1) {
+	XColor  f, b;
+	*cursor = XCreateFontCursor(W_Display, cnum);
+	if (cnum == XC_xterm) {
+
+	    f.pixel = colortable[W_Yellow].pixelValue;
+	    b.pixel = colortable[W_Black].pixelValue;
+
+	    XQueryColor(W_Display, W_Colormap, &f);
+	    XQueryColor(W_Display, W_Colormap, &b);
+
+	    XRecolorCursor(W_Display, *cursor, &f, &b);
+	} else if (cnum == XC_pirate) {
+	    f.pixel = colortable[W_Red].pixelValue;
+	    b.pixel = colortable[W_Black].pixelValue;
+
+	    XQueryColor(W_Display, W_Colormap, &f);
+	    XQueryColor(W_Display, W_Colormap, &b);
+
+	    XRecolorCursor(W_Display, *cursor, &f, &b);
+	}
+    } else
+#endif
+    if (0 == strcmp("bomb here", adefault)) {
+	static Cursor bomb_here = 0;
+	if (bomb_here == 0) {
+	    bomb_here = make_cursor(cross_bits, crossmask_bits,
+				    cross_width, cross_height,
+				    cross_x_hot, cross_y_hot);
+	}
+	*cursor = bomb_here;
+    }
+}
+
+int
+checkMapped(name)
+    char   *name;
+{
+    char    buf[100];
+
+    sprintf(buf, "%s.mapped", name);
+    return (booleanDefault(buf, 0));
+}
+
+void
+W_WarpPointer(window, x, y)
+    W_Window window;
+    int     x, y;
+{
+    static int warped_from_x = 0, warped_from_y = 0;
+
+    if (window == NULL) {
+	if (W_in_message) {
+	    XWarpPointer(W_Display, None, W_Root, 0, 0, 0, 0, warped_from_x, warped_from_y);
+	    W_in_message = 0;
+	}
+    } else {
+	findMouse(&warped_from_x, &warped_from_y);
+	XWarpPointer(W_Display, None, W_Void2Window(window)->window, 0, 0, 0, 0, 0, 0);
+	W_in_message = 1;
+    }
+}
+
+static void
+findMouse(x, y)
+    int    *x, *y;
+{
+    Window  theRoot, theChild;
+    int     wX, wY, rootX, rootY, status;
+    unsigned int wButtons;
+
+    status = XQueryPointer(W_Display, W_Root, &theRoot, &theChild, &rootX, &rootY, &wX, &wY, &wButtons);
+    if (status == True) {
+	*x = wX;
+	*y = wY;
+    } else {
+	*x = 0;
+	*y = 0;
+    }
+}
+
+int
+findMouseInWin(x, y, w)
+    int    *x, *y;
+    W_Window w;
+{
+    Window  theRoot, theChild;
+    int     wX, wY, rootX, rootY, status;
+    unsigned int wButtons;
+    struct window *win = W_Void2Window(w);
+    Window  thisWin = win->window;
+
+    status = XQueryPointer(W_Display, thisWin, &theRoot, &theChild,
+			   &rootX, &rootY, &wX, &wY, &wButtons);
+    if (status == True) {
+	/*
+	   if it's in the window we specified then the values returned should
+	   be within the with and height of the window
+	*/
+	if (wX <= win->width && wY <= win->height) {
+	    *x = wX;
+	    *y = wY;
+	    return 1;
+	}
+    }
+    *x = 0;
+    *y = 0;
+    return 0;
+}
+
+#ifdef AUTOKEY
+static void
+W_Flush()
+{
+    XFlush(W_Display);
+}
+
+W_AutoRepeatOff()
+{
+    XAutoRepeatOff(W_Display);
+    W_Flush();
+}
+
+W_AutoRepeatOn()
+{
+    XAutoRepeatOn(W_Display);
+    W_Flush();
+}
+#endif				/* AUTOKEY */
+
+/* find the width of a font */
+int
+W_StringWidth(string, font)
+    char    string[];
+    W_Font  font;
+{
+    int     x, y;
+
+    y = strlen(string);
+    x = XTextWidth(fonts[fontNum(font)].fontstruct, string, y);
+    return (x);			/* just a guess ?? old never returned! WHS
+				   4/6/93 */
+}
+
+void
+W_TranslatePoints(w, x, y)
+    int    *x, *y;
+    W_Window w;
+{
+    struct window *win;
+    win = W_Void2Window(w);
+
+    if (win->type == WIN_TEXT) {
+	*y = (*y - MENU_PAD) / W_Textheight;
+	*x = (*x - MENU_PAD) / W_Textwidth;
+    }
+    return;
+}
+
+#if 0
+#define MAKE_WINDOW_GETTER(name, part) \
+  W_Callback name(w) \
+       W_Window w; \
+ { \
+     return W_Void2Window(w)->part; \
+ }
+
+#define MAKE_WINDOW_SETTER(name, port) \
+   W_Callback name(w, c) \
+      W_Window w; \
+      W_Callback c; \
+   { \
+      W_Void2Window(w)->port = c; \
+   }
+
+MAKE_WINDOW_GETTER(W_GetWindowKeyDownHandler, handle_keydown);
+MAKE_WINDOW_SETTER(W_SetWindowKeyDownHandler, handle_keydown);
+
+MAKE_WINDOW_GETTER(W_GetWindowKeyUpHandler, handle_keyup);
+MAKE_WINDOW_SETTER(W_SetWindowKeyUpHandler, handle_keyup);
+
+MAKE_WINDOW_GETTER(W_GetWindowButtonHandler, handle_button);
+MAKE_WINDOW_SETTER(W_SetWindowButtonHandler, handle_button);
+
+MAKE_WINDOW_GETTER(W_GetWindowExposeHandler, handle_expose);
+MAKE_WINDOW_SETTER(W_SetWindowExposeHandler, handle_expose);
+#endif				/* 0 */
+
+void
+W_ResizeWindow(window, neww, newh)	/* TSH 2/93 */
+    W_Window window;
+    int     neww, newh;
+{
+    Window  win = W_Void2Window(window)->window;
+
+    XResizeWindow(W_Display, win, (unsigned int) neww, (unsigned int) newh);
+}
+
+void
+W_ResizeMenu(window, neww, newh)/* TSH 2/93 */
+    W_Window window;
+    int     neww, newh;
+{
+    W_ResizeWindow(window, neww * W_Textwidth + WIN_EDGE * 2,
+	      newh * (W_Textheight + MENU_PAD * 2) + (newh - 1) * MENU_BAR);
+}
+
+void
+W_ResizeText(window, neww, newh)/* TSH 2/93 */
+    W_Window window;
+    int     neww, newh;
+{
+    W_ResizeWindow(window, neww * W_Textwidth + WIN_EDGE * 2,
+		   newh * W_Textheight + MENU_PAD * 2);
+}
+
+void
+W_Deiconify(window)
+    W_Window window;
+{
+    struct window *win;
+    win = W_Void2Window(window);
+    /* according to ICCCM 4.1.4, this is how you deiconify a window. */
+    XMapWindow(W_Display, win->window);
+}
+
+W_Icon
+W_MakeShieldBitmap(width, height, window)
+    int     width, height;
+    W_Window window;
+{
+    static GC pen = 0;
+    struct window *win;
+    struct icon *newicon;
+
+    win = W_Void2Window(window);
+
+    newicon = (struct icon *) malloc(sizeof(struct icon));
+    newicon->width = width;
+    newicon->height = height;
+    newicon->bitmap = XCreatePixmap(W_Display, win->window, width, height, 1);
+    newicon->window = win->window;
+    newicon->pixmap = 0;
+
+    pen = XCreateGC(W_Display, newicon->bitmap, 0L, 0);
+    XSetForeground(W_Display, pen, 0L);
+    XFillRectangle(W_Display, newicon->bitmap, pen, 0, 0, width, height);
+    XSetForeground(W_Display, pen, 1L);
+    XDrawArc(W_Display, newicon->bitmap, pen, 0, 0, width - 1, height - 1, 0, 360 * 64);
+    XFreeGC(W_Display, pen);
+
+    return W_Icon2Void(newicon);
+}
+
+#ifdef BEEPLITE
+void 
+W_OverlayBitmap(x, y, bit, color)
+    int     x, y;
+    W_Icon  bit;
+    W_Color color;
+{
+    struct icon *icon = W_Void2Icon(bit);
+#ifdef DEBUG
+    printf("Overlaying bitmap to %d\n", icon->window);
+#endif
+    XCopyPlane(W_Display, icon->bitmap, icon->window,
+	     colortable[color].contexts[0], 0, 0, icon->width, icon->height,
+	       x, y, 1);
+}
+#endif