changeset 5626:93bb7e0935ba

Initial revision
author Richard M. Stallman <rms@gnu.org>
date Tue, 18 Jan 1994 23:47:41 +0000
parents 24f92f49a07f
children 7ff2d6076466
files lwlib/Makefile.in lwlib/dispatch.c lwlib/lwlib-Xlw.c lwlib/lwlib-Xlw.h lwlib/lwlib-Xm.c lwlib/lwlib-Xm.h lwlib/lwlib-Xol.h lwlib/lwlib-int.h lwlib/lwlib-utils.c lwlib/lwlib-utils.h lwlib/lwlib.c lwlib/lwlib.h lwlib/xlwmenu.c lwlib/xlwmenu.h src/widget.c src/widget.h
diffstat 16 files changed, 6192 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwlib/Makefile.in	Tue Jan 18 23:47:41 1994 +0000
@@ -0,0 +1,397 @@
+# Makefile generated by imake - do not edit!
+# $XConsortium: imake.c,v 1.51 89/12/12 12:37:30 jim Exp $
+#
+# The cpp used on this machine replaces all newlines and multiple tabs and
+# spaces in a macro expansion with a single space.  Imake tries to compensate
+# for this, but is not always successful.
+#
+
+###########################################################################
+# Makefile generated from "Imake.tmpl" and <Imakefile>
+# $XConsortium: Imake.tmpl,v 1.77 89/12/18 17:01:37 jim Exp $
+#
+# Platform-specific parameters may be set in the appropriate .cf
+# configuration files.  Site-wide parameters may be set in the file
+# site.def.  Full rebuilds are recommended if any parameters are changed.
+#
+# If your C preprocessor doesn't define any unique symbols, you'll need
+# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
+# "make Makefile", "make Makefiles", or "make World").
+#
+# If you absolutely can't get imake to work, you'll need to set the
+# variables at the top of each Makefile as well as the dependencies at the
+# bottom (makedepend will do this automatically).
+#
+
+###########################################################################
+# platform-specific configuration parameters - edit sun.cf to change
+
+# platform:  $XConsortium: sun.cf,v 1.38 89/12/23 16:10:10 jim Exp $
+# operating system:  SunOS 4.0.3
+
+###########################################################################
+# site-specific configuration parameters - edit site.def to change
+
+# site:  $XConsortium: site.def,v 1.21 89/12/06 11:46:50 jim Exp $
+
+            SHELL = /bin/sh
+
+              TOP = .
+      CURRENT_DIR = .
+
+               AR = ar cq
+  BOOTSTRAPCFLAGS =
+               CC = gcc -DNOSTDHDRS -fstrength-reduce -fpcc-struct-return -fwritable-strings -traditional
+
+         COMPRESS = compress
+              CPP = /lib/cpp $(STD_CPP_DEFINES)
+    PREPROCESSCMD = gcc -DNOSTDHDRS -fstrength-reduce -fpcc-struct-return -fwritable-strings -traditional -E $(STD_CPP_DEFINES)
+          INSTALL = install
+               LD = ld
+             LINT = lint
+      LINTLIBFLAG = -C
+         LINTOPTS = -axz
+               LN = ln -s
+             MAKE = make
+               MV = mv
+               CP = cp
+           RANLIB = ranlib
+  RANLIBINSTFLAGS =
+               RM = rm -f
+     STD_INCLUDES =
+  STD_CPP_DEFINES =
+      STD_DEFINES =
+ EXTRA_LOAD_FLAGS =
+  EXTRA_LIBRARIES =
+             TAGS = ctags
+
+    SHAREDCODEDEF = -DSHAREDCODE
+         SHLIBDEF = -DSUNSHLIB
+
+    PROTO_DEFINES =
+
+     INSTPGMFLAGS =
+
+     INSTBINFLAGS = -m 0755
+     INSTUIDFLAGS = -m 4755
+     INSTLIBFLAGS = -m 0664
+     INSTINCFLAGS = -m 0444
+     INSTMANFLAGS = -m 0444
+     INSTDATFLAGS = -m 0444
+    INSTKMEMFLAGS = -m 4755
+
+          DESTDIR =
+
+     TOP_INCLUDES = -I$(INCROOT)
+
+      CDEBUGFLAGS = -O
+        CCOPTIONS =
+      COMPATFLAGS =
+
+      ALLINCLUDES = $(STD_INCLUDES) $(TOP_INCLUDES) $(INCLUDES) $(EXTRA_INCLUDES)
+       ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(PROTO_DEFINES) $(DEFINES) $(COMPATFLAGS)
+           CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
+        LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
+           LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+        LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS)
+   LDCOMBINEFLAGS = -X -r
+
+        MACROFILE = sun.cf
+           RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
+
+    IMAKE_DEFINES =
+
+         IRULESRC = $(CONFIGDIR)
+        IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
+
+     ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
+			$(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
+			$(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
+
+###########################################################################
+# X Window System Build Parameters
+# $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $
+
+###########################################################################
+# X Window System make variables; this need to be coordinated with rules
+# $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $
+
+          PATHSEP = /
+        USRLIBDIR = $(DESTDIR)/usr/lib
+           BINDIR = $(DESTDIR)/usr/bin/X11
+          INCROOT = $(DESTDIR)/usr/include
+     BUILDINCROOT = $(TOP)
+      BUILDINCDIR = $(BUILDINCROOT)/X11
+      BUILDINCTOP = ..
+           INCDIR = $(INCROOT)/X11
+           ADMDIR = $(DESTDIR)/usr/adm
+           LIBDIR = $(USRLIBDIR)/X11
+        CONFIGDIR = $(LIBDIR)/config
+       LINTLIBDIR = $(USRLIBDIR)/lint
+
+          FONTDIR = $(LIBDIR)/fonts
+         XINITDIR = $(LIBDIR)/xinit
+           XDMDIR = $(LIBDIR)/xdm
+           AWMDIR = $(LIBDIR)/awm
+           TWMDIR = $(LIBDIR)/twm
+           GWMDIR = $(LIBDIR)/gwm
+          MANPATH = $(DESTDIR)/usr/man
+    MANSOURCEPATH = $(MANPATH)/man
+           MANDIR = $(MANSOURCEPATH)n
+        LIBMANDIR = $(MANSOURCEPATH)3
+      XAPPLOADDIR = $(LIBDIR)/app-defaults
+
+        SOXLIBREV = 4.2
+          SOXTREV = 4.0
+         SOXAWREV = 4.0
+        SOOLDXREV = 4.0
+         SOXMUREV = 4.0
+        SOXEXTREV = 4.0
+
+       FONTCFLAGS = -t
+
+     INSTAPPFLAGS = $(INSTDATFLAGS)
+
+            IMAKE = imake
+           DEPEND = makedepend
+              RGB = rgb
+            FONTC = bdftosnf
+        MKFONTDIR = mkfontdir
+        MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier
+
+        CONFIGSRC = $(TOP)/config
+        CLIENTSRC = $(TOP)/clients
+          DEMOSRC = $(TOP)/demos
+           LIBSRC = $(TOP)/lib
+          FONTSRC = $(TOP)/fonts
+       INCLUDESRC = $(TOP)/X11
+        SERVERSRC = $(TOP)/server
+          UTILSRC = $(TOP)/util
+        SCRIPTSRC = $(UTILSRC)/scripts
+       EXAMPLESRC = $(TOP)/examples
+       CONTRIBSRC = $(TOP)/../contrib
+           DOCSRC = $(TOP)/doc
+           RGBSRC = $(TOP)/rgb
+        DEPENDSRC = $(UTILSRC)/makedepend
+         IMAKESRC = $(CONFIGSRC)
+         XAUTHSRC = $(LIBSRC)/Xau
+          XLIBSRC = $(LIBSRC)/X
+           XMUSRC = $(LIBSRC)/Xmu
+       TOOLKITSRC = $(LIBSRC)/Xt
+       AWIDGETSRC = $(LIBSRC)/Xaw
+       OLDXLIBSRC = $(LIBSRC)/oldX
+      XDMCPLIBSRC = $(LIBSRC)/Xdmcp
+      BDFTOSNFSRC = $(FONTSRC)/bdftosnf
+     MKFONTDIRSRC = $(FONTSRC)/mkfontdir
+     EXTENSIONSRC = $(TOP)/extensions
+
+  DEPEXTENSIONLIB = $(USRLIBDIR)/libXext.a
+     EXTENSIONLIB =  -lXext
+
+          DEPXLIB = $(DEPEXTENSIONLIB)
+             XLIB = $(EXTENSIONLIB) -lX11
+
+      DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
+         XAUTHLIB =  -lXau
+
+        DEPXMULIB =
+           XMULIB = -lXmu
+
+       DEPOLDXLIB =
+          OLDXLIB = -loldX
+
+      DEPXTOOLLIB =
+         XTOOLLIB = -lXt
+
+        DEPXAWLIB =
+           XAWLIB = -lXaw
+
+ LINTEXTENSIONLIB = $(USRLIBDIR)/llib-lXext.ln
+         LINTXLIB = $(USRLIBDIR)/llib-lX11.ln
+          LINTXMU = $(USRLIBDIR)/llib-lXmu.ln
+        LINTXTOOL = $(USRLIBDIR)/llib-lXt.ln
+          LINTXAW = $(USRLIBDIR)/llib-lXaw.ln
+
+        XWLIBSRC = $(CONTRIBSRC)/toolkits/Xw
+        DEPXWLIB = $(USRLIBDIR)/libXw.a
+        XWLIB =  -lXw
+
+          DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
+
+         DEPLIBS1 = $(DEPLIBS)
+         DEPLIBS2 = $(DEPLIBS)
+         DEPLIBS3 = $(DEPLIBS)
+
+###########################################################################
+# Imake rules for building libraries, programs, scripts, and data files
+# rules:  $XConsortium: Imake.rules,v 1.67 89/12/18 17:14:15 jim Exp $
+
+###########################################################################
+# start of Imakefile
+
+# Imakefile file for liblw.a, Copyright (c) 1992-1993 Lucid, Inc.
+
+    STD_DEFINES =
+    CDEBUGFLAGS = -O
+    EXT_DEFINES = -DTHIS_IS_X11R4
+        WHICH_X = x11r4
+
+     LUCID_SRCS = lwlib-Xlw.c xlwmenu.c
+     LUCID_OBJS = lwlib-Xlw.o xlwmenu.o
+     MOTIF_SRCS = lwlib-Xm.c
+     MOTIF_OBJS = lwlib-Xm.o
+      OLIT_SRCS = lwlib-Xol.c lwlib-Xol-mb.c
+      OLIT_OBJS = lwlib-Xol.o lwlib-Xol-mb.o
+
+TOOLKIT_DEFINES = -DUSE_LUCID
+   TOOLKIT_SRCS = $(LUCID_SRC)
+   TOOLKIT_OBJS = $(LUCID_OBJS)
+
+           SRCS = lwlib.c $(TOOLKIT_SRCS) lwlib-utils.c $(EXT_SRCS)
+           OBJS = lwlib.o $(TOOLKIT_OBJS) lwlib-utils.o $(EXT_OBJS) $(EZ_OBJS)
+      EXT_FLAGS = -I$(TOOLKITSRC) $(EXT_DEFINES)
+        LIBNAME = liblw.a
+
+.c.o:
+	$(RM) $@
+	$(CC) -c $(CFLAGS) $*.c
+
+all:: liblw.a
+
+liblw.a: $(OBJS)
+	$(RM) $@
+	$(AR) $@ $(OBJS)
+	$(RANLIB) $@
+
+Makefiles::
+	@case '${MFLAGS}' in *[ik]*) set +e;; esac; \
+	for i in energize ;\
+	do \
+	echo "making Makefiles in $(CURRENT_DIR)/$$i..."; \
+	case "$$i" in \
+	./?*/?*/?*/?*) newtop=../../../../ sub=subsubsubsub;; \
+	./?*/?*/?*) newtop=../../../ sub=subsubsub;; \
+	./?*/?*) newtop=../../ sub=subsub;; \
+	./?*) newtop=../ sub=sub;; \
+	*/?*/?*/?*) newtop=../../../../ sub=subsubsubsub;; \
+	*/?*/?*) newtop=../../../ sub=subsubsub;; \
+	*/?*) newtop=../../ sub=subsub;; \
+	*) newtop=../ sub=sub;; \
+	esac; \
+	case "$(TOP)" in \
+	/?*) newtop= upprefix= ;; \
+	*) upprefix=../ ;; \
+	esac; \
+	$(MAKE) $${sub}dirMakefiles UPPREFIX=$$upprefix NEWTOP=$$newtop \
+	MAKEFILE_SUBDIR=$$i NEW_CURRENT_DIR=$(CURRENT_DIR)/$$i;\
+	done
+
+subdirMakefiles:
+	$(RM) $(MAKEFILE_SUBDIR)/Makefile.bak
+	-@if [ -f $(MAKEFILE_SUBDIR)/Makefile ]; then \
+	echo "	$(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak"; \
+	$(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak; \
+	else exit 0; fi
+	cd $(MAKEFILE_SUBDIR); $(IMAKE_CMD) -DTOPDIR=$(UPPREFIX)$(TOP) -DCURDIR=$(NEW_CURRENT_DIR); \
+	$(MAKE) $(MFLAGS) Makefiles
+
+subsubdirMakefiles:
+	$(RM) $(MAKEFILE_SUBDIR)/Makefile.bak
+	-@if [ -f $(MAKEFILE_SUBDIR)/Makefile ]; then \
+	echo "	$(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak"; \
+	$(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak; \
+	else exit 0; fi
+	cd $(MAKEFILE_SUBDIR); $(IMAKE_CMD) -DTOPDIR=$(UPPREFIX)$(UPPREFIX)$(TOP) -DCURDIR=$(NEW_CURRENT_DIR); \
+	$(MAKE) $(MFLAGS) Makefiles
+
+subsubsubdirMakefiles:
+	$(RM) $(MAKEFILE_SUBDIR)/Makefile.bak
+	-@if [ -f $(MAKEFILE_SUBDIR)/Makefile ]; then \
+	echo "	$(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak"; \
+	$(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak; \
+	else exit 0; fi
+	cd $(MAKEFILE_SUBDIR); $(IMAKE_CMD) -DTOPDIR=$(UPPREFIX)$(UPPREFIX)$(UPPREFIX)$(TOP) -DCURDIR=$(NEW_CURRENT_DIR); \
+	$(MAKE) $(MFLAGS) Makefiles
+
+subsubsubsubdirMakefiles:
+	$(RM) $(MAKEFILE_SUBDIR)/Makefile.bak
+	-@if [ -f $(MAKEFILE_SUBDIR)/Makefile ]; then \
+	echo "	$(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak"; \
+	$(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak; \
+	else exit 0; fi
+	cd $(MAKEFILE_SUBDIR); $(IMAKE_CMD) -DTOPDIR=$(UPPREFIX)$(UPPREFIX)$(UPPREFIX)$(UPPREFIX)$(TOP) -DCURDIR=$(NEW_CURRENT_DIR); \
+	$(MAKE) $(MFLAGS) Makefiles
+
+depend::
+	$(DEPEND) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
+
+CPPDEFS=-DCPP_PROGRAM=\"/lib/cpp\"
+
+lwlib.o:  lwlib.c
+	$(RM) $@
+	$(CC) -c $(CFLAGS)  $(TOOLKIT_DEFINES) $*.c
+
+dispatch.o:  dispatch.c
+	$(RM) $@
+	$(CC) -c $(CFLAGS)  $(EXT_FLAGS) $*.c
+
+xrdb-cpp.o:  xrdb-cpp.c
+	$(RM) $@
+	$(CC) -c $(CFLAGS)  $(EXT_FLAGS) "$(CPPDEFS)" $*.c
+
+xrdb.o:      xrdb.c
+	$(RM) $@
+	$(CC) -c $(CFLAGS)      $(EXT_FLAGS) $*.c
+
+lwlib-Xm.o:  lwlib-Xm.c
+	$(RM) $@
+	$(CC) -c $(CFLAGS)  $(ENERGIZEP) $*.c
+
+lwlib-utils.o: lwlib-utils.h
+lwlib.o:       lwlib.h lwlib-internal.h
+lwlib-Xlw.o:   lwlib.h lwlib-internal.h
+lwlib-Xm.o:    lwlib.h lwlib-internal.h lwlib-utils.h
+lwlib-Xol.o:   lwlib.h lwlib-internal.h
+lwlib-Xol-mb.o: lwlib-Xol-mb.h lwlib-Xol-mbP.h
+
+###########################################################################
+# common rules for all Makefiles - do not edit
+
+emptyrule::
+
+clean::
+	$(RM_CMD) \#*
+
+Makefile::
+	-@if [ -f Makefile ]; then \
+	echo "	$(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
+	$(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
+	else exit 0; fi
+	$(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
+
+tags::
+	$(TAGS) -w *.[ch]
+	$(TAGS) -xw *.[ch] > TAGS
+
+saber:
+	#load $(ALLDEFINES) $(SRCS)
+
+osaber:
+	#load $(ALLDEFINES) $(OBJS)
+
+###########################################################################
+# empty rules for directories that do not have SUBDIRS - do not edit
+
+install::
+	@echo "install in $(CURRENT_DIR) done"
+
+install.man::
+	@echo "install.man in $(CURRENT_DIR) done"
+
+Makefiles::
+
+includes::
+
+###########################################################################
+# dependencies generated by makedepend
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwlib/dispatch.c	Tue Jan 18 23:47:41 1994 +0000
@@ -0,0 +1,275 @@
+/* Defines a function to find the Widget that XtDispatchEvent() would use.
+   Copyright (C) 1992 Lucid, Inc.
+
+This file is part of the Lucid Widget Library.
+
+The Lucid Widget Library is free software; you can redistribute it and/or 
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+The Lucid Widget Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of 
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* 
+ *   The function XtWidgetToDispatchTo(), given an XEvent, returns the 
+ *   widget that XtDispatchEvent() would send that event to if called now.
+ *   This file copies much code from the X11r4 Xt source, and is thus a
+ *   portability problem.  It also requires data structures defined in
+ *   IntrinsicI.h, which is a non-exported Xt header file, so you can't
+ *   compile this file unless you have the Xt sources online.
+ */
+
+#include <IntrinsicI.h>   /* Don't change this: see comments in Imakefile. */
+#include <X11/Xatom.h>
+#include "dispatch.h"
+
+#ifdef THIS_IS_X11R4
+
+#ifdef THIS_IS_X11R5
+ERROR!! only one of THIS_IS_X11R4 or THIS_IS_X11R5 must be defined.
+#endif
+
+#else /* ! THIS_IS_X11R4 */
+
+#ifndef THIS_IS_X11R5
+ERROR!! one of THIS_IS_X11R4 or THIS_IS_X11R5 must be defined.
+#endif
+
+#endif /* ! THIS_IS_X11R4 */
+
+
+/* ##  All of the code on this page was copied from the X11R5 lib/Xt/Event.c,
+   ##  but is compatible with X11R4; the code in Event.c is different, but
+   ##  functionally equivalent for our purposes.
+ */
+
+#if __STDC__
+#define Const const
+#else
+#define Const /**/
+#endif
+
+#define NonMaskableMask ((EventMask)0x80000000L)
+
+#define COMP_EXPOSE   (widget->core.widget_class->core_class.compress_exposure)
+#define COMP_EXPOSE_TYPE (COMP_EXPOSE & 0x0f)
+#define GRAPHICS_EXPOSE  ((XtExposeGraphicsExpose & COMP_EXPOSE) || \
+			  (XtExposeGraphicsExposeMerged & COMP_EXPOSE))
+#define NO_EXPOSE        (XtExposeNoExpose & COMP_EXPOSE)
+
+
+/* -- lots of stuff we don't need to copy, omitted -- */
+
+
+static EventMask Const masks[] = {
+	0,			    /* Error, should never see  */
+	0,			    /* Reply, should never see  */
+	KeyPressMask,		    /* KeyPress			*/
+	KeyReleaseMask,		    /* KeyRelease		*/
+	ButtonPressMask,	    /* ButtonPress		*/
+	ButtonReleaseMask,	    /* ButtonRelease		*/
+	PointerMotionMask	    /* MotionNotify		*/
+		| ButtonMotionMask,
+	EnterWindowMask,	    /* EnterNotify		*/
+	LeaveWindowMask,	    /* LeaveNotify		*/
+	FocusChangeMask,	    /* FocusIn			*/
+	FocusChangeMask,	    /* FocusOut			*/
+	KeymapStateMask,	    /* KeymapNotify		*/
+	ExposureMask,		    /* Expose			*/
+	NonMaskableMask,	    /* GraphicsExpose, in GC    */
+	NonMaskableMask,	    /* NoExpose, in GC		*/
+	VisibilityChangeMask,       /* VisibilityNotify		*/
+	SubstructureNotifyMask,     /* CreateNotify		*/
+	StructureNotifyMask	    /* DestroyNotify		*/
+		| SubstructureNotifyMask,
+	StructureNotifyMask	    /* UnmapNotify		*/
+		| SubstructureNotifyMask,
+	StructureNotifyMask	    /* MapNotify		*/
+		| SubstructureNotifyMask,
+	SubstructureRedirectMask,   /* MapRequest		*/
+	StructureNotifyMask	    /* ReparentNotify		*/
+		| SubstructureNotifyMask,
+	StructureNotifyMask	    /* ConfigureNotify		*/
+		| SubstructureNotifyMask,
+	SubstructureRedirectMask,   /* ConfigureRequest		*/
+	StructureNotifyMask	    /* GravityNotify		*/
+		| SubstructureNotifyMask,
+	ResizeRedirectMask,	    /* ResizeRequest		*/
+	StructureNotifyMask	    /* CirculateNotify		*/
+		| SubstructureNotifyMask,
+	SubstructureRedirectMask,   /* CirculateRequest		*/
+	PropertyChangeMask,	    /* PropertyNotify		*/
+	NonMaskableMask,	    /* SelectionClear		*/
+	NonMaskableMask,	    /* SelectionRequest		*/
+	NonMaskableMask,	    /* SelectionNotify		*/
+	ColormapChangeMask,	    /* ColormapNotify		*/
+	NonMaskableMask,	    /* ClientMessage		*/
+	NonMaskableMask		    /* MappingNotify		*/
+};
+
+#ifdef THIS_IS_X11R4
+
+static /* in R5, this is not static, so we don't need to define it at all */
+EventMask _XtConvertTypeToMask (eventType)
+    int		eventType;
+{
+    eventType &= 0x7f;	/* Events sent with XSendEvent have high bit set. */
+    if (eventType < XtNumber(masks))
+	return masks[eventType];
+    else
+	return 0;
+}
+
+#endif /* R4 */
+
+/* -- _XtOnGrabList() omitted -- */
+
+
+static Widget LookupSpringLoaded(grabList)
+    XtGrabList	grabList;
+{
+    XtGrabList	gl;
+
+    for (gl = grabList; gl != NULL; gl = gl->next) {
+	if (gl->spring_loaded)
+	  if (XtIsSensitive(gl->widget))
+	    return gl->widget;
+	  else
+	    return NULL;
+	if (gl->exclusive) break;
+    }
+    return NULL;
+}
+
+
+
+/* This function is new. */
+
+static Boolean WouldDispatchEvent(event, widget, mask, pd)
+     register XEvent    *event;
+     Widget    widget;
+     EventMask mask;
+     XtPerDisplay pd;
+{
+  XtEventRec *p;   
+  Boolean would_dispatched = False;
+  
+  if ((mask == ExposureMask) ||
+      ((event->type == NoExpose) && NO_EXPOSE) ||
+      ((event->type == GraphicsExpose) && GRAPHICS_EXPOSE) )
+    if (widget->core.widget_class->core_class.expose != NULL )
+      return True;
+  
+  
+  if ((mask == VisibilityChangeMask) &&
+      XtClass(widget)->core_class.visible_interest) 
+    return True;
+  
+  for (p=widget->core.event_table; p != NULL; p = p->next) 
+    if ((mask & p->mask) != 0
+#ifdef THIS_IS_X11R4
+	|| (mask == 0 && p->non_filter)
+#endif
+	)
+      return True;
+
+  return False;
+}
+
+
+/* ####  This function is mostly copied from DecideToDispatch().
+ */
+
+typedef enum _GrabType {pass, ignore, remap} GrabType;
+
+Widget
+XtWidgetToDispatchTo (XEvent* event)
+{
+  register    Widget widget;
+  EventMask   mask;
+  GrabType    grabType;
+  Widget	dspWidget;
+  Time	time = 0;
+  XtPerDisplay pd;
+  XtPerDisplayInput pdi;
+  XtGrabList  grabList;
+  
+  widget = XtWindowToWidget (event->xany.display, event->xany.window);
+  pd = _XtGetPerDisplay(event->xany.display);
+  pdi = _XtGetPerDisplayInput(event->xany.display);
+  grabList = *_XtGetGrabList(pdi);
+  
+  mask = _XtConvertTypeToMask(event->xany.type);
+  grabType = pass;
+  switch (event->xany.type & 0x7f) {
+  case KeyPress:
+  case KeyRelease:	grabType = remap; break;
+  case ButtonPress:
+  case ButtonRelease:	grabType = remap; break;
+  case MotionNotify:	grabType = ignore;
+#define XKnownButtons (Button1MotionMask|Button2MotionMask|Button3MotionMask|\
+                       Button4MotionMask|Button5MotionMask)
+			mask |= (event->xmotion.state & XKnownButtons);
+#undef XKnownButtons
+				break;
+  case EnterNotify:	grabType = ignore; break;
+  }
+  
+  if (widget == NULL) {
+    if (grabType != remap) return False;
+    /* event occurred in a non-widget window, but we've promised also
+       to dispatch it to the nearest accessible spring_loaded widget */
+    else if ((widget = LookupSpringLoaded(grabList)) != NULL)
+      return widget;
+    return False;
+  }
+
+  switch(grabType) {
+  case pass:
+    return widget;
+    
+  case ignore:
+    if ((grabList == NULL || _XtOnGrabList(widget,grabList))
+	&& XtIsSensitive(widget)) {
+      return widget;
+    }
+    return NULL;
+    
+  case remap:
+    
+    {
+      Widget was_dispatched_to= NULL;
+      extern Widget _XtFindRemapWidget();
+      extern void _XtUngrabBadGrabs();
+      
+      dspWidget = _XtFindRemapWidget(event, widget, mask, pdi);
+      
+      if ((grabList == NULL || 
+	   _XtOnGrabList(dspWidget, grabList)) &&
+	  XtIsSensitive(dspWidget)) {
+	if (WouldDispatchEvent (event, dspWidget, mask, pd))
+	  was_dispatched_to = dspWidget;
+      }
+      
+      /* Also dispatch to nearest accessible spring_loaded. */
+      /* Fetch this afterward to reflect modal list changes */
+      grabList = *_XtGetGrabList(pdi);
+      widget = LookupSpringLoaded(grabList);
+      if (widget != NULL && widget != dspWidget) {
+	if (!was_dispatched_to)
+	  was_dispatched_to =  widget;
+      }
+      
+      return was_dispatched_to;
+    }
+  }
+  /* should never reach here */
+  return NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwlib/lwlib-Xlw.c	Tue Jan 18 23:47:41 1994 +0000
@@ -0,0 +1,178 @@
+/* The lwlib interface to "xlwmenu" menus.
+   Copyright (C) 1992 Lucid, Inc.
+
+This file is part of the Lucid Widget Library.
+
+The Lucid Widget Library is free software; you can redistribute it and/or 
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+The Lucid Widget Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of 
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "lwlib-Xlw.h"
+#include <X11/StringDefs.h>
+#include <X11/IntrinsicP.h>
+#include <X11/ObjectP.h>
+#include <X11/CompositeP.h>
+#include <X11/Shell.h>
+#include "xlwmenu.h"
+
+/* Menu callbacks */
+static void
+pre_hook (Widget w, XtPointer client_data, XtPointer call_data)
+{
+  widget_instance* instance = (widget_instance*)client_data;
+  widget_value* val;
+
+  if (w->core.being_destroyed)
+    return;
+
+  val = lw_get_widget_value_for_widget (instance, w);
+  if (instance->info->pre_activate_cb)
+    instance->info->pre_activate_cb (w, instance->info->id,
+				     val ? val->call_data : NULL);
+}
+
+static void
+pick_hook (Widget w, XtPointer client_data, XtPointer call_data)
+{
+  widget_instance* instance = (widget_instance*)client_data;
+  widget_value* contents_val = (widget_value*)call_data;
+  widget_value* widget_val;
+  XtPointer widget_arg;
+
+  if (w->core.being_destroyed)
+    return;
+
+  if (instance->info->selection_cb && contents_val && contents_val->enabled
+      && !contents_val->contents)
+    instance->info->selection_cb (w, instance->info->id,
+				  contents_val->call_data);
+
+  widget_val = lw_get_widget_value_for_widget (instance, w);
+  widget_arg = widget_val ? widget_val->call_data : NULL;
+  if (instance->info->post_activate_cb)
+    instance->info->post_activate_cb (w, instance->info->id, widget_arg);
+
+}
+
+/* creation functions */
+static Widget
+xlw_create_menubar (widget_instance* instance)
+{
+  Widget widget =
+    XtVaCreateWidget (instance->info->name, xlwMenuWidgetClass,
+		      instance->parent,
+		      XtNmenu, instance->info->val,
+		      0);
+  XtAddCallback (widget, XtNopen, pre_hook, (XtPointer)instance);
+  XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
+  return widget;
+}
+
+static Widget
+xlw_create_popup_menu (widget_instance* instance)
+{
+  Widget popup_shell =
+    XtCreatePopupShell (instance->info->name, overrideShellWidgetClass,
+			instance->parent, NULL, 0);
+  
+  Widget widget = 
+    XtVaCreateManagedWidget ("popup", xlwMenuWidgetClass,
+			     popup_shell,
+			     XtNmenu, instance->info->val,
+			     XtNhorizontal, False,
+			     0);
+
+  XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
+
+  return popup_shell;
+}
+
+widget_creation_entry 
+xlw_creation_table [] =
+{
+  {"menubar", xlw_create_menubar},
+  {"popup", xlw_create_popup_menu},
+  {NULL, NULL}
+};
+
+Boolean
+lw_lucid_widget_p (Widget widget)
+{
+  WidgetClass the_class = XtClass (widget);
+  if (the_class == xlwMenuWidgetClass)
+    return True;
+  if (the_class == overrideShellWidgetClass)
+    return
+      XtClass (((CompositeWidget)widget)->composite.children [0])
+	== xlwMenuWidgetClass;
+  return False;
+}
+
+void
+xlw_update_one_widget (widget_instance* instance, Widget widget,
+		       widget_value* val, Boolean deep_p)
+{
+  XlwMenuWidget mw;
+
+  if (XtIsShell (widget))
+    mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0];
+  else
+    mw = (XlwMenuWidget)widget;
+  XtVaSetValues (widget, XtNmenu, val, 0);
+}
+
+void
+xlw_update_one_value (widget_instance* instance, Widget widget,
+		      widget_value* val)
+{
+  return;
+}
+
+void
+xlw_pop_instance (widget_instance* instance, Boolean up)
+{
+}
+
+void
+xlw_popup_menu (Widget widget)
+{
+  XButtonPressedEvent dummy;
+  XlwMenuWidget mw;
+
+  if (!XtIsShell (widget))
+    return;
+
+  mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0];
+
+  dummy.type = ButtonPress;
+  dummy.serial = 0;
+  dummy.send_event = 0;
+  dummy.display = XtDisplay (widget);
+  dummy.window = XtWindow (XtParent (widget));
+  dummy.time = CurrentTime;
+  dummy.button = 0;
+  XQueryPointer (dummy.display, dummy.window, &dummy.root,
+		 &dummy.subwindow, &dummy.x_root, &dummy.y_root,
+		 &dummy.x, &dummy.y, &dummy.state);
+
+  pop_up_menu (mw, &dummy);
+}
+
+/* Destruction of instances */
+void
+xlw_destroy_instance (widget_instance* instance)
+{
+  if (instance->widget)
+    XtDestroyWidget (instance->widget);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwlib/lwlib-Xlw.h	Tue Jan 18 23:47:41 1994 +0000
@@ -0,0 +1,29 @@
+#ifndef LWLIB_XLW_H
+#define LWLIB_XLW_H
+
+#include "lwlib-internal.h"
+
+extern widget_creation_entry xlw_creation_table [];
+extern widget_creation_function xlw_create_dialog;
+
+Boolean
+lw_lucid_widget_p (Widget widget);
+
+void
+xlw_update_one_widget (widget_instance* instance, Widget widget,
+		       widget_value* val, Boolean deep_p);
+
+void
+xlw_update_one_value (widget_instance* instance, Widget widget,
+		      widget_value* val);
+
+void
+xlw_destroy_instance (widget_instance* instance);
+
+void
+xlw_pop_instance (widget_instance* instance, Boolean up);
+
+void
+xlw_popup_menu (Widget widget);
+
+#endif /* LWLIB_XLW_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwlib/lwlib-Xm.c	Tue Jan 18 23:47:41 1994 +0000
@@ -0,0 +1,1495 @@
+/* The lwlib interface to Motif widgets.
+   Copyright (C) 1992 Lucid, Inc.
+
+This file is part of the Lucid Widget Library.
+
+The Lucid Widget Library is free software; you can redistribute it and/or 
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+The Lucid Widget Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of 
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <X11/StringDefs.h>
+#include <X11/IntrinsicP.h>
+#include <X11/ObjectP.h>
+#include <X11/CoreP.h>
+#include <X11/CompositeP.h>
+
+#include "lwlib-Xm.h"
+#include "lwlib-utils.h"
+
+#include <Xm/BulletinB.h>
+#include <Xm/CascadeB.h>
+#include <Xm/DrawingA.h>
+#include <Xm/FileSB.h>
+#include <Xm/Label.h>
+#include <Xm/List.h>
+#include <Xm/MenuShell.h>
+#include <Xm/MessageB.h>
+#include <Xm/PushB.h>
+#include <Xm/PushBG.h>
+#include <Xm/ArrowB.h>
+#include <Xm/SelectioB.h>
+#include <Xm/Text.h>
+#include <Xm/TextF.h>
+#include <Xm/ToggleB.h>
+#include <Xm/ToggleBG.h>
+#include <Xm/RowColumn.h>
+#include <Xm/ScrolledW.h>
+#include <Xm/Separator.h>
+#include <Xm/DialogS.h>
+#include <Xm/Form.h>
+
+static void xm_pull_down_callback (Widget, XtPointer, XtPointer);
+static void xm_internal_update_other_instances (Widget, XtPointer,
+						XtPointer);
+static void xm_generic_callback (Widget, XtPointer, XtPointer);
+static void xm_nosel_callback (Widget, XtPointer, XtPointer);
+static void xm_pop_down_callback (Widget, XtPointer, XtPointer);
+
+static void
+xm_update_menu (widget_instance* instance, Widget widget, widget_value* val,
+		Boolean deep_p);
+
+/* Structures to keep destroyed instances */
+typedef struct _destroyed_instance 
+{
+  char*		name;
+  char*		type;
+  Widget 	widget;
+  Widget	parent;
+  Boolean	pop_up_p;
+  struct _destroyed_instance*	next;
+} destroyed_instance;
+
+static destroyed_instance*
+all_destroyed_instances = NULL;
+
+static destroyed_instance*
+make_destroyed_instance (char* name, char* type, Widget widget, Widget parent,
+			 Boolean pop_up_p)
+{
+  destroyed_instance* instance =
+    (destroyed_instance*)malloc (sizeof (destroyed_instance));
+  instance->name = strdup (name);
+  instance->type = strdup (type);
+  instance->widget = widget;
+  instance->parent = parent;
+  instance->pop_up_p = pop_up_p;
+  instance->next = NULL;
+  return instance;
+}
+			 
+static void
+free_destroyed_instance (destroyed_instance* instance)
+{
+  free (instance->name);
+  free (instance->type);
+  free (instance);
+}
+
+/* motif utility functions */
+Widget
+first_child (Widget widget)
+{
+  return ((CompositeWidget)widget)->composite.children [0];
+}
+
+Boolean
+lw_motif_widget_p (Widget widget)
+{
+  return 
+    XtClass (widget) == xmDialogShellWidgetClass
+      || XmIsPrimitive (widget) || XmIsManager (widget) || XmIsGadget (widget);
+}
+
+static XmString
+resource_motif_string (Widget widget, char* name)
+{
+  XtResource resource;
+  XmString result = 0;
+  
+  resource.resource_name = name;
+  resource.resource_class = XmCXmString;
+  resource.resource_type = XmRXmString;
+  resource.resource_size = sizeof (XmString);
+  resource.resource_offset = 0;
+  resource.default_type = XtRImmediate;
+  resource.default_addr = 0;
+
+  XtGetSubresources (widget, (XtPointer)&result, "dialogString",
+		     "DialogString", &resource, 1, NULL, 0);
+  return result;
+}
+
+static void
+destroy_all_children (Widget widget)
+{
+  Widget* children;
+  unsigned int number;
+  int i;
+
+  children = XtCompositeChildren (widget, &number);
+  if (children)
+    {
+      /* Unmanage all children and destroy them.  They will only be 
+       * really destroyed when we get out of DispatchEvent. */
+      for (i = 0; i < number; i++)
+	{
+	  Widget child = children [i];
+	  if (!child->core.being_destroyed)
+	    {
+	      XtUnmanageChild (child);
+	      XtDestroyWidget (child);
+	    }
+	}
+      XtFree ((char *) children);
+    }
+}
+
+/* update the label of anything subclass of a label */
+static void
+xm_update_label (widget_instance* instance, Widget widget, widget_value* val)
+{
+  XmString res_string = 0;
+  XmString built_string = 0;
+  XmString key_string = 0;
+  Arg al [256];
+  int ac;
+  
+  ac = 0;
+
+  if (val->value)
+    {
+      res_string = resource_motif_string (widget, val->value);
+
+      if (res_string)
+	{
+	  XtSetArg (al [ac], XmNlabelString, res_string); ac++;
+	}
+      else
+	{
+	  built_string =
+	    XmStringCreateLtoR (val->value, XmSTRING_DEFAULT_CHARSET);
+	  XtSetArg (al [ac], XmNlabelString, built_string); ac++;
+	}
+      XtSetArg (al [ac], XmNlabelType, XmSTRING); ac++;
+    }
+  
+  if (val->key)
+    {
+      key_string = XmStringCreateLtoR (val->key, XmSTRING_DEFAULT_CHARSET);
+      XtSetArg (al [ac], XmNacceleratorText, key_string); ac++;
+    }
+
+  if (ac)
+    XtSetValues (widget, al, ac);
+
+  if (built_string)
+    XmStringFree (built_string);
+
+  if (key_string)
+    XmStringFree (key_string);
+}
+
+/* update of list */
+static void
+xm_update_list (widget_instance* instance, Widget widget, widget_value* val)
+{
+  widget_value* cur;
+  int i;
+  XtRemoveAllCallbacks (widget, XmNsingleSelectionCallback);
+  XtAddCallback (widget, XmNsingleSelectionCallback, xm_generic_callback,
+		 instance);
+  for (cur = val->contents, i = 0; cur; cur = cur->next)
+    if (cur->value)
+      {
+	XmString xmstr = XmStringCreate (cur->value, XmSTRING_DEFAULT_CHARSET);
+	i += 1;
+	XmListAddItem (widget, xmstr, 0);
+	if (cur->selected)
+	  XmListSelectPos (widget, i, False);
+	XmStringFree (xmstr);
+      }
+}
+
+/* update of buttons */
+static void
+xm_update_pushbutton (widget_instance* instance, Widget widget,
+		      widget_value* val)
+{
+  XtVaSetValues (widget, XmNalignment, XmALIGNMENT_CENTER, 0);
+  XtRemoveAllCallbacks (widget, XmNactivateCallback);
+  XtAddCallback (widget, XmNactivateCallback, xm_generic_callback, instance);
+}
+
+static void
+xm_update_cascadebutton (widget_instance* instance, Widget widget,
+			 widget_value* val)
+{
+  /* Should also rebuild the menu by calling ...update_menu... */
+  XtRemoveAllCallbacks (widget, XmNcascadingCallback);
+  XtAddCallback (widget, XmNcascadingCallback, xm_pull_down_callback,
+		 instance);
+}
+
+/* update toggle and radiobox */
+static void
+xm_update_toggle (widget_instance* instance, Widget widget, widget_value* val)
+{
+  XtRemoveAllCallbacks (widget, XmNvalueChangedCallback);
+  XtAddCallback (widget, XmNvalueChangedCallback,
+		 xm_internal_update_other_instances, instance);
+  XtVaSetValues (widget, XmNset, val->selected,
+		 XmNalignment, XmALIGNMENT_BEGINNING, 0);
+}
+
+static void
+xm_update_radiobox (widget_instance* instance, Widget widget,
+		    widget_value* val)
+{
+  Widget toggle;
+  widget_value* cur;
+
+  /* update the callback */
+  XtRemoveAllCallbacks (widget, XmNentryCallback);
+  XtAddCallback (widget, XmNentryCallback, xm_generic_callback, instance);
+
+  /* first update all the toggles */
+  /* Energize kernel interface is currently bad.  It sets the selected widget
+     with the selected flag but returns it by its name.  So we currently
+     have to support both setting the selection with the selected slot
+     of val contents and setting it with the "value" slot of val.  The latter
+     has a higher priority.  This to be removed when the kernel is fixed. */
+  for (cur = val->contents; cur; cur = cur->next)
+    {
+      toggle = XtNameToWidget (widget, cur->value);
+      if (toggle)
+	{
+	  XtVaSetValues (toggle, XmNsensitive, cur->enabled, 0);
+	  if (!val->value && cur->selected)
+	    XtVaSetValues (toggle, XmNset, cur->selected, 0);
+	  if (val->value && strcmp (val->value, cur->value))
+	    XtVaSetValues (toggle, XmNset, False, 0);
+	}
+    }
+
+  /* The selected was specified by the value slot */
+  if (val->value)
+    {
+      toggle = XtNameToWidget (widget, val->value);
+      if (toggle)
+	XtVaSetValues (toggle, XmNset, True, 0);
+    }
+}
+
+/* update a popup menu, pulldown menu or a menubar */
+static Boolean
+all_dashes_p (char* s)
+{
+  char* t;
+  for (t = s; *t; t++)
+    if (*t != '-')
+      return False;
+  return True;
+}
+
+static void
+make_menu_in_widget (widget_instance* instance, Widget widget,
+		     widget_value* val)
+{
+  Widget* children = 0;
+  int num_children;
+  int child_index;
+  widget_value* cur;
+  Widget button = 0;
+  Widget menu;
+  Arg al [256];
+  int ac;
+  Boolean menubar_p;
+
+  /* Allocate the children array */
+  for (num_children = 0, cur = val; cur; num_children++, cur = cur->next);
+  children = (Widget*)XtMalloc (num_children * sizeof (Widget));
+
+  /* tricky way to know if this RowColumn is a menubar or a pulldown... */
+  menubar_p = False;
+  XtSetArg (al[0], XmNisHomogeneous, &menubar_p);
+  XtGetValues (widget, al, 1);
+
+  /* add the unmap callback for popups and pulldowns */
+  /*** this sounds bogus ***/
+  if (!menubar_p)
+    XtAddCallback (XtParent (widget), XmNpopdownCallback,
+		   xm_pop_down_callback, (XtPointer)instance);
+
+  for (child_index = 0, cur = val; cur; child_index++, cur = cur->next)
+    {    
+      ac = 0;
+      XtSetArg (al [ac], XmNsensitive, cur->enabled); ac++;
+      XtSetArg (al [ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
+      XtSetArg (al [ac], XmNuserData, cur->call_data); ac++;
+      
+      if (all_dashes_p (cur->name))
+	{
+	  button = XmCreateSeparator (widget, cur->name, NULL, 0);
+	}
+      else if (!cur->contents)
+	{
+	  if (menubar_p)
+	    button = XmCreateCascadeButton (widget, cur->name, al, ac);
+	  else if (!cur->call_data)
+	    button = XmCreateLabel (widget, cur->name, al, ac);
+	  else
+	    button = XmCreatePushButtonGadget (widget, cur->name, al, ac);
+
+	  xm_update_label (instance, button, cur);
+
+	  /* don't add a callback to a simple label */
+	  if (cur->call_data)
+	    XtAddCallback (button, XmNactivateCallback, xm_generic_callback,
+			   (XtPointer)instance);
+	}
+      else
+	{
+	  menu = XmCreatePulldownMenu (widget, "pulldown", NULL, 0);
+	  make_menu_in_widget (instance, menu, cur->contents);
+	  XtSetArg (al [ac], XmNsubMenuId, menu); ac++;
+	  button = XmCreateCascadeButton (widget, cur->name, al, ac);
+
+	  xm_update_label (instance, button, cur);
+
+	  XtAddCallback (button, XmNcascadingCallback, xm_pull_down_callback,
+			 (XtPointer)instance);
+	}
+
+      children [child_index] = button;
+    }
+
+  XtManageChildren (children, num_children);
+
+  /* Last entry is the help button.  Has to be done after managing
+   * the buttons otherwise the menubar is only 4 pixels high... */
+  if (button)
+    {
+      ac = 0;
+      XtSetArg (al [ac], XmNmenuHelpWidget, button); ac++;
+      XtSetValues (widget, al, ac);
+    }
+
+  XtFree ((char *) children);
+}
+
+static void
+update_one_menu_entry (widget_instance* instance, Widget widget,
+		       widget_value* val, Boolean deep_p)
+{
+  Arg al [256];
+  int ac;
+  Widget menu;
+  widget_value* contents;
+
+  if (val->change == NO_CHANGE)
+    return;
+
+  /* update the sensitivity and userdata */
+  /* Common to all widget types */
+  XtVaSetValues (widget,
+		 XmNsensitive, val->enabled,
+		 XmNuserData, val->call_data,
+		 0);
+
+  /* update the menu button as a label. */
+  if (val->change >= VISIBLE_CHANGE)
+    xm_update_label (instance, widget, val);
+
+  /* update the pulldown/pullaside as needed */
+  ac = 0;
+  menu = NULL;
+  XtSetArg (al [ac], XmNsubMenuId, &menu); ac++;
+  XtGetValues (widget, al, ac);
+  
+  contents = val->contents;
+
+  if (!menu)
+    {
+      if (contents)
+	{
+	  menu = XmCreatePulldownMenu (widget, "pulldown", NULL, 0);
+	  make_menu_in_widget (instance, menu, contents);
+	  ac = 0;
+	  XtSetArg (al [ac], XmNsubMenuId, menu); ac++;
+	  XtSetValues (widget, al, ac);
+	}
+    }
+  else if (!contents)
+    {
+      ac = 0;
+      XtSetArg (al [ac], XmNsubMenuId, NULL); ac++;
+      XtSetValues (widget, al, ac);
+      XtDestroyWidget (menu);
+    }
+  else if (deep_p && contents->change != NO_CHANGE)
+    xm_update_menu (instance, menu, val, 1);
+}
+
+static void
+xm_update_menu (widget_instance* instance, Widget widget, widget_value* val,
+		Boolean deep_p)
+{
+  /* Widget is a RowColumn widget whose contents have to be updated
+   * to reflect the list of items in val->contents */
+  if (val->contents->change == STRUCTURAL_CHANGE)
+    {
+      destroy_all_children (widget);
+      make_menu_in_widget (instance, widget, val->contents);
+    }
+  else
+    {
+      /* Update all the buttons of the RowColumn in order. */
+      Widget* children;
+      unsigned int num_children;
+      int i;
+      widget_value* cur;
+
+      children = XtCompositeChildren (widget, &num_children);
+      if (children)
+	{
+	  for (i = 0, cur = val->contents; i < num_children; i++)
+	    {
+	      if (!cur)
+		abort ();
+	      if (children [i]->core.being_destroyed
+		  || strcmp (XtName (children [i]), cur->name))
+		continue;
+	      update_one_menu_entry (instance, children [i], cur, deep_p);
+	      cur = cur->next;
+	    }
+	  XtFree ((char *) children);
+	}
+      if (cur)
+	abort ();
+    }
+}
+
+
+/* update text widgets */
+
+static void
+xm_update_text (widget_instance* instance, Widget widget, widget_value* val)
+{
+  XmTextSetString (widget, val->value ? val->value : "");
+  XtRemoveAllCallbacks (widget, XmNactivateCallback);
+  XtAddCallback (widget, XmNactivateCallback, xm_generic_callback, instance);
+  XtRemoveAllCallbacks (widget, XmNvalueChangedCallback);
+  XtAddCallback (widget, XmNvalueChangedCallback,
+		 xm_internal_update_other_instances, instance);
+}
+
+static void
+xm_update_text_field (widget_instance* instance, Widget widget,
+		      widget_value* val)
+{
+  XmTextFieldSetString (widget, val->value ? val->value : "");
+  XtRemoveAllCallbacks (widget, XmNactivateCallback);
+  XtAddCallback (widget, XmNactivateCallback, xm_generic_callback, instance);
+  XtRemoveAllCallbacks (widget, XmNvalueChangedCallback);
+  XtAddCallback (widget, XmNvalueChangedCallback,
+		 xm_internal_update_other_instances, instance);
+}
+
+
+/* update a motif widget */
+
+void
+xm_update_one_widget (widget_instance* instance, Widget widget,
+		      widget_value* val, Boolean deep_p)
+{
+  WidgetClass class;
+  
+  /* Mark as not edited */
+  val->edited = False;
+
+  /* Common to all widget types */
+  XtVaSetValues (widget,
+		 XmNsensitive, val->enabled,
+		 XmNuserData, val->call_data,
+		 0);
+  
+  /* Common to all label like widgets */
+  if (XtIsSubclass (widget, xmLabelWidgetClass))
+    xm_update_label (instance, widget, val);
+  
+  class = XtClass (widget);
+  /* Class specific things */
+  if (class == xmPushButtonWidgetClass ||
+      class == xmArrowButtonWidgetClass)
+    {
+      xm_update_pushbutton (instance, widget, val);
+    }
+  else if (class == xmCascadeButtonWidgetClass)
+    {
+      xm_update_cascadebutton (instance, widget, val);
+    }
+  else if (class == xmToggleButtonWidgetClass
+	   || class == xmToggleButtonGadgetClass)
+    {
+      xm_update_toggle (instance, widget, val);
+    }
+  else if (class == xmRowColumnWidgetClass)
+    {
+      Boolean radiobox = 0;
+      int ac = 0;
+      Arg al [1];
+      
+      XtSetArg (al [ac], XmNradioBehavior, &radiobox); ac++;
+      XtGetValues (widget, al, ac);
+      
+      if (radiobox)
+	xm_update_radiobox (instance, widget, val);
+      else
+	xm_update_menu (instance, widget, val, deep_p);
+    }
+  else if (class == xmTextWidgetClass)
+    {
+      xm_update_text (instance, widget, val);
+    }
+  else if (class == xmTextFieldWidgetClass)
+    {
+      xm_update_text_field (instance, widget, val);
+    }
+  else if (class == xmListWidgetClass)
+    {
+      xm_update_list (instance, widget, val);
+    }
+}
+
+/* getting the value back */
+void
+xm_update_one_value (widget_instance* instance, Widget widget,
+		     widget_value* val)
+{
+  WidgetClass class = XtClass (widget);
+  widget_value *old_wv;
+
+  /* copy the call_data slot into the "return" widget_value */
+  for (old_wv = instance->info->val->contents; old_wv; old_wv = old_wv->next)
+    if (!strcmp (val->name, old_wv->name))
+      {
+	val->call_data = old_wv->call_data;
+	break;
+      }
+  
+  if (class == xmToggleButtonWidgetClass || class == xmToggleButtonGadgetClass)
+    {
+      XtVaGetValues (widget, XmNset, &val->selected, 0);
+      val->edited = True;
+    }
+  else if (class == xmTextWidgetClass)
+    {
+      if (val->value)
+	free (val->value);
+      val->value = XmTextGetString (widget);
+      val->edited = True;
+    }
+  else if (class == xmTextFieldWidgetClass)
+    {
+      if (val->value)
+	free (val->value);
+      val->value = XmTextFieldGetString (widget);
+      val->edited = True;
+    }
+  else if (class == xmRowColumnWidgetClass)
+    {
+      Boolean radiobox = 0;
+      int ac = 0;
+      Arg al [1];
+      
+      XtSetArg (al [ac], XmNradioBehavior, &radiobox); ac++;
+      XtGetValues (widget, al, ac);
+      
+      if (radiobox)
+	{
+	  CompositeWidget radio = (CompositeWidget)widget;
+	  int i;
+	  for (i = 0; i < radio->composite.num_children; i++)
+	    {
+	      int set = False;
+	      Widget toggle = radio->composite.children [i];
+	      
+	      XtVaGetValues (toggle, XmNset, &set, 0);
+	      if (set)
+		{
+		  if (val->value)
+		    free (val->value);
+		  val->value = strdup (XtName (toggle));
+		}
+	    }
+	  val->edited = True;
+	}
+    }
+  else if (class == xmListWidgetClass)
+    {
+      int pos_cnt;
+      int* pos_list;
+      if (XmListGetSelectedPos (widget, &pos_list, &pos_cnt))
+	{
+	  int i;
+	  widget_value* cur;
+	  for (cur = val->contents, i = 0; cur; cur = cur->next)
+	    if (cur->value)
+	      {
+		int j;
+		cur->selected = False;
+		i += 1;
+		for (j = 0; j < pos_cnt; j++)
+		  if (pos_list [j] == i)
+		    {
+		      cur->selected = True;
+		      val->value = strdup (cur->name);
+		    }
+	      }
+	  val->edited = 1;
+	  XtFree ((char *) pos_list);
+	}
+    }
+}
+
+
+/* This function is for activating a button from a program.  It's wrong because
+   we pass a NULL argument in the call_data which is not Motif compatible.
+   This is used from the XmNdefaultAction callback of the List widgets to
+   have a dble-click put down a dialog box like the button woudl do. 
+   I could not find a way to do that with accelerators.
+ */
+static void
+activate_button (Widget widget, XtPointer closure, XtPointer call_data)
+{
+  Widget button = (Widget)closure;
+  XtCallCallbacks (button, XmNactivateCallback, NULL);
+}
+
+/* creation functions */
+
+/* dialogs */
+static Widget
+make_dialog (char* name, Widget parent, Boolean pop_up_p,
+	     char* shell_title, char* icon_name, Boolean text_input_slot,
+	     Boolean radio_box, Boolean list,
+	     int left_buttons, int right_buttons)
+{
+  Widget result;
+  Widget form;
+  Widget row;
+  Widget icon;
+  Widget icon_separator;
+  Widget message;
+  Widget value = 0;
+  Widget separator;
+  Widget button = 0;
+  Widget children [16];		/* for the final XtManageChildren */
+  int	 n_children;
+  Arg 	al[64];			/* Arg List */
+  int 	ac;			/* Arg Count */
+  int 	i;
+  
+  if (pop_up_p)
+    {
+      ac = 0;
+      XtSetArg(al[ac], XmNtitle, shell_title); ac++;
+      XtSetArg(al[ac], XtNallowShellResize, True); ac++;
+      XtSetArg(al[ac], XmNdeleteResponse, XmUNMAP); ac++;
+      result = XmCreateDialogShell (parent, "dialog", al, ac);
+      ac = 0;
+      XtSetArg(al[ac], XmNautoUnmanage, FALSE); ac++;
+/*      XtSetArg(al[ac], XmNautoUnmanage, TRUE); ac++; */ /* ####is this ok? */
+      XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+      form = XmCreateForm (result, shell_title, al, ac);
+    }
+  else
+    {
+      ac = 0;
+      XtSetArg(al[ac], XmNautoUnmanage, FALSE); ac++;
+      XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+      form = XmCreateForm (parent, shell_title, al, ac);
+      result = form;
+    }
+
+  ac = 0;
+  XtSetArg(al[ac], XmNpacking, XmPACK_COLUMN); ac++;
+  XtSetArg(al[ac], XmNorientation, XmVERTICAL); ac++;
+  XtSetArg(al[ac], XmNnumColumns, left_buttons + right_buttons + 1); ac++;
+  XtSetArg(al[ac], XmNmarginWidth, 0); ac++;
+  XtSetArg(al[ac], XmNmarginHeight, 0); ac++;
+  XtSetArg(al[ac], XmNspacing, 13); ac++;
+  XtSetArg(al[ac], XmNadjustLast, False); ac++;
+  XtSetArg(al[ac], XmNalignment, XmALIGNMENT_CENTER); ac++;
+  XtSetArg(al[ac], XmNisAligned, True); ac++;
+  XtSetArg(al[ac], XmNtopAttachment, XmATTACH_NONE); ac++;
+  XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
+  XtSetArg(al[ac], XmNbottomOffset, 13); ac++;
+  XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
+  XtSetArg(al[ac], XmNleftOffset, 13); ac++;
+  XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
+  XtSetArg(al[ac], XmNrightOffset, 13); ac++;
+  row = XmCreateRowColumn (form, "row", al, ac);
+  
+  n_children = 0;
+  for (i = 0; i < left_buttons; i++)
+    {
+      char button_name [16];
+      sprintf (button_name, "button%d", i + 1);
+      ac = 0;
+      if (i == 0)
+	{
+	  XtSetArg(al[ac], XmNhighlightThickness, 1); ac++;
+	  XtSetArg(al[ac], XmNshowAsDefault, TRUE); ac++;
+	}
+      XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+      children [n_children] = XmCreatePushButton (row, button_name, al, ac);
+
+      if (i == 0)
+	{
+	  button = children [n_children];
+	  ac = 0;
+	  XtSetArg(al[ac], XmNdefaultButton, button); ac++;
+	  XtSetValues (row, al, ac);
+	}
+
+      n_children++;
+    }
+
+  /* invisible seperator button */
+  ac = 0;
+  XtSetArg (al[ac], XmNmappedWhenManaged, FALSE); ac++;
+  children [n_children] = XmCreateLabel (row, "separator_button", al, ac);
+  n_children++;
+  
+  for (i = 0; i < right_buttons; i++)
+    {
+      char button_name [16];
+      sprintf (button_name, "button%d", left_buttons + i + 1);
+      ac = 0;
+      XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+      children [n_children] = XmCreatePushButton (row, button_name, al, ac);
+      if (! button) button = children [n_children];
+      n_children++;
+    }
+  
+  XtManageChildren (children, n_children);
+  
+  ac = 0;
+  XtSetArg(al[ac], XmNtopAttachment, XmATTACH_NONE); ac++;
+  XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
+  XtSetArg(al[ac], XmNbottomOffset, 13); ac++;
+  XtSetArg(al[ac], XmNbottomWidget, row); ac++;
+  XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
+  XtSetArg(al[ac], XmNleftOffset, 0); ac++;
+  XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
+  XtSetArg(al[ac], XmNrightOffset, 0); ac++;
+  separator = XmCreateSeparator (form, "", al, ac);
+
+  ac = 0;
+  XtSetArg(al[ac], XmNlabelType, XmPIXMAP); ac++;
+  XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
+  XtSetArg(al[ac], XmNtopOffset, 13); ac++;
+  XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
+  XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
+  XtSetArg(al[ac], XmNleftOffset, 13); ac++;
+  XtSetArg(al[ac], XmNrightAttachment, XmATTACH_NONE); ac++;
+  icon = XmCreateLabel (form, icon_name, al, ac);
+
+  ac = 0;
+  XtSetArg(al[ac], XmNmappedWhenManaged, FALSE); ac++;
+  XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
+  XtSetArg(al[ac], XmNtopOffset, 6); ac++;
+  XtSetArg(al[ac], XmNtopWidget, icon); ac++;
+  XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
+  XtSetArg(al[ac], XmNbottomOffset, 6); ac++;
+  XtSetArg(al[ac], XmNbottomWidget, separator); ac++;
+  XtSetArg(al[ac], XmNleftAttachment, XmATTACH_NONE); ac++;
+  XtSetArg(al[ac], XmNrightAttachment, XmATTACH_NONE); ac++;
+  icon_separator = XmCreateLabel (form, "", al, ac);
+
+  if (text_input_slot)
+    {
+      ac = 0;
+      XtSetArg(al[ac], XmNcolumns, 50); ac++;
+      XtSetArg(al[ac], XmNtopAttachment, XmATTACH_NONE); ac++;
+      XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
+      XtSetArg(al[ac], XmNbottomOffset, 13); ac++;
+      XtSetArg(al[ac], XmNbottomWidget, separator); ac++;
+      XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
+      XtSetArg(al[ac], XmNleftOffset, 13); ac++;
+      XtSetArg(al[ac], XmNleftWidget, icon); ac++;
+      XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
+      XtSetArg(al[ac], XmNrightOffset, 13); ac++;
+      value = XmCreateTextField (form, "value", al, ac);
+    }
+  else if (radio_box)
+    {
+      Widget radio_butt;
+      ac = 0;
+      XtSetArg(al[ac], XmNmarginWidth, 0); ac++;
+      XtSetArg(al[ac], XmNmarginHeight, 0); ac++;
+      XtSetArg(al[ac], XmNspacing, 13); ac++;
+      XtSetArg(al[ac], XmNalignment, XmALIGNMENT_CENTER); ac++;
+      XtSetArg(al[ac], XmNorientation, XmHORIZONTAL); ac++;
+      XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
+      XtSetArg(al[ac], XmNbottomOffset, 13); ac++;
+      XtSetArg(al[ac], XmNbottomWidget, separator); ac++;
+      XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
+      XtSetArg(al[ac], XmNleftOffset, 13); ac++;
+      XtSetArg(al[ac], XmNleftWidget, icon); ac++;
+      XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
+      XtSetArg(al[ac], XmNrightOffset, 13); ac++;
+      value = XmCreateRadioBox (form, "radiobutton1", al, ac);
+      ac = 0;
+      i = 0;
+      radio_butt = XmCreateToggleButtonGadget (value, "radio1", al, ac);
+      children [i++] = radio_butt;
+      radio_butt = XmCreateToggleButtonGadget (value, "radio2", al, ac);
+      children [i++] = radio_butt;
+      radio_butt = XmCreateToggleButtonGadget (value, "radio3", al, ac);
+      children [i++] = radio_butt;
+      XtManageChildren (children, i);
+    }
+  else if (list)
+    {
+      ac = 0;
+      XtSetArg(al[ac], XmNvisibleItemCount, 5); ac++;
+      XtSetArg(al[ac], XmNtopAttachment, XmATTACH_NONE); ac++;
+      XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
+      XtSetArg(al[ac], XmNbottomOffset, 13); ac++;
+      XtSetArg(al[ac], XmNbottomWidget, separator); ac++;
+      XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
+      XtSetArg(al[ac], XmNleftOffset, 13); ac++;
+      XtSetArg(al[ac], XmNleftWidget, icon); ac++;
+      XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
+      XtSetArg(al[ac], XmNrightOffset, 13); ac++;
+      value = XmCreateScrolledList (form, "list", al, ac);
+
+      /* this is the easiest way I found to have the dble click in the
+	 list activate the default button */
+      XtAddCallback (value, XmNdefaultActionCallback, activate_button, button);
+    }
+  
+  ac = 0;
+  XtSetArg(al[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
+  XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
+  XtSetArg(al[ac], XmNtopOffset, 13); ac++;
+  XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
+  XtSetArg(al[ac], XmNbottomOffset, 13); ac++;
+  XtSetArg(al[ac], XmNbottomWidget,
+	   text_input_slot || radio_box || list ? value : separator); ac++;
+  XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
+  XtSetArg(al[ac], XmNleftOffset, 13); ac++;
+  XtSetArg(al[ac], XmNleftWidget, icon); ac++;
+  XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
+  XtSetArg(al[ac], XmNrightOffset, 13); ac++;
+  message = XmCreateLabel (form, "message", al, ac);
+  
+  if (list)
+    XtManageChild (value);
+
+  i = 0;
+  children [i] = row; i++;
+  children [i] = separator; i++;
+  if (text_input_slot || radio_box)
+    {
+      children [i] = value; i++;
+    }
+  children [i] = message; i++;
+  children [i] = icon; i++;
+  children [i] = icon_separator; i++;
+  XtManageChildren (children, i);
+  
+  if (text_input_slot || list)
+    {
+      XtInstallAccelerators (value, button);
+      XtSetKeyboardFocus (result, value);
+    }
+  else
+    {
+      XtInstallAccelerators (form, button);
+      XtSetKeyboardFocus (result, button);
+    }
+  
+  return result;
+}
+
+static destroyed_instance*
+find_matching_instance (widget_instance* instance)
+{
+  destroyed_instance*	cur;
+  destroyed_instance*	prev;
+  char*	type = instance->info->type;
+  char*	name = instance->info->name;
+
+  for (prev = NULL, cur = all_destroyed_instances;
+       cur;
+       prev = cur, cur = cur->next)
+    {
+      if (!strcmp (cur->name, name)
+	  && !strcmp (cur->type, type)
+	  && cur->parent == instance->parent
+	  && cur->pop_up_p == instance->pop_up_p)
+	{
+	  if (prev)
+	    prev->next = cur->next;
+	  else
+	    all_destroyed_instances = cur->next;
+	  return cur;
+	}
+      /* do some cleanup */
+      else if (!cur->widget)
+	{
+	  if (prev)
+	    prev->next = cur->next;
+	  else
+	    all_destroyed_instances = cur->next;
+	  free_destroyed_instance (cur);
+	  cur = prev ? prev : all_destroyed_instances;
+	}
+    }
+  return NULL;
+}
+
+static void
+mark_dead_instance_destroyed (Widget widget, XtPointer closure,
+			      XtPointer call_data)
+{
+  destroyed_instance* instance = (destroyed_instance*)closure;
+  instance->widget = NULL;
+}
+
+static void
+recenter_widget (Widget widget)
+{
+  Widget parent = XtParent (widget);
+  Screen* screen = XtScreen (widget);
+  Dimension screen_width = WidthOfScreen (screen);
+  Dimension screen_height = HeightOfScreen (screen);
+  Dimension parent_width = 0;
+  Dimension parent_height = 0;
+  Dimension child_width = 0;
+  Dimension child_height = 0;
+  Position x;
+  Position y;
+
+  XtVaGetValues (widget, XtNwidth, &child_width, XtNheight, &child_height, 0);
+  XtVaGetValues (parent, XtNwidth, &parent_width, XtNheight, &parent_height,
+		 0);
+
+  x = (((Position)parent_width) - ((Position)child_width)) / 2;
+  y = (((Position)parent_height) - ((Position)child_height)) / 2;
+  
+  XtTranslateCoords (parent, x, y, &x, &y);
+
+  if (x + child_width > screen_width)
+    x = screen_width - child_width;
+  if (x < 0)
+    x = 0;
+
+  if (y + child_height > screen_height)
+    y = screen_height - child_height;
+  if (y < 0)
+    y = 0;
+
+  XtVaSetValues (widget, XtNx, x, XtNy, y, 0);
+}
+
+static Widget
+recycle_instance (destroyed_instance* instance)
+{
+  Widget widget = instance->widget;
+
+  /* widget is NULL if the parent was destroyed. */
+  if (widget)
+    {
+      Widget focus;
+      Widget separator;
+
+      /* Remove the destroy callback as the instance is not in the list
+	 anymore */
+      XtRemoveCallback (instance->parent, XtNdestroyCallback,
+			mark_dead_instance_destroyed,
+			(XtPointer)instance);
+
+      /* Give the focus to the initial item */
+      focus = XtNameToWidget (widget, "*value");
+      if (!focus)
+	focus = XtNameToWidget (widget, "*button1");
+      if (focus)
+	XtSetKeyboardFocus (widget, focus);
+      
+      /* shrink the separator label back to their original size */
+      separator = XtNameToWidget (widget, "*separator_button");
+      if (separator)
+	XtVaSetValues (separator, XtNwidth, 5, XtNheight, 5, 0);
+
+      /* Center the dialog in its parent */
+      recenter_widget (widget);
+    }
+  free_destroyed_instance (instance);
+  return widget;
+}
+
+Widget
+xm_create_dialog (widget_instance* instance)
+{
+  char* 	name = instance->info->type;
+  Widget 	parent = instance->parent;
+  Widget	widget;
+  Boolean 	pop_up_p = instance->pop_up_p;
+  char*		shell_name = 0;
+  char* 	icon_name;
+  Boolean	text_input_slot = False;
+  Boolean	radio_box = False;
+  Boolean	list = False;
+  int		total_buttons;
+  int		left_buttons = 0;
+  int		right_buttons = 1;
+  destroyed_instance*	dead_one;
+
+  /* try to find a widget to recycle */
+  dead_one = find_matching_instance (instance);
+  if (dead_one)
+    {
+      Widget recycled_widget = recycle_instance (dead_one);
+      if (recycled_widget)
+	return recycled_widget;
+    }
+
+  switch (name [0]){
+  case 'E': case 'e':
+    icon_name = "dbox-error";
+    shell_name = "Error";
+    break;
+
+  case 'I': case 'i':
+    icon_name = "dbox-info";
+    shell_name = "Information";
+    break;
+
+  case 'L': case 'l':
+    list = True;
+    icon_name = "dbox-question";
+    shell_name = "Prompt";
+    break;
+
+  case 'P': case 'p':
+    text_input_slot = True;
+    icon_name = "dbox-question";
+    shell_name = "Prompt";
+    break;
+
+  case 'Q': case 'q':
+    icon_name = "dbox-question";
+    shell_name = "Question";
+    break;
+  }
+  
+  total_buttons = name [1] - '0';
+
+  if (name [3] == 'T' || name [3] == 't')
+    {
+      text_input_slot = False;
+      radio_box = True;
+    }
+  else if (name [3])
+    right_buttons = name [4] - '0';
+  
+  left_buttons = total_buttons - right_buttons;
+  
+  widget = make_dialog (name, parent, pop_up_p,
+			shell_name, icon_name, text_input_slot, radio_box,
+			list, left_buttons, right_buttons);
+
+  XtAddCallback (widget, XmNpopdownCallback, xm_nosel_callback,
+		 (XtPointer) instance);
+  return widget;
+}
+
+static Widget
+make_menubar (widget_instance* instance)
+{
+  return XmCreateMenuBar (instance->parent, instance->info->name, NULL, 0);
+}
+
+static void
+remove_grabs (Widget shell, XtPointer closure, XtPointer call_data)
+{
+  XmRowColumnWidget menu = (XmRowColumnWidget) closure;
+  XmRemoveFromPostFromList (menu, XtParent (XtParent ((Widget) menu)));
+}
+
+static Widget
+make_popup_menu (widget_instance* instance)
+{
+  Widget parent = instance->parent;
+  Window parent_window = parent->core.window;
+  Widget result;
+
+  /* sets the parent window to 0 to fool Motif into not generating a grab */
+  parent->core.window = 0;
+  result = XmCreatePopupMenu (parent, instance->info->name, NULL, 0);
+  XtAddCallback (XtParent (result), XmNpopdownCallback, remove_grabs,
+		 (XtPointer)result);
+  parent->core.window = parent_window;
+  return result;
+}
+
+/* Table of functions to create widgets */
+
+#ifdef ENERGIZE
+
+/* interface with the XDesigner generated functions */
+typedef Widget (*widget_maker) (Widget);
+extern Widget create_project_p_sheet (Widget parent);
+extern Widget create_debugger_p_sheet (Widget parent);
+extern Widget create_breaklist_p_sheet (Widget parent);
+extern Widget create_le_browser_p_sheet (Widget parent);
+extern Widget create_class_browser_p_sheet (Widget parent);
+extern Widget create_call_browser_p_sheet (Widget parent);
+extern Widget create_build_dialog (Widget parent);
+extern Widget create_editmode_dialog (Widget parent);
+extern Widget create_search_dialog (Widget parent);
+extern Widget create_project_display_dialog (Widget parent);
+
+static Widget
+make_one (widget_instance* instance, widget_maker fn)
+{
+  Widget result;
+  Arg 	al [64];
+  int 	ac = 0;
+
+  if (instance->pop_up_p)
+    {
+      XtSetArg (al [ac], XmNallowShellResize, TRUE); ac++;
+      result = XmCreateDialogShell (instance->parent, "dialog", NULL, 0);
+      XtAddCallback (result, XmNpopdownCallback, &xm_nosel_callback,
+		     (XtPointer) instance);
+      (*fn) (result);
+    }
+  else
+    {
+      result = (*fn) (instance->parent);
+      XtRealizeWidget (result);
+    }
+  return result;
+}
+
+static Widget
+make_project_p_sheet (widget_instance* instance)
+{
+  return make_one (instance, create_project_p_sheet);
+}
+
+static Widget
+make_debugger_p_sheet (widget_instance* instance)
+{
+  return make_one (instance, create_debugger_p_sheet);
+}
+
+static Widget
+make_breaklist_p_sheet (widget_instance* instance)
+{
+  return make_one (instance, create_breaklist_p_sheet);
+}
+
+static Widget
+make_le_browser_p_sheet (widget_instance* instance)
+{
+  return make_one (instance, create_le_browser_p_sheet);
+}
+
+static Widget
+make_class_browser_p_sheet (widget_instance* instance)
+{
+  return make_one (instance, create_class_browser_p_sheet);
+}
+
+static Widget
+make_call_browser_p_sheet (widget_instance* instance)
+{
+  return make_one (instance, create_call_browser_p_sheet);
+}
+
+static Widget
+make_build_dialog (widget_instance* instance)
+{
+  return make_one (instance, create_build_dialog);
+}
+
+static Widget
+make_editmode_dialog (widget_instance* instance)
+{
+  return make_one (instance, create_editmode_dialog);
+}
+
+static Widget
+make_search_dialog (widget_instance* instance)
+{
+  return make_one (instance, create_search_dialog);
+}
+
+static Widget
+make_project_display_dialog (widget_instance* instance)
+{
+  return make_one (instance, create_project_display_dialog);
+}
+
+#endif /* ENERGIZE */
+
+widget_creation_entry
+xm_creation_table [] = 
+{
+  {"menubar", 			make_menubar},
+  {"popup",			make_popup_menu},
+#ifdef ENERGIZE
+  {"project_p_sheet",		make_project_p_sheet},
+  {"debugger_p_sheet",		make_debugger_p_sheet},
+  {"breaklist_psheet",		make_breaklist_p_sheet},
+  {"leb_psheet",       		make_le_browser_p_sheet},
+  {"class_browser_psheet",	make_class_browser_p_sheet},
+  {"ctree_browser_psheet",	make_call_browser_p_sheet},
+  {"build",			make_build_dialog},
+  {"editmode",			make_editmode_dialog},
+  {"search",			make_search_dialog},
+  {"project_display",		make_project_display_dialog},
+#endif /* ENERGIZE */
+  {NULL, NULL}
+};
+
+/* Destruction of instances */
+void
+xm_destroy_instance (widget_instance* instance)
+{
+  Widget widget = instance->widget;
+  /* recycle the dialog boxes */
+  /* Disable the recycling until we can find a way to have the dialog box
+     get reasonable layout after we modify its contents. */
+  if (0
+      && XtClass (widget) == xmDialogShellWidgetClass)
+    {
+      destroyed_instance* dead_instance =
+	make_destroyed_instance (instance->info->name,
+				 instance->info->type,
+				 instance->widget,
+				 instance->parent,
+				 instance->pop_up_p);
+      dead_instance->next = all_destroyed_instances;
+      all_destroyed_instances = dead_instance;
+      XtUnmanageChild (first_child (instance->widget));
+      XFlush (XtDisplay (instance->widget));
+      XtAddCallback (instance->parent, XtNdestroyCallback,
+		     mark_dead_instance_destroyed, (XtPointer)dead_instance);
+    }
+  else
+    {
+      /* This might not be necessary now that the nosel is attached to
+	 popdown instead of destroy, but it can't hurt. */
+      XtRemoveCallback (instance->widget, XtNdestroyCallback,
+			xm_nosel_callback, (XtPointer)instance);
+      XtDestroyWidget (instance->widget);
+    }
+}
+
+/* popup utility */
+void
+xm_popup_menu (Widget widget)
+{
+  XButtonPressedEvent dummy;
+  XEvent* event;
+
+  dummy.type = ButtonPress;
+  dummy.serial = 0;
+  dummy.send_event = 0;
+  dummy.display = XtDisplay (widget);
+  dummy.window = XtWindow (XtParent (widget));
+  dummy.time = 0;
+  dummy.button = 0;
+  XQueryPointer (dummy.display, dummy.window, &dummy.root,
+		 &dummy.subwindow, &dummy.x_root, &dummy.y_root,
+		 &dummy.x, &dummy.y, &dummy.state);
+  event = (XEvent *) &dummy;
+
+  if (event->type == ButtonPress || event->type == ButtonRelease)
+    {
+      /* This is so totally ridiculous: there's NO WAY to tell Motif
+	 that *any* button can select a menu item.  Only one button
+	 can have that honor.
+       */
+      char *trans = 0;
+      if      (event->xbutton.state & Button5Mask) trans = "<Btn5Down>";
+      else if (event->xbutton.state & Button4Mask) trans = "<Btn4Down>";
+      else if (event->xbutton.state & Button3Mask) trans = "<Btn3Down>";
+      else if (event->xbutton.state & Button2Mask) trans = "<Btn2Down>";
+      else if (event->xbutton.state & Button1Mask) trans = "<Btn1Down>";
+      if (trans) XtVaSetValues (widget, XmNmenuPost, trans, 0);
+      XmMenuPosition (widget, (XButtonPressedEvent *) event);
+    }
+  XtManageChild (widget);
+}
+
+static void
+set_min_dialog_size (Widget w)
+{
+  short width;
+  short height;
+  XtVaGetValues (w, XmNwidth, &width, XmNheight, &height, 0);
+  XtVaSetValues (w, XmNminWidth, width, XmNminHeight, height, 0);
+}
+
+void
+xm_pop_instance (widget_instance* instance, Boolean up)
+{
+  Widget widget = instance->widget;
+
+  if (XtClass (widget) == xmDialogShellWidgetClass)
+    {
+      Widget widget_to_manage = first_child (widget);
+      if (up)
+	{
+	  XtManageChild (widget_to_manage);
+	  set_min_dialog_size (widget);
+	  XtSetKeyboardFocus (instance->parent, widget);
+	}
+      else
+	XtUnmanageChild (widget_to_manage);
+    }
+  else
+    {
+      if (up)
+	XtManageChild (widget);
+      else
+	XtUnmanageChild (widget);	
+    }
+}
+
+
+/* motif callback */ 
+
+enum do_call_type { pre_activate, selection, no_selection, post_activate };
+
+static void
+do_call (Widget widget, XtPointer closure, enum do_call_type type)
+{
+  Arg al [256];
+  int ac;
+  XtPointer user_data;
+  widget_instance* instance = (widget_instance*)closure;
+  Widget instance_widget;
+  LWLIB_ID id;
+
+  if (!instance)
+    return;
+  if (widget->core.being_destroyed)
+    return;
+
+  instance_widget = instance->widget;
+  if (!instance_widget)
+    return;
+
+  id = instance->info->id;
+  ac = 0;
+  user_data = NULL;
+  XtSetArg (al [ac], XmNuserData, &user_data); ac++;
+  XtGetValues (widget, al, ac);
+  switch (type)
+    {
+    case pre_activate:
+      if (instance->info->pre_activate_cb)
+	instance->info->pre_activate_cb (widget, id, user_data);
+      break;
+    case selection:
+      if (instance->info->selection_cb)
+	instance->info->selection_cb (widget, id, user_data);
+      break;
+    case no_selection:
+      if (instance->info->selection_cb)
+	instance->info->selection_cb (widget, id, (XtPointer) -1);
+      break;
+    case post_activate:
+      if (instance->info->post_activate_cb)
+	instance->info->post_activate_cb (widget, id, user_data);
+      break;
+    default:
+      abort ();
+    }
+}
+
+/* Like lw_internal_update_other_instances except that it does not do
+   anything if its shell parent is not managed.  This is to protect 
+   lw_internal_update_other_instances to dereference freed memory
+   if the widget was ``destroyed'' by caching it in the all_destroyed_instances
+   list */
+static void
+xm_internal_update_other_instances (Widget widget, XtPointer closure,
+				    XtPointer call_data)
+{
+  Widget parent;
+  for (parent = widget; parent; parent = XtParent (parent))
+    if (XtIsShell (parent))
+      break;
+    else if (!XtIsManaged (parent))
+      return;
+   lw_internal_update_other_instances (widget, closure, call_data);
+}
+
+static void
+xm_generic_callback (Widget widget, XtPointer closure, XtPointer call_data)
+{
+  lw_internal_update_other_instances (widget, closure, call_data);
+  do_call (widget, closure, selection);
+}
+
+static void
+xm_nosel_callback (Widget widget, XtPointer closure, XtPointer call_data)
+{
+  /* This callback is only called when a dialog box is dismissed with the wm's
+     destroy button (WM_DELETE_WINDOW.)  We want the dialog box to be destroyed
+     in that case, not just unmapped, so that it releases its keyboard grabs.
+     But there are problems with running our callbacks while the widget is in
+     the process of being destroyed, so we set XmNdeleteResponse to XmUNMAP
+     instead of XmDESTROY and then destroy it ourself after having run the
+     callback.
+   */
+  do_call (widget, closure, no_selection);
+  XtDestroyWidget (widget);
+}
+
+static void
+xm_pull_down_callback (Widget widget, XtPointer closure, XtPointer call_data)
+{
+  do_call (widget, closure, pre_activate);
+}
+
+static void
+xm_pop_down_callback (Widget widget, XtPointer closure, XtPointer call_data)
+{
+  do_call (widget, closure, post_activate);
+}
+
+
+/* set the keyboard focus */
+void
+xm_set_keyboard_focus (Widget parent, Widget w)
+{
+  XmProcessTraversal (w, 0);
+  XtSetKeyboardFocus (parent, w);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwlib/lwlib-Xm.h	Tue Jan 18 23:47:41 1994 +0000
@@ -0,0 +1,34 @@
+#ifndef LWLIB_XM_H
+#define LWLIB_XM_H
+
+#include "lwlib-internal.h"
+
+extern widget_creation_entry xm_creation_table [];
+
+Widget 
+xm_create_dialog (widget_instance* instance);
+
+Boolean
+lw_motif_widget_p (Widget widget);
+
+void
+xm_update_one_widget (widget_instance* instance, Widget widget,
+		      widget_value* val, Boolean deep_p);
+
+void
+xm_update_one_value (widget_instance* instance, Widget widget,
+		     widget_value* val);
+
+void
+xm_destroy_instance (widget_instance* instance);
+
+void
+xm_set_keyboard_focus (Widget parent, Widget w);
+
+void
+xm_popup_menu (Widget widget);
+
+void
+xm_pop_instance (widget_instance* instance, Boolean up);
+
+#endif /* LWLIB_XM_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwlib/lwlib-Xol.h	Tue Jan 18 23:47:41 1994 +0000
@@ -0,0 +1,29 @@
+#ifndef LWLIB_XOL_H
+#define LWLIB_XOL_H
+
+#include "lwlib-internal.h"
+
+extern widget_creation_entry xol_creation_table [];
+extern Widget xol_create_dialog (widget_instance *);
+
+Boolean
+lw_olit_widget_p (Widget widget);
+
+void
+xol_update_one_widget (widget_instance* instance, Widget widget,
+		       widget_value* val, Boolean deep_p);
+
+void
+xol_update_one_value (widget_instance* instance, Widget widget,
+		      widget_value* val);
+
+void
+xol_destroy_instance (widget_instance* instance);
+
+void
+xol_pop_instance (widget_instance* instance, Boolean up);
+
+void
+xol_popup_menu (Widget widget);
+
+#endif /* LWLIB_XOL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwlib/lwlib-int.h	Tue Jan 18 23:47:41 1994 +0000
@@ -0,0 +1,54 @@
+#ifndef LWLIB_INTERNAL_H
+#define LWLIB_INTERNAL_H
+
+#include "lwlib.h"
+
+/*
+extern char *strdup (const char *);
+extern int strcasecmp (const char *, const char *);
+*/
+
+typedef struct _widget_instance
+{
+  Widget		widget;
+  Widget		parent;
+  Boolean		pop_up_p;
+  struct _widget_info*		info;
+  struct _widget_instance*	next;
+} widget_instance;
+
+typedef struct _widget_info
+{
+  char*			type;
+  char*			name;
+  LWLIB_ID		id;
+  widget_value*		val;
+  Boolean		busy;
+  lw_callback		pre_activate_cb;
+  lw_callback		selection_cb;
+  lw_callback		post_activate_cb;
+  struct _widget_instance*	instances;
+  struct _widget_info*		next;
+} widget_info;
+
+typedef Widget
+(*widget_creation_function) (widget_instance* instance);
+
+typedef struct _widget_creation_entry
+{
+  char*				type;
+  widget_creation_function	function;
+} widget_creation_entry;
+
+/* update all other instances of a widget.  Can be used in a callback when
+   a wiget has been used by the user */
+void
+lw_internal_update_other_instances (Widget widget, XtPointer closure,
+				    XtPointer call_data);
+
+/* get the widget_value for a widget in a given instance */
+widget_value*
+lw_get_widget_value_for_widget (widget_instance* instance, Widget w);
+
+#endif /* LWLIB_INTERNAL_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwlib/lwlib-utils.c	Tue Jan 18 23:47:41 1994 +0000
@@ -0,0 +1,162 @@
+/* Defines some widget utility functions.
+   Copyright (C) 1992 Lucid, Inc.
+
+This file is part of the Lucid Widget Library.
+
+The Lucid Widget Library is free software; you can redistribute it and/or 
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+The Lucid Widget Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of 
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <memory.h>
+
+#include <X11/Xatom.h>
+#include <X11/IntrinsicP.h>
+#include <X11/ObjectP.h>
+#include "lwlib-utils.h"
+
+/* Redisplay the contents of the widget, without first clearing it. */
+void
+XtNoClearRefreshWidget (Widget widget)
+{
+  XEvent event;
+
+  event.type = Expose;
+  event.xexpose.serial = 0;
+  event.xexpose.send_event = 0;
+  event.xexpose.display = XtDisplay (widget);
+  event.xexpose.window = XtWindow (widget);
+  event.xexpose.x = 0;
+  event.xexpose.y = 0;
+  event.xexpose.width = widget->core.width;
+  event.xexpose.height = widget->core.height;
+  event.xexpose.count = 0;
+
+  (*widget->core.widget_class->core_class.expose)
+    (widget, &event, (Region)NULL);
+}
+
+
+/* 
+ * Apply a function to all the subwidgets of a given widget recursively.
+*/
+void
+XtApplyToWidgets (Widget w, XtApplyToWidgetsProc proc, XtPointer arg)
+{
+  if (XtIsComposite (w))
+    {
+      CompositeWidget cw = (CompositeWidget) w;
+      /* We have to copy the children list before mapping over it, because
+	 the procedure might add/delete elements, which would lose badly.
+	 */
+      int nkids = cw->composite.num_children;
+      Widget *kids = (Widget *) malloc (sizeof (Widget) * nkids);
+      int i;
+      memcpy (kids, cw->composite.children, sizeof (Widget) * nkids);
+      for (i = 0; i < nkids; i++)
+/* This prevent us from using gadgets, why is it here? */
+/*	if (XtIsWidget (kids [i])) */
+	  {
+	    /* do the kiddies first in case we're destroying */
+	    XtApplyToWidgets (kids [i], proc, arg);
+	    proc (kids [i], arg);
+	  }
+      free (kids);
+    }
+}
+
+
+/*
+ * Apply a function to all the subwidgets of a given widget recursively.
+ * Stop as soon as the function returns non NULL and returns this as a value.
+ */
+void *
+XtApplyUntilToWidgets (Widget w, XtApplyUntilToWidgetsProc proc, XtPointer arg)
+{
+  void* result;
+  if (XtIsComposite (w))
+    {
+      CompositeWidget cw = (CompositeWidget)w;
+      int i;
+      for (i = 0; i < cw->composite.num_children; i++)
+	if (XtIsWidget (cw->composite.children [i])){
+	  result = proc (cw->composite.children [i], arg);
+	  if (result)
+	    return result;
+	  result = XtApplyUntilToWidgets (cw->composite.children [i], proc,
+					  arg);
+	  if (result)
+	    return result;
+	}
+    }
+  return NULL;
+}
+
+
+/*
+ * Returns a copy of the list of all children of a composite widget
+ */
+Widget *
+XtCompositeChildren (Widget widget, unsigned int* number)
+{
+  CompositeWidget cw = (CompositeWidget)widget;
+  Widget* result;
+  int n;
+  int i;
+
+  if (!XtIsComposite (widget))
+    {
+      *number = 0;
+      return NULL;
+    }
+  n = cw->composite.num_children;
+  result = (Widget*)XtMalloc (n * sizeof (Widget));
+  *number = n;
+  for (i = 0; i < n; i++)
+    result [i] = cw->composite.children [i];
+  return result;
+}
+
+Boolean
+XtWidgetBeingDestroyedP (Widget widget)
+{
+  return widget->core.being_destroyed;
+}
+
+void
+XtSafelyDestroyWidget (Widget widget)
+{
+#if 0
+
+  /* this requires IntrinsicI.h (actually, InitialI.h) */
+
+  XtAppContext app = XtWidgetToApplicationContext(widget);
+
+  if (app->dispatch_level == 0)
+    {
+      app->dispatch_level = 1;
+      XtDestroyWidget (widget);
+      /* generates an event so that the event loop will be called */
+      XChangeProperty (XtDisplay (widget), XtWindow (widget),
+		       XA_STRING, XA_STRING, 32, PropModeAppend, NULL, 0);
+      app->dispatch_level = 0;
+    }
+  else
+    XtDestroyWidget (widget);
+  
+#else
+  abort ();
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwlib/lwlib-utils.h	Tue Jan 18 23:47:41 1994 +0000
@@ -0,0 +1,20 @@
+#ifndef _LWLIB_UTILS_H_
+#define _LWLIB_UTILS_H_
+
+void XtNoClearRefreshWidget (Widget);
+
+typedef void (*XtApplyToWidgetsProc) (Widget, XtPointer);
+typedef void* (*XtApplyUntilToWidgetsProc) (Widget, XtPointer);
+
+void XtApplyToWidgets (Widget, XtApplyToWidgetsProc, XtPointer);
+void *XtApplyUntilToWidgets (Widget, XtApplyUntilToWidgetsProc, XtPointer);
+
+Widget *XtCompositeChildren (Widget, unsigned int *);
+
+/* returns True is the widget is being destroyed, False otherwise */
+Boolean
+XtWidgetBeingDestroyedP (Widget widget);
+
+void XtSafelyDestroyWidget (Widget);
+
+#endif /* _LWLIB_UTILS_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwlib/lwlib.c	Tue Jan 18 23:47:41 1994 +0000
@@ -0,0 +1,1111 @@
+/* A general interface to the widgets of different toolkits.
+   Copyright (C) 1992, 1993 Lucid, Inc.
+
+This file is part of the Lucid Widget Library.
+
+The Lucid Widget Library is free software; you can redistribute it and/or 
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+The Lucid Widget Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of 
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#ifdef NeXT
+#undef __STRICT_BSD__ /* ick */
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdio.h>
+#include <X11/StringDefs.h>
+#include "lwlib-internal.h"
+#include "lwlib-utils.h"
+
+#if defined(__GNUC__) && !defined(alloca)
+#define alloca __builtin_alloca
+#endif
+
+#if ((!__GNUC__) && !defined(__hpux)) && !defined(AIXV3)
+#include <alloca.h>
+#endif
+
+#if defined(AIXV3)
+#pragma alloca
+#endif
+
+#if defined (USE_LUCID)
+#include "lwlib-Xlw.h"
+#endif
+#if defined (USE_MOTIF)
+#include "lwlib-Xm.h"
+#endif
+#if defined (USE_OLIT)
+#include "lwlib-Xol.h"
+#endif
+
+#if !defined (USE_LUCID) && !defined (USE_MOTIF) && !defined (USE_OLIT)
+ERROR!  At least one of USE_LUCID, USE_MOTIF or USE_OLIT must be defined.
+#endif
+
+#if defined (USE_MOTIF) && defined (USE_OLIT)
+ERROR! no more than one of USE_MOTIF and USE_OLIT may be defined.
+#endif
+
+/* List of all widgets managed by the library. */
+static widget_info*
+all_widget_info = NULL;
+
+/* Forward declarations */
+static void
+instanciate_widget_instance (widget_instance* instance);
+
+/* utility functions for widget_instance and widget_info */
+static char *
+safe_strdup (char* s)
+{
+  char *result;
+  if (! s) return 0;
+  result = (char *) malloc (strlen (s) + 1);
+  if (! result)
+    return 0;
+  strcpy (result, s);
+  return result;
+}
+
+static void
+safe_free_str (char* s)
+{
+  if (s) free (s);
+}
+
+static widget_value *widget_value_free_list = 0;
+
+widget_value *
+malloc_widget_value ()
+{
+  widget_value *wv;
+  if (widget_value_free_list)
+    {
+      wv = widget_value_free_list;
+      widget_value_free_list = wv->free_list;
+      wv->free_list = 0;
+    }
+  else
+    {
+      wv = (widget_value *) malloc (sizeof (widget_value));
+    }
+  memset (wv, 0, sizeof (widget_value));
+  return wv;
+}
+
+/* this is analagous to free().  It frees only what was allocated
+   by malloc_widget_value(), and no substructures. 
+ */
+void
+free_widget_value (wv)
+     widget_value *wv;
+{
+  if (wv->free_list)
+    abort ();
+  wv->free_list = widget_value_free_list;
+  widget_value_free_list = wv;
+}
+
+static void
+free_widget_value_tree (widget_value* wv)
+{
+  if (!wv)
+    return;
+
+  if (wv->name) free (wv->name);
+  if (wv->value) free (wv->value);
+  if (wv->key) free (wv->key);
+
+  wv->name = wv->value = wv->key = (char *) 0xDEADBEEF;
+
+  if (wv->toolkit_data && wv->free_toolkit_data)
+    {
+      free (wv->toolkit_data);
+      wv->toolkit_data = (void *) 0xDEADBEEF;
+    }
+
+  if (wv->contents && (wv->contents != (widget_value*)1))
+    {
+      free_widget_value_tree (wv->contents);
+      wv->contents = (widget_value *) 0xDEADBEEF;
+    }
+  if (wv->next)
+    {
+      free_widget_value_tree (wv->next);
+      wv->next = (widget_value *) 0xDEADBEEF;
+    }
+  free_widget_value (wv);
+}
+
+static widget_value *
+copy_widget_value_tree (widget_value* val, change_type change)
+{
+  widget_value* copy;
+  
+  if (!val)
+    return NULL;
+  if (val == (widget_value *) 1)
+    return val;
+
+  copy = malloc_widget_value ();
+  copy->name = safe_strdup (val->name);
+  copy->value = safe_strdup (val->value);
+  copy->key = safe_strdup (val->key);
+  copy->enabled = val->enabled;
+  copy->selected = val->selected;
+  copy->edited = False;
+  copy->change = change;
+  copy->contents = copy_widget_value_tree (val->contents, change);
+  copy->call_data = val->call_data;
+  copy->next = copy_widget_value_tree (val->next, change);
+  copy->toolkit_data = NULL;
+  copy->free_toolkit_data = False;
+  return copy;
+}
+
+static widget_info *
+allocate_widget_info (char* type, char* name, LWLIB_ID id, widget_value* val,
+		      lw_callback pre_activate_cb, lw_callback selection_cb,
+		      lw_callback post_activate_cb)
+{
+  widget_info* info = (widget_info*)malloc (sizeof (widget_info));
+  info->type = safe_strdup (type);
+  info->name = safe_strdup (name);
+  info->id = id;
+  info->val = copy_widget_value_tree (val, STRUCTURAL_CHANGE);
+  info->busy = False;
+  info->pre_activate_cb = pre_activate_cb;
+  info->selection_cb = selection_cb;
+  info->post_activate_cb = post_activate_cb;
+  info->instances = NULL;
+
+  info->next = all_widget_info;
+  all_widget_info = info;
+
+  return info;
+}
+
+static void
+free_widget_info (widget_info* info)
+{
+  safe_free_str (info->type);
+  safe_free_str (info->name);
+  free_widget_value_tree (info->val);
+  memset ((void*)info, 0xDEADBEEF, sizeof (widget_info));
+  free (info);
+}
+
+static void
+mark_widget_destroyed (Widget widget, XtPointer closure, XtPointer call_data)
+{
+  widget_instance* instance = (widget_instance*)closure;
+
+  /* be very conservative */
+  if (instance->widget == widget)
+    instance->widget = NULL;
+}
+
+static widget_instance *
+allocate_widget_instance (widget_info* info, Widget parent, Boolean pop_up_p)
+{
+  widget_instance* instance =
+    (widget_instance*)malloc (sizeof (widget_instance));
+  instance->parent = parent;
+  instance->pop_up_p = pop_up_p;
+  instance->info = info;
+  instance->next = info->instances;
+  info->instances = instance;
+
+  instanciate_widget_instance (instance);
+
+  XtAddCallback (instance->widget, XtNdestroyCallback,
+		 mark_widget_destroyed, (XtPointer)instance);
+  return instance;
+}
+
+static void
+free_widget_instance (widget_instance* instance)
+{
+  memset ((void*)instance, 0xDEADBEEF, sizeof (widget_instance));
+  free (instance);
+}
+
+static widget_info *
+get_widget_info (LWLIB_ID id, Boolean remove_p)
+{
+  widget_info* info;
+  widget_info* prev;
+  for (prev = NULL, info = all_widget_info;
+       info;
+       prev = info, info = info->next)
+    if (info->id == id)
+     {
+       if (remove_p)
+	 {
+	   if (prev)
+	     prev->next = info->next;
+	   else
+	     all_widget_info = info->next;
+	 }
+      return info;
+     }
+  return NULL;
+}
+
+static widget_instance *
+get_widget_instance (Widget widget, Boolean remove_p)
+{
+  widget_info* info;
+  widget_instance* instance;
+  widget_instance* prev;
+  for (info = all_widget_info; info; info = info->next)
+    for (prev = NULL, instance = info->instances;
+	 instance;
+	 prev = instance, instance = instance->next)
+      if (instance->widget == widget)
+	{
+	  if (remove_p)
+	    {
+	      if (prev)
+		prev->next = instance->next;
+	      else
+		info->instances = instance->next;
+	    }
+	  return instance;
+	}
+  return (widget_instance *) 0;
+}
+
+static widget_instance*
+find_instance (LWLIB_ID id, Widget parent, Boolean pop_up_p)
+{
+  widget_info* info = get_widget_info (id, False);
+  widget_instance* instance;
+
+  if (info)
+    for (instance = info->instances; instance; instance = instance->next)
+      if (instance->parent == parent && instance->pop_up_p == pop_up_p)
+	return instance;
+
+  return NULL;
+}
+
+
+/* utility function for widget_value */
+static Boolean
+safe_strcmp (char* s1, char* s2)
+{
+  if (!!s1 ^ !!s2) return True;
+  return (s1 && s2) ? strcmp (s1, s2) : s1 ? False : !!s2;
+}
+
+static int
+max (int i1, int i2)
+{
+  return i1 > i2 ? i1 : i2;
+}
+
+
+#if 0
+# define EXPLAIN(name, oc, nc, desc, a1, a2)				\
+   printf ("Change: \"%s\"\tmax(%s=%d,%s=%d)\t%s %d %d\n",		\
+	   name,							\
+	   (oc == NO_CHANGE ? "none" :					\
+	    (oc == INVISIBLE_CHANGE ? "invisible" :			\
+	     (oc == VISIBLE_CHANGE ? "visible" :			\
+	      (oc == STRUCTURAL_CHANGE ? "structural" : "???")))),	\
+	   oc,								\
+	   (nc == NO_CHANGE ? "none" :					\
+	    (nc == INVISIBLE_CHANGE ? "invisible" :			\
+	     (nc == VISIBLE_CHANGE ? "visible" :			\
+	      (nc == STRUCTURAL_CHANGE ? "structural" : "???")))),	\
+	   nc, desc, a1, a2)
+#else
+# define EXPLAIN(name, oc, nc, desc, a1, a2)
+#endif
+
+
+static widget_value *
+merge_widget_value (widget_value* val1, widget_value* val2, int level)
+{
+  change_type change;
+  widget_value* merged_next;
+  widget_value* merged_contents;
+
+  if (!val1)
+    {
+      if (val2)
+	return copy_widget_value_tree (val2, STRUCTURAL_CHANGE);
+      else
+	return NULL;
+    }
+  if (!val2)
+    {
+      free_widget_value_tree (val1);
+      return NULL;
+    }
+  
+  change = NO_CHANGE;
+
+  if (safe_strcmp (val1->name, val2->name))
+    {
+      EXPLAIN (val1->name, change, STRUCTURAL_CHANGE, "name change",
+	       val1->name, val2->name);
+      change = max (change, STRUCTURAL_CHANGE);
+      safe_free_str (val1->name);
+      val1->name = safe_strdup (val2->name);
+    }
+  if (safe_strcmp (val1->value, val2->value))
+    {
+      EXPLAIN (val1->name, change, VISIBLE_CHANGE, "value change",
+	       val1->value, val2->value);
+      change = max (change, VISIBLE_CHANGE);
+      safe_free_str (val1->value);
+      val1->value = safe_strdup (val2->value);
+    }
+  if (safe_strcmp (val1->key, val2->key))
+    {
+      EXPLAIN (val1->name, change, VISIBLE_CHANGE, "key change",
+	       val1->key, val2->key);
+      change = max (change, VISIBLE_CHANGE);
+      safe_free_str (val1->key);
+      val1->key = safe_strdup (val2->key);
+    }
+  if (val1->enabled != val2->enabled)
+    {
+      EXPLAIN (val1->name, change, VISIBLE_CHANGE, "enablement change",
+	       val1->enabled, val2->enabled);
+      change = max (change, VISIBLE_CHANGE);
+      val1->enabled = val2->enabled;
+    }
+  if (val1->selected != val2->selected)
+    {
+      EXPLAIN (val1->name, change, VISIBLE_CHANGE, "selection change",
+	       val1->selected, val2->selected);
+      change = max (change, VISIBLE_CHANGE);
+      val1->selected = val2->selected;
+    }
+  if (val1->call_data != val2->call_data)
+    {
+      EXPLAIN (val1->name, change, INVISIBLE_CHANGE, "call-data change",
+	       val1->call_data, val2->call_data);
+      change = max (change, INVISIBLE_CHANGE);
+      val1->call_data = val2->call_data;
+    }
+
+  if (level > 0)
+    {
+      merged_contents =
+	merge_widget_value (val1->contents, val2->contents, level - 1);
+      
+      if (val1->contents && !merged_contents)
+	{
+	  EXPLAIN (val1->name, change, INVISIBLE_CHANGE, "(contents gone)",
+		   0, 0);
+	  change = max (change, INVISIBLE_CHANGE);
+	}
+      else if (merged_contents && merged_contents->change != NO_CHANGE)
+	{
+	  EXPLAIN (val1->name, change, INVISIBLE_CHANGE, "(contents change)",
+		   0, 0);
+	  change = max (change, INVISIBLE_CHANGE);
+	}
+      
+      val1->contents = merged_contents;
+    }
+
+  merged_next = merge_widget_value (val1->next, val2->next, level);
+
+  if (val1->next && !merged_next)
+    {
+      EXPLAIN (val1->name, change, STRUCTURAL_CHANGE, "(following gone)",
+	       0, 0);
+      change = max (change, STRUCTURAL_CHANGE);
+    }
+  else if (merged_next)
+    {
+      if (merged_next->change)
+	EXPLAIN (val1->name, change, merged_next->change, "(following change)",
+		 0, 0);
+      change = max (change, merged_next->change);
+    }
+
+  val1->next = merged_next;
+
+  val1->change = change;
+  
+  if (change > NO_CHANGE && val1->toolkit_data)
+    {
+      if (val1->free_toolkit_data)
+	free (val1->toolkit_data);
+      val1->toolkit_data = NULL;
+    }
+
+  return val1;
+}
+
+
+/* modifying the widgets */
+static Widget
+name_to_widget (widget_instance* instance, char* name)
+{
+  Widget widget = NULL;
+
+  if (!instance->widget)
+    return NULL;
+
+  if (!strcmp (XtName (instance->widget), name))
+    widget = instance->widget;
+  else
+    {
+      int length = strlen (name) + 2;
+      char* real_name = (char *) alloca (length);
+      real_name [0] = '*';
+      strcpy (real_name + 1, name);
+      
+      widget = XtNameToWidget (instance->widget, real_name);
+    }
+  return widget;
+}
+
+static void
+set_one_value (widget_instance* instance, widget_value* val, Boolean deep_p)
+{
+  Widget widget = name_to_widget (instance, val->name);
+  
+  if (widget)
+    {
+#if defined (USE_LUCID)
+      if (lw_lucid_widget_p (instance->widget))
+	xlw_update_one_widget (instance, widget, val, deep_p);
+#endif
+#if defined (USE_MOTIF)
+      if (lw_motif_widget_p (instance->widget))
+	xm_update_one_widget (instance, widget, val, deep_p);
+#endif
+#if defined (USE_OLIT)
+      if (lw_olit_widget_p (instance->widget))
+	xol_update_one_widget (instance, widget, val, deep_p);
+#endif
+    }
+}
+
+static void
+update_one_widget_instance (widget_instance* instance, Boolean deep_p)
+{
+  widget_value *val;
+
+  if (!instance->widget)
+    /* the widget was destroyed */
+    return;
+
+  for (val = instance->info->val; val; val = val->next)
+    if (val->change != NO_CHANGE)
+      set_one_value (instance, val, deep_p);
+}
+
+static void
+update_all_widget_values (widget_info* info, Boolean deep_p)
+{
+  widget_instance* instance;
+  widget_value* val;
+
+  for (instance = info->instances; instance; instance = instance->next)
+    update_one_widget_instance (instance, deep_p);
+
+  for (val = info->val; val; val = val->next)
+    val->change = NO_CHANGE;
+}
+
+void
+lw_modify_all_widgets (LWLIB_ID id, widget_value* val, Boolean deep_p)
+{
+  widget_info* info = get_widget_info (id, False);
+  widget_value* new_val;
+  widget_value* next_new_val;
+  widget_value* cur;
+  widget_value* prev;
+  widget_value* next;
+  int		found;
+
+  if (!info)
+    return;
+
+  for (new_val = val; new_val; new_val = new_val->next)
+    {
+      next_new_val = new_val->next;
+      new_val->next = NULL;
+      found = False;
+      for (prev = NULL, cur = info->val; cur; prev = cur, cur = cur->next)
+	if (!strcmp (cur->name, new_val->name))
+	  {
+	    found = True;
+	    next = cur->next;
+	    cur->next = NULL;
+	    cur = merge_widget_value (cur, new_val, deep_p ? 1000 : 1);
+	    if (prev)
+	      prev->next = cur ? cur : next;
+	    else
+	      info->val = cur ? cur : next;
+	    if (cur)
+	      cur->next = next;
+	    break;
+	  }
+      if (!found)
+	{
+	  /* Could not find it, add it */
+	  if (prev)
+	    prev->next = copy_widget_value_tree (new_val, STRUCTURAL_CHANGE);
+	  else
+	    info->val = copy_widget_value_tree (new_val, STRUCTURAL_CHANGE);
+	}
+      new_val->next = next_new_val;
+    }
+
+  update_all_widget_values (info, deep_p);
+}
+
+
+/* creating the widgets */
+
+static void
+initialize_widget_instance (widget_instance* instance)
+{
+  widget_value* val;
+
+  for (val = instance->info->val; val; val = val->next)
+    val->change = STRUCTURAL_CHANGE;
+
+  update_one_widget_instance (instance, True);
+
+  for (val = instance->info->val; val; val = val->next)
+    val->change = NO_CHANGE;
+}
+
+
+static widget_creation_function
+find_in_table (char* type, widget_creation_entry* table)
+{
+  widget_creation_entry* cur;
+  for (cur = table; cur->type; cur++)
+    if (!strcasecmp (type, cur->type))
+      return cur->function;
+  return NULL;
+}
+
+static Boolean
+dialog_spec_p (char* name)
+{
+  /* return True if name matches [EILPQeilpq][1-9][Bb] or 
+     [EILPQeilpq][1-9][Bb][Rr][1-9] */
+  if (!name)
+    return False;
+  
+  switch (name [0])
+    {
+    case 'E': case 'I': case 'L': case 'P': case 'Q':
+    case 'e': case 'i': case 'l': case 'p': case 'q':
+      if (name [1] >= '0' && name [1] <= '9')
+	{
+	  if (name [2] != 'B' && name [2] != 'b')
+	    return False;
+	  if (!name [3])
+	    return True;
+	  if ((name [3] == 'T' || name [3] == 't') && !name [4])
+	    return True;
+	  if ((name [3] == 'R' || name [3] == 'r')
+	      && name [4] >= '0' && name [4] <= '9' && !name [5])
+	    return True;
+	  return False;
+	}
+      else
+	return False;
+    
+    default:
+      return False;
+    }
+}
+
+static void
+instanciate_widget_instance (widget_instance* instance)
+{
+  widget_creation_function function = NULL;
+
+#if defined (USE_LUCID)
+  if (!function)
+    function = find_in_table (instance->info->type, xlw_creation_table);
+#endif
+#if defined(USE_MOTIF)
+  if (!function)
+    function = find_in_table (instance->info->type, xm_creation_table);
+#endif
+#if defined (USE_OLIT)
+  if (!function)
+    function = find_in_table (instance->info->type, xol_creation_table);
+#endif
+
+  if (!function)
+    {
+      if (dialog_spec_p (instance->info->type))
+	{
+#if defined (USE_LUCID)
+	  /* not yet */
+#endif
+#if defined(USE_MOTIF)
+	  if (!function)
+	    function = xm_create_dialog;
+#endif
+#if defined (USE_OLIT)
+	  /* not yet */
+#endif
+	}
+    }
+  
+  if (!function)
+    {
+      printf ("No creation function for widget type %s\n",
+	      instance->info->type);
+      abort ();
+    }
+
+  instance->widget = (*function) (instance);
+
+  if (!instance->widget)
+    abort ();
+
+  /*   XtRealizeWidget (instance->widget);*/
+}
+
+void 
+lw_register_widget (char* type, char* name, LWLIB_ID id, widget_value* val,
+		    lw_callback pre_activate_cb, lw_callback selection_cb,
+		    lw_callback post_activate_cb)
+{
+  if (!get_widget_info (id, False))
+    allocate_widget_info (type, name, id, val, pre_activate_cb, selection_cb,
+			  post_activate_cb);
+}
+
+Widget
+lw_get_widget (LWLIB_ID id, Widget parent, Boolean pop_up_p)
+{
+  widget_instance* instance;
+  
+  instance = find_instance (id, parent, pop_up_p);
+  return instance ? instance->widget : NULL;
+}
+
+Widget
+lw_make_widget (LWLIB_ID id, Widget parent, Boolean pop_up_p)
+{
+  widget_instance* instance;
+  widget_info* info;
+  
+  instance = find_instance (id, parent, pop_up_p);
+  if (!instance)
+    {
+      info = get_widget_info (id, False);
+      if (!info)
+	return NULL;
+      instance = allocate_widget_instance (info, parent, pop_up_p);
+      initialize_widget_instance (instance);
+    }
+  if (!instance->widget)
+    abort ();
+  return instance->widget;
+}
+
+Widget
+lw_create_widget (char* type, char* name, LWLIB_ID id, widget_value* val,
+		  Widget parent, Boolean pop_up_p, lw_callback pre_activate_cb,
+		  lw_callback selection_cb, lw_callback post_activate_cb)
+{
+  lw_register_widget (type, name, id, val, pre_activate_cb, selection_cb,
+		      post_activate_cb);
+  return lw_make_widget (id, parent, pop_up_p);
+}
+		  
+
+/* destroying the widgets */
+static void
+destroy_one_instance (widget_instance* instance)
+{
+  /* Remove the destroy callback on the widget; that callback will try to
+     dereference the instance object (to set its widget slot to 0, since the
+     widget is dead.)  Since the instance is now dead, we don't have to worry
+     about the fact that its widget is dead too.
+
+     This happens in the Phase2Destroy of the widget, so this callback would
+     not have been run until arbitrarily long after the instance was freed.
+   */
+  if (instance->widget)
+    XtRemoveCallback (instance->widget, XtNdestroyCallback,
+		      mark_widget_destroyed, (XtPointer)instance);
+
+  if (instance->widget)
+    {
+      /* The else are pretty tricky here, including the empty statement
+	 at the end because it would be very bad to destroy a widget
+	 twice. */
+#if defined (USE_LUCID)
+      if (lw_lucid_widget_p (instance->widget))
+	xlw_destroy_instance (instance);
+      else
+#endif
+#if defined (USE_MOTIF)
+      if (lw_motif_widget_p (instance->widget))
+	xm_destroy_instance (instance);
+      else
+#endif
+#if defined (USE_OLIT)
+      if (lw_olit_widget_p (instance->widget))
+	xol_destroy_instance (instance);
+      else
+#endif
+	/* do not remove the empty statement */
+	;
+    }
+
+  free_widget_instance (instance);
+}
+
+void
+lw_destroy_widget (Widget w)
+{
+  widget_instance* instance = get_widget_instance (w, True);
+  
+  if (instance)
+    {
+      widget_info *info = instance->info;
+      /* instance has already been removed from the list; free it */
+      destroy_one_instance (instance);
+      /* if there are no instances left, free the info too */
+      if (!info->instances)
+	lw_destroy_all_widgets (info->id);
+    }
+}
+
+void
+lw_destroy_all_widgets (LWLIB_ID id)
+{
+  widget_info* info = get_widget_info (id, True);
+  widget_instance* instance;
+  widget_instance* next;
+
+  if (info)
+    {
+      for (instance = info->instances; instance; )
+	{
+	  next = instance->next;
+	  destroy_one_instance (instance);
+	  instance = next;
+	}
+      free_widget_info (info);
+    }
+}
+
+void
+lw_destroy_everything ()
+{
+  while (all_widget_info)
+    lw_destroy_all_widgets (all_widget_info->id);
+}
+
+void
+lw_destroy_all_pop_ups ()
+{
+  widget_info* info;
+  widget_info* next;
+  widget_instance* instance;
+
+  for (info = all_widget_info; info; info = next)
+    {
+      next = info->next;
+      instance = info->instances;
+      if (instance && instance->pop_up_p)
+	lw_destroy_all_widgets (info->id);
+    }
+}
+
+#ifdef USE_MOTIF
+extern Widget first_child (Widget);	/* garbage */
+#endif
+
+Widget
+lw_raise_all_pop_up_widgets ()
+{
+  widget_info* info;
+  widget_instance* instance;
+  Widget result = NULL;
+
+  for (info = all_widget_info; info; info = info->next)
+    for (instance = info->instances; instance; instance = instance->next)
+      if (instance->pop_up_p)
+	{
+	  Widget widget = instance->widget;
+	  if (widget)
+	    {
+	      if (XtIsManaged (widget)
+#ifdef USE_MOTIF
+		  /* What a complete load of crap!!!!
+		     When a dialogShell is on the screen, it is not managed!
+		   */
+		  || (lw_motif_widget_p (instance->widget) &&
+		      XtIsManaged (first_child (widget)))
+#endif
+		  )
+		{
+		  if (!result)
+		    result = widget;
+		  XMapRaised (XtDisplay (widget), XtWindow (widget));
+		}
+	    }
+	}
+  return result;
+}
+
+static void
+lw_pop_all_widgets (LWLIB_ID id, Boolean up)
+{
+  widget_info* info = get_widget_info (id, False);
+  widget_instance* instance;
+
+  if (info)
+    for (instance = info->instances; instance; instance = instance->next)
+      if (instance->pop_up_p && instance->widget)
+	{
+	  if (!XtIsRealized (instance->widget))
+	    XtRealizeWidget (instance->widget);
+#if defined (USE_LUCID)
+	  if (lw_lucid_widget_p (instance->widget))
+	    xlw_pop_instance (instance, up);
+#endif
+#if defined (USE_MOTIF)
+	  if (lw_motif_widget_p (instance->widget))
+	    xm_pop_instance (instance, up);
+#endif
+#if defined (USE_OLIT)
+	  if (lw_olit_widget_p (instance->widget))
+	    xol_pop_instance (instance, up);
+#endif
+	}
+}
+
+void
+lw_pop_up_all_widgets (LWLIB_ID id)
+{
+  lw_pop_all_widgets (id, True);
+}
+
+void
+lw_pop_down_all_widgets (LWLIB_ID id)
+{
+  lw_pop_all_widgets (id, False);
+}
+
+void
+lw_popup_menu (Widget widget)
+{
+#if defined (USE_LUCID)
+  if (lw_lucid_widget_p (widget))
+    xlw_popup_menu (widget);
+#endif
+#if defined (USE_MOTIF)
+  if (lw_motif_widget_p (widget))
+    xm_popup_menu (widget);
+#endif
+#if defined (USE_OLIT)
+  if (lw_olit_widget_p (widget))
+    xol_popup_menu (widget);
+#endif
+}
+
+/* get the values back */
+static Boolean
+get_one_value (widget_instance* instance, widget_value* val)
+{
+  Widget widget = name_to_widget (instance, val->name);
+      
+  if (widget)
+    {
+#if defined (USE_LUCID)
+      if (lw_lucid_widget_p (instance->widget))
+	xlw_update_one_value (instance, widget, val);
+#endif
+#if defined (USE_MOTIF)
+      if (lw_motif_widget_p (instance->widget))
+	xm_update_one_value (instance, widget, val);
+#endif
+#if defined (USE_OLIT)
+      if (lw_olit_widget_p (instance->widget))
+	xol_update_one_value (instance, widget, val);
+#endif
+      return True;
+    }
+  else
+    return False;
+}
+
+Boolean
+lw_get_some_values (LWLIB_ID id, widget_value* val_out)
+{
+  widget_info* info = get_widget_info (id, False);
+  widget_instance* instance;
+  widget_value* val;
+  Boolean result = False;
+
+  if (!info)
+    return False;
+
+  instance = info->instances;
+  if (!instance)
+    return False;
+
+  for (val = val_out; val; val = val->next)
+    if (get_one_value (instance, val))
+      result = True;
+
+  return result;
+}
+
+widget_value*
+lw_get_all_values (LWLIB_ID id)
+{
+  widget_info* info = get_widget_info (id, False);
+  widget_value* val = info->val;
+  if (lw_get_some_values (id, val))
+    return val;
+  else
+    return NULL;
+}
+
+/* internal function used by the library dependent implementation to get the
+   widget_value for a given widget in an instance */
+widget_value*
+lw_get_widget_value_for_widget (widget_instance* instance, Widget w)
+{
+  char* name = XtName (w);
+  widget_value* cur;
+  for (cur = instance->info->val; cur; cur = cur->next)
+    if (!strcmp (cur->name, name))
+      return cur;
+  return NULL;
+}
+
+/* update other instances value when one thing changed */
+/* This function can be used as a an XtCallback for the widgets that get 
+  modified to update other instances of the widgets.  Closure should be the
+  widget_instance. */
+void
+lw_internal_update_other_instances (Widget widget, XtPointer closure,
+				    XtPointer call_data)
+{
+  /* To forbid recursive calls */
+  static Boolean updating;
+  
+  widget_instance* instance = (widget_instance*)closure;
+  char* name = XtName (widget);
+  widget_info* info;
+  widget_instance* cur;
+  widget_value* val;
+
+  /* never recurse as this could cause infinite recursions. */
+  if (updating)
+    return;
+
+  /* protect against the widget being destroyed */
+  if (XtWidgetBeingDestroyedP (widget))
+    return;
+
+  /* Return immediately if there are no other instances */
+  info = instance->info;
+  if (!info->instances->next)
+    return;
+
+  updating = True;
+
+  for (val = info->val; val && strcmp (val->name, name); val = val->next);
+
+  if (val && get_one_value (instance, val))
+    for (cur = info->instances; cur; cur = cur->next)
+      if (cur != instance)
+	set_one_value (cur, val, True);
+
+  updating = False;
+}
+
+
+/* get the id */
+
+LWLIB_ID
+lw_get_widget_id (Widget w)
+{
+  widget_instance* instance = get_widget_instance (w, False);
+
+  return instance ? instance->info->id : 0;
+}
+
+/* set the keyboard focus */
+void
+lw_set_keyboard_focus (Widget parent, Widget w)
+{
+#if defined (USE_MOTIF)
+  xm_set_keyboard_focus (parent, w);
+#else
+  XtSetKeyboardFocus (parent, w);
+#endif
+}
+
+/* Show busy */
+static void
+show_one_widget_busy (Widget w, Boolean flag)
+{
+  Pixel foreground = 0;
+  Pixel background = 1;
+  Widget widget_to_invert = XtNameToWidget (w, "*sheet");
+  if (!widget_to_invert)
+    widget_to_invert = w;
+  
+  XtVaGetValues (widget_to_invert,
+		 XtNforeground, &foreground,
+		 XtNbackground, &background,
+		 0);
+  XtVaSetValues (widget_to_invert,
+		 XtNforeground, background,
+		 XtNbackground, foreground,
+		 0);
+}
+
+void
+lw_show_busy (Widget w, Boolean busy)
+{
+  widget_instance* instance = get_widget_instance (w, False);
+  widget_info* info;
+  widget_instance* next;
+
+  if (instance)
+    {
+      info = instance->info;
+      if (info->busy != busy)
+	{
+	  for (next = info->instances; next; next = next->next)
+	    if (next->widget)
+	      show_one_widget_busy (next->widget, busy);
+	  info->busy = busy;
+	}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwlib/lwlib.h	Tue Jan 18 23:47:41 1994 +0000
@@ -0,0 +1,103 @@
+#ifndef LWLIB_H
+#define LWLIB_H
+
+#include <X11/Intrinsic.h>
+
+/*
+** Widget values depend on the Widget type:
+** 
+** widget:   (name value key enabled data contents/selected)
+**
+** label:    ("name" "string" NULL NULL NULL NULL)
+** button:   ("name" "string" "key" T/F data <default-button-p>)
+** button w/menu: 
+**           ("name" "string" "key" T/F data (label|button|button w/menu...))
+** menubar:  ("name" NULL NULL T/F data (button w/menu))
+** selectable thing:
+**           ("name" "string" "key" T/F data T/F)
+** checkbox: selectable thing
+** radio:    ("name" NULL NULL T/F data (selectable thing...))
+** strings:  ("name" NULL NULL T/F data (selectable thing...))
+** text:     ("name" "string" <ign> T/F data)
+*/
+
+typedef unsigned long LWLIB_ID;
+
+typedef enum _change_type
+{
+  NO_CHANGE = 0,
+  INVISIBLE_CHANGE = 1,
+  VISIBLE_CHANGE = 2,
+  STRUCTURAL_CHANGE = 3
+} change_type;
+
+typedef struct _widget_value
+{
+  /* name of widget */
+  char*		name;
+  /* value (meaning depend on widget type) */
+  char*		value;
+  /* keyboard equivalent. no implications for XtTranslations */ 
+  char*		key;
+  /* true if enabled */
+  Boolean	enabled;
+  /* true if selected */
+  Boolean	selected;
+  /* true if was edited (maintained by get_value) */
+  Boolean	edited;
+  /* true if has changed (maintained by lw library) */
+  change_type	change;
+  /* Contents of the sub-widgets, also selected slot for checkbox */
+  struct _widget_value*	contents;
+  /* data passed to callback */
+  XtPointer	call_data;
+  /* next one in the list */
+  struct _widget_value*	next;
+  /* slot for the toolkit dependent part.  Always initialize to NULL. */
+  void* toolkit_data;
+  /* tell us if we should free the toolkit data slot when freeing the
+     widget_value itself. */
+  Boolean free_toolkit_data;
+
+  /* we resource the widget_value structures; this points to the next
+     one on the free list if this one has been deallocated.
+   */
+  struct _widget_value *free_list;
+} widget_value;
+
+
+typedef void (*lw_callback) (Widget w, LWLIB_ID id, void* data);
+
+void  lw_register_widget (char* type, char* name, LWLIB_ID id,
+			  widget_value* val, lw_callback pre_activate_cb,
+			  lw_callback selection_cb,
+			  lw_callback post_activate_cb);
+Widget lw_get_widget (LWLIB_ID id, Widget parent, Boolean pop_up_p);
+Widget lw_make_widget (LWLIB_ID id, Widget parent, Boolean pop_up_p);
+Widget lw_create_widget (char* type, char* name, LWLIB_ID id,
+			 widget_value* val, Widget parent, Boolean pop_up_p,
+			 lw_callback pre_activate_cb,
+			 lw_callback selection_cb,
+			 lw_callback post_activate_cb);
+LWLIB_ID lw_get_widget_id (Widget w);
+void lw_modify_all_widgets (LWLIB_ID id, widget_value* val, Boolean deep_p);
+void lw_destroy_widget (Widget w);
+void lw_destroy_all_widgets (LWLIB_ID id);
+void lw_destroy_everything (void);
+void lw_destroy_all_pop_ups (void);
+Widget lw_raise_all_pop_up_widgets (void);
+widget_value* lw_get_all_values (LWLIB_ID id);
+Boolean lw_get_some_values (LWLIB_ID id, widget_value* val);
+void lw_pop_up_all_widgets (LWLIB_ID id);
+void lw_pop_down_all_widgets (LWLIB_ID id);
+widget_value *malloc_widget_value ();
+void free_widget_value (widget_value *);
+void lw_popup_menu (Widget);
+
+/* Toolkit independent way of focusing on a Widget at the Xt level. */
+void lw_set_keyboard_focus (Widget parent, Widget w);
+
+/* Silly Energize hack to invert the "sheet" button */
+void lw_show_busy (Widget w, Boolean busy);
+
+#endif /* LWLIB_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwlib/xlwmenu.c	Tue Jan 18 23:47:41 1994 +0000
@@ -0,0 +1,1265 @@
+/* Implements a lightweight menubar widget.  
+   Copyright (C) 1992 Lucid, Inc.
+
+This file is part of the Lucid Widget Library.
+
+The Lucid Widget Library is free software; you can redistribute it and/or 
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+The Lucid Widget Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of 
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Created by devin@lucid.com */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <sys/types.h>
+#include <X11/Xos.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/cursorfont.h>
+#include <X11/bitmaps/gray>
+#include "xlwmenuP.h"
+#include <string.h>
+
+static char 
+xlwMenuTranslations [] = 
+"<BtnDown>:	start()\n\
+<BtnMotion>:	drag()\n\
+<BtnUp>:	select()\n\
+";
+
+#define offset(field) XtOffset(XlwMenuWidget, field)
+static XtResource 
+xlwMenuResources[] =
+{ 
+  {XtNfont,  XtCFont, XtRFontStruct, sizeof(XFontStruct *),
+     offset(menu.font),XtRString, "XtDefaultFont"},
+  {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
+     offset(menu.foreground), XtRString, "XtDefaultForeground"},
+  {XtNbuttonForeground, XtCButtonForeground, XtRPixel, sizeof(Pixel),
+     offset(menu.button_foreground), XtRString, "XtDefaultForeground"},
+  {XtNmargin, XtCMargin, XtRDimension,  sizeof(Dimension),
+     offset(menu.margin), XtRImmediate, (XtPointer)0},
+  {XtNhorizontalSpacing, XtCMargin, XtRDimension,  sizeof(Dimension),
+     offset(menu.horizontal_spacing), XtRImmediate, (XtPointer)3},
+  {XtNverticalSpacing, XtCMargin, XtRDimension,  sizeof(Dimension),
+     offset(menu.vertical_spacing), XtRImmediate, (XtPointer)1},
+  {XtNarrowSpacing, XtCMargin, XtRDimension,  sizeof(Dimension),
+     offset(menu.arrow_spacing), XtRImmediate, (XtPointer)10},
+
+  {XmNshadowThickness, XmCShadowThickness, XmRHorizontalDimension,
+     sizeof (Dimension), offset (menu.shadow_thickness),
+     XtRImmediate, (XtPointer) 2},
+  {XmNtopShadowColor, XmCTopShadowColor, XtRPixel, sizeof (Pixel),
+     offset (menu.top_shadow_color), XtRImmediate, (XtPointer)-1},
+  {XmNbottomShadowColor, XmCBottomShadowColor, XtRPixel, sizeof (Pixel),
+     offset (menu.bottom_shadow_color), XtRImmediate, (XtPointer)-1},
+  {XmNtopShadowPixmap, XmCTopShadowPixmap, XtRPixmap, sizeof (Pixmap),
+     offset (menu.top_shadow_pixmap), XtRImmediate, (XtPointer)None},
+  {XmNbottomShadowPixmap, XmCBottomShadowPixmap, XtRPixmap, sizeof (Pixmap),
+     offset (menu.bottom_shadow_pixmap), XtRImmediate, (XtPointer)None},
+
+  {XtNopen, XtCCallback, XtRCallback, sizeof(XtPointer), 
+     offset(menu.open), XtRCallback, (XtPointer)NULL},
+  {XtNselect, XtCCallback, XtRCallback, sizeof(XtPointer), 
+     offset(menu.select), XtRCallback, (XtPointer)NULL},
+  {XtNmenu, XtCMenu, XtRPointer, sizeof(XtPointer),
+     offset(menu.contents), XtRImmediate, (XtPointer)NULL},
+  {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
+     offset(menu.cursor_shape), XtRString, (XtPointer)"right_ptr"},
+  {XtNhorizontal, XtCHorizontal, XtRInt, sizeof(int),
+     offset(menu.horizontal), XtRImmediate, (XtPointer)True},
+};
+#undef offset
+
+static Boolean XlwMenuSetValues();
+static void XlwMenuRealize();
+static void XlwMenuRedisplay();
+static void XlwMenuResize();
+static void XlwMenuInitialize();
+static void XlwMenuRedisplay();
+static void XlwMenuDestroy();
+static void XlwMenuClassInitialize();
+static void Start();
+static void Drag();
+static void Select();
+
+static XtActionsRec 
+xlwMenuActionsList [] =
+{
+  {"start",		Start},
+  {"drag",		Drag},
+  {"select",		Select},
+};
+
+#define SuperClass ((CoreWidgetClass)&coreClassRec)
+
+XlwMenuClassRec xlwMenuClassRec =
+{
+  {  /* CoreClass fields initialization */
+    (WidgetClass) SuperClass,		/* superclass		  */	
+    "XlwMenu",				/* class_name		  */
+    sizeof(XlwMenuRec),			/* size			  */
+    XlwMenuClassInitialize,		/* class_initialize	  */
+    NULL,				/* class_part_initialize  */
+    FALSE,				/* class_inited		  */
+    XlwMenuInitialize,			/* initialize		  */
+    NULL,				/* initialize_hook	  */
+    XlwMenuRealize,			/* realize		  */
+    xlwMenuActionsList,			/* actions		  */
+    XtNumber(xlwMenuActionsList),	/* num_actions		  */
+    xlwMenuResources,			/* resources		  */
+    XtNumber(xlwMenuResources),		/* resource_count	  */
+    NULLQUARK,				/* xrm_class		  */
+    TRUE,				/* compress_motion	  */
+    TRUE,				/* compress_exposure	  */
+    TRUE,				/* compress_enterleave    */
+    FALSE,				/* visible_interest	  */
+    XlwMenuDestroy,			/* destroy		  */
+    XlwMenuResize,			/* resize		  */
+    XlwMenuRedisplay,			/* expose		  */
+    XlwMenuSetValues,			/* set_values		  */
+    NULL,				/* set_values_hook	  */
+    XtInheritSetValuesAlmost,		/* set_values_almost	  */
+    NULL,				/* get_values_hook	  */
+    NULL,				/* accept_focus		  */
+    XtVersion,				/* version		  */
+    NULL,				/* callback_private	  */
+    xlwMenuTranslations,		/* tm_table		  */
+    XtInheritQueryGeometry,		/* query_geometry	  */
+    XtInheritDisplayAccelerator,	/* display_accelerator	  */
+    NULL				/* extension		  */
+  },  /* XlwMenuClass fields initialization */
+  {
+    0					/* dummy */
+  },
+};
+
+WidgetClass xlwMenuWidgetClass = (WidgetClass) &xlwMenuClassRec;
+
+/* Utilities */
+static void
+push_new_stack (XlwMenuWidget mw, widget_value* val)
+{
+  if (!mw->menu.new_stack)
+    {
+      mw->menu.new_stack_length = 10;
+      mw->menu.new_stack =
+	(widget_value**)XtCalloc (mw->menu.new_stack_length,
+				  sizeof (widget_value*));
+    }
+  else if (mw->menu.new_depth == mw->menu.new_stack_length)
+    {
+      mw->menu.new_stack_length *= 2;
+      mw->menu.new_stack =
+	(widget_value**)XtRealloc ((char*)mw->menu.new_stack,
+				   mw->menu.new_stack_length * sizeof (widget_value*));
+    }
+  mw->menu.new_stack [mw->menu.new_depth++] = val;
+}
+
+static void
+pop_new_stack_if_no_contents (XlwMenuWidget mw)
+{
+  if (mw->menu.new_depth)
+    {
+      if (!mw->menu.new_stack [mw->menu.new_depth - 1]->contents)
+	mw->menu.new_depth -= 1;
+    }
+}
+
+static void
+make_old_stack_space (XlwMenuWidget mw, int n)
+{
+  if (!mw->menu.old_stack)
+    {
+      mw->menu.old_stack_length = 10;
+      mw->menu.old_stack =
+	(widget_value**)XtCalloc (mw->menu.old_stack_length,
+				  sizeof (widget_value*));
+    }
+  else if (mw->menu.old_stack_length < n)
+    {
+      mw->menu.old_stack_length *= 2;
+      mw->menu.old_stack =
+	(widget_value**)XtRealloc ((char*)mw->menu.old_stack,
+				   mw->menu.old_stack_length * sizeof (widget_value*));
+    }
+}
+
+/* Size code */
+static Boolean
+all_dashes_p (char* s)
+{
+  char* p;
+  for (p = s; *p == '-'; p++);
+  return !*p;
+}
+
+static int
+string_width (XlwMenuWidget mw, char* s)
+{
+  XCharStruct xcs;
+  int drop;
+  
+  XTextExtents (mw->menu.font, s, strlen (s), &drop, &drop, &drop, &xcs);
+  return xcs.width;
+}
+
+static int
+arrow_width (XlwMenuWidget mw)
+{
+  return mw->menu.font->ascent / 2 | 1;
+}
+
+static XtResource
+nameResource[] =
+{ 
+  {"labelString",  "LabelString", XtRString, sizeof(String),
+     0, XtRImmediate, 0},
+};
+
+static char*
+resource_widget_value (XlwMenuWidget mw, widget_value* val)
+{
+  if (!val->toolkit_data)
+    {
+      char* resourced_name = NULL;
+      char* complete_name;
+      XtGetSubresources ((Widget) mw,
+			 (XtPointer) &resourced_name,
+			 val->name, val->name,
+			 nameResource, 1, NULL, 0);
+      if (!resourced_name)
+	resourced_name = val->name;
+      if (!val->value)
+	complete_name = (char *) strdup (resourced_name);
+      else
+	{
+	  int complete_length =
+	    strlen (resourced_name) + strlen (val->value) + 2;
+	  complete_name = XtMalloc (complete_length);
+	  *complete_name = 0;
+	  strcat (complete_name, resourced_name);
+	  strcat (complete_name, " ");
+	  strcat (complete_name, val->value);
+	}
+
+      val->toolkit_data = complete_name;
+      val->free_toolkit_data = True;
+    }
+  return (char*)val->toolkit_data;
+}
+
+/* Returns the sizes of an item */
+static void
+size_menu_item (XlwMenuWidget mw, widget_value* val, int horizontal_p,
+		int* label_width, int* rest_width, int* height)
+{
+  if (all_dashes_p (val->name))
+    {
+      *height = 2;
+      *label_width = 1;
+      *rest_width = 0;
+    }
+  else
+    {
+      *height =
+	mw->menu.font->ascent + mw->menu.font->descent
+	  + 2 * mw->menu.vertical_spacing + 2 * mw->menu.shadow_thickness;
+      
+      *label_width =
+	string_width (mw, resource_widget_value (mw, val))
+	  + mw->menu.horizontal_spacing + mw->menu.shadow_thickness;
+      
+      *rest_width =  mw->menu.horizontal_spacing + mw->menu.shadow_thickness;
+      if (!horizontal_p)
+	{
+	  if (val->contents)
+	    *rest_width += arrow_width (mw) + mw->menu.arrow_spacing;
+	  else if (val->key)
+	    *rest_width +=
+	      string_width (mw, val->key) + mw->menu.arrow_spacing;
+	}
+    }
+}
+
+static void
+size_menu (XlwMenuWidget mw, int level)
+{
+  int		label_width = 0;
+  int		rest_width = 0;
+  int		max_rest_width = 0;
+  int		height = 0;
+  int		horizontal_p = mw->menu.horizontal && (level == 0);
+  widget_value*	val;
+  window_state*	ws;
+
+  if (level >= mw->menu.old_depth)
+    abort ();
+
+  ws = &mw->menu.windows [level];  
+  ws->width = 0;
+  ws->height = 0;
+  ws->label_width = 0;
+
+  for (val = mw->menu.old_stack [level]->contents; val; val = val->next)
+    {
+      size_menu_item (mw, val, horizontal_p, &label_width, &rest_width,
+		      &height);
+      if (horizontal_p)
+	{
+	  ws->width += label_width + rest_width;
+	  if (height > ws->height)
+	    ws->height = height;
+	}
+      else
+	{
+	  if (label_width > ws->label_width)
+	    ws->label_width = label_width;
+	  if (rest_width > max_rest_width)
+	    max_rest_width = rest_width;
+	  ws->height += height;
+	}
+    }
+  
+  if (horizontal_p)
+    ws->label_width = 0;
+  else
+    ws->width = ws->label_width + max_rest_width;
+
+  ws->width += 2 * mw->menu.shadow_thickness;
+  ws->height += 2 * mw->menu.shadow_thickness;
+}
+
+
+/* Display code */
+static void
+draw_arrow (XlwMenuWidget mw, Window window, GC gc, int x, int y, int width)
+{
+  XPoint points [3];
+  points [0].x = x;
+  points [0].y = y + mw->menu.font->ascent;
+  points [1].x = x;
+  points [1].y = y;
+  points [2].x = x + width;
+  points [2].y = y + mw->menu.font->ascent / 2;
+  
+  XFillPolygon (XtDisplay (mw), window, gc, points, 3, Convex,
+		CoordModeOrigin);
+}
+
+static void
+draw_shadow_rectangle (XlwMenuWidget mw, Window window,
+		      int x, int y, int width, int height, int erase_p)
+{
+  Display *dpy = XtDisplay (mw);
+  GC top_gc = !erase_p ? mw->menu.shadow_top_gc : mw->menu.background_gc;
+  GC bottom_gc = !erase_p ? mw->menu.shadow_bottom_gc : mw->menu.background_gc;
+  int thickness = mw->menu.shadow_thickness;
+  XPoint points [4];
+  points [0].x = x;
+  points [0].y = y;
+  points [1].x = x + width;
+  points [1].y = y;
+  points [2].x = x + width - thickness;
+  points [2].y = y + thickness;
+  points [3].x = x;
+  points [3].y = y + thickness;
+  XFillPolygon (dpy, window, top_gc, points, 4, Convex, CoordModeOrigin);
+  points [0].x = x;
+  points [0].y = y + thickness;
+  points [1].x = x;
+  points [1].y = y + height;
+  points [2].x = x + thickness;
+  points [2].y = y + height - thickness;
+  points [3].x = x + thickness;
+  points [3].y = y + thickness;
+  XFillPolygon (dpy, window, top_gc, points, 4, Convex, CoordModeOrigin);
+  points [0].x = x + width;
+  points [0].y = y;
+  points [1].x = x + width - thickness;
+  points [1].y = y + thickness;
+  points [2].x = x + width - thickness;
+  points [2].y = y + height - thickness;
+  points [3].x = x + width;
+  points [3].y = y + height - thickness;
+  XFillPolygon (dpy, window, bottom_gc, points, 4, Convex, CoordModeOrigin);
+  points [0].x = x;
+  points [0].y = y + height;
+  points [1].x = x + width;
+  points [1].y = y + height;
+  points [2].x = x + width;
+  points [2].y = y + height - thickness;
+  points [3].x = x + thickness;
+  points [3].y = y + height - thickness;
+  XFillPolygon (dpy, window, bottom_gc, points, 4, Convex, CoordModeOrigin);
+}
+
+
+/* Display the menu item and increment where.x and where.y to show how large
+** the menu item was. 
+*/
+static void
+display_menu_item (XlwMenuWidget mw, widget_value* val, window_state* ws,
+		   XPoint* where, Boolean highlighted_p, Boolean horizontal_p,
+		   Boolean just_compute_p)
+{
+  GC deco_gc;
+  GC text_gc;
+  int font_ascent = mw->menu.font->ascent;
+  int font_descent = mw->menu.font->descent;
+  int shadow = mw->menu.shadow_thickness;
+  int separator_p = all_dashes_p (val->name);
+  int h_spacing = mw->menu.horizontal_spacing;
+  int v_spacing = mw->menu.vertical_spacing;
+  int label_width;
+  int rest_width;
+  int height;
+  int width;
+  int button_p;
+
+  /* compute the sizes of the item */
+  size_menu_item (mw, val, horizontal_p, &label_width, &rest_width, &height);
+
+  if (horizontal_p)
+    width = label_width + rest_width;
+  else
+    {
+      label_width = ws->label_width;
+      width = ws->width - 2 * shadow;
+    }
+
+  /* see if it should be a button in the menubar */
+  button_p = horizontal_p && val->call_data;
+
+  /* Only highlight an enabled item that has a callback. */
+  if (highlighted_p)
+    if (!val->enabled || !(val->call_data || val->contents))
+      highlighted_p = 0;
+
+  /* do the drawing. */
+  if (!just_compute_p)
+    {
+      /* Add the shadow border of the containing menu */
+      int x = where->x + shadow;
+      int y = where->y + shadow;
+
+      /* pick the foreground and background GC. */
+      if (val->enabled)
+	text_gc = button_p ? mw->menu.button_gc : mw->menu.foreground_gc;
+      else
+	text_gc =
+	  button_p ? mw->menu.inactive_button_gc : mw->menu.inactive_gc;
+      deco_gc = mw->menu.foreground_gc;
+
+      if (separator_p)
+	{
+	  XDrawLine (XtDisplay (mw), ws->window, mw->menu.shadow_bottom_gc,
+		     x, y, x + width, y);
+	  XDrawLine (XtDisplay (mw), ws->window, mw->menu.shadow_top_gc,
+		     x, y + 1, x + width, y + 1);
+	}
+      else 
+	{
+	  char* display_string = resource_widget_value (mw, val);
+	  draw_shadow_rectangle (mw, ws->window, x, y, width, height, True);
+	  XDrawString (XtDisplay (mw), ws->window, text_gc,
+		       x + h_spacing + shadow,
+		       y + v_spacing + shadow + font_ascent,
+		       display_string, strlen (display_string));
+	  
+	  if (!horizontal_p)
+	    {
+	      if (val->contents)
+		{
+		  int a_w = arrow_width (mw);
+		  draw_arrow (mw, ws->window, deco_gc,
+			      x + label_width + mw->menu.arrow_spacing,
+			      y + v_spacing + shadow, a_w);
+		}
+	      else if (val->key)
+		{
+		  XDrawString (XtDisplay (mw), ws->window, text_gc,
+			       x + label_width + mw->menu.arrow_spacing,
+			       y + v_spacing + shadow + font_ascent,
+			       val->key, strlen (val->key));
+		}
+	    }
+
+	  else if (button_p)
+	    {
+#if 1
+	      XDrawRectangle (XtDisplay (mw), ws->window, deco_gc,
+			      x + shadow, y + shadow,
+			      label_width + h_spacing - 1,
+			      font_ascent + font_descent + 2 * v_spacing - 1);
+#else
+	      highlighted_p = True;
+#endif
+	    }
+
+	  if (highlighted_p)
+	    draw_shadow_rectangle (mw, ws->window, x, y, width, height, False);
+	}
+    }
+  
+  where->x += width;
+  where->y += height;
+}
+
+static void
+display_menu (XlwMenuWidget mw, int level, Boolean just_compute_p,
+	      XPoint* highlighted_pos, XPoint* hit, widget_value** hit_return,
+	      widget_value* this, widget_value* that)
+{
+  widget_value*	val;
+  widget_value* following_item;
+  window_state* ws;
+  XPoint	where;
+  int horizontal_p = mw->menu.horizontal && (level == 0);
+  int highlighted_p;
+  int just_compute_this_one_p;
+
+  if (level >= mw->menu.old_depth)
+    abort ();
+
+  if (level < mw->menu.old_depth - 1)
+    following_item = mw->menu.old_stack [level + 1];
+  else 
+    following_item = NULL;
+
+  if (hit)
+    *hit_return = NULL;
+
+  where.x = 0;
+  where.y = 0;
+
+  ws = &mw->menu.windows [level];
+  for (val = mw->menu.old_stack [level]->contents; val; val = val->next)
+    {
+      highlighted_p = val == following_item;
+      if (highlighted_p && highlighted_pos)
+	{
+	  if (horizontal_p)
+	    highlighted_pos->x = where.x;
+	  else
+	    highlighted_pos->y = where.y;
+	}
+      
+      just_compute_this_one_p =
+	just_compute_p || ((this || that) && val != this &&  val != that);
+
+      display_menu_item (mw, val, ws, &where, highlighted_p, horizontal_p,
+			 just_compute_this_one_p);
+
+      if (highlighted_p && highlighted_pos)
+	{
+	  if (horizontal_p)
+	    highlighted_pos->y = where.y;
+	  else
+	    highlighted_pos->x = where.x;
+	}
+
+      if (hit
+	  && !*hit_return
+	  && (horizontal_p ? hit->x < where.x : hit->y < where.y)
+	  && !all_dashes_p (val->name))
+	*hit_return = val;
+
+      if (horizontal_p)
+	where.y = 0;
+      else
+	where.x = 0;
+    }
+  
+  if (!just_compute_p)
+    draw_shadow_rectangle (mw, ws->window, 0, 0, ws->width, ws->height, False);
+}
+
+/* Motion code */
+static void
+set_new_state (XlwMenuWidget mw, widget_value* val, int level)
+{
+  int i;
+  
+  mw->menu.new_depth = 0;
+  for (i = 0; i < level; i++)
+    push_new_stack (mw, mw->menu.old_stack [i]);
+  push_new_stack (mw, val);
+}
+
+static void
+make_windows_if_needed (XlwMenuWidget mw, int n)
+{
+  int i;
+  int start_at;
+  XSetWindowAttributes xswa;
+  int mask;
+  Window root = RootWindowOfScreen (DefaultScreenOfDisplay (XtDisplay (mw)));
+  window_state* windows;
+  
+  if (mw->menu.windows_length >= n)
+    return;
+
+  xswa.save_under = True;
+  xswa.override_redirect = True;
+  xswa.background_pixel = mw->core.background_pixel;
+  xswa.border_pixel = mw->core.border_pixel;
+  xswa.event_mask =
+    ExposureMask | ButtonMotionMask | PointerMotionHintMask
+      | ButtonReleaseMask | ButtonPressMask;
+  xswa.cursor = mw->menu.cursor_shape;
+  mask = CWSaveUnder | CWOverrideRedirect | CWBackPixel | CWBorderPixel
+    | CWEventMask | CWCursor;
+  
+  if (!mw->menu.windows)
+    {
+      mw->menu.windows =
+	(window_state*)XtMalloc (n * sizeof (window_state));
+      start_at = 0;
+    }
+  else
+    {
+      mw->menu.windows =
+	(window_state*)XtRealloc ((char*)mw->menu.windows,
+				  n * sizeof (window_state));
+      start_at = mw->menu.windows_length;
+    }
+  mw->menu.windows_length = n;
+
+  windows = mw->menu.windows;
+
+  for (i = start_at; i < n; i++)
+   {
+     windows [i].x = 0;
+     windows [i].y = 0;
+     windows [i].width = 1;
+     windows [i].height = 1;
+     windows [i].window =
+       XCreateWindow (XtDisplay (mw), root, 0, 0, 1, 1,
+		      0, 0, CopyFromParent, CopyFromParent, mask, &xswa);
+  }
+}
+
+/* Make the window fit in the screen */
+static void
+fit_to_screen (XlwMenuWidget mw, window_state* ws, window_state* previous_ws,
+	       Boolean horizontal_p)
+{
+  int screen_width = WidthOfScreen (XtScreen (mw));
+  int screen_height = HeightOfScreen (XtScreen (mw));
+
+  if (ws->x < 0)
+    ws->x = 0;
+  else if (ws->x + ws->width > screen_width)
+    {
+      if (!horizontal_p)
+	ws->x = previous_ws->x - ws->width;
+      else
+	ws->x = screen_width - ws->width;
+    }
+  if (ws->y < 0)
+    ws->y = 0;
+  else if (ws->y + ws->height > screen_height)
+    {
+      if (horizontal_p)
+	ws->y = previous_ws->y - ws->height;
+      else
+	ws->y = screen_height - ws->height;
+    }
+}
+
+/* Updates old_stack from new_stack and redisplays. */
+static void
+remap_menubar (XlwMenuWidget mw)
+{
+  int i;
+  int last_same;
+  XPoint selection_position;
+  int old_depth = mw->menu.old_depth;
+  int new_depth = mw->menu.new_depth;
+  widget_value** old_stack;
+  widget_value** new_stack;
+  window_state* windows;
+  widget_value* old_selection;
+  widget_value* new_selection;
+
+  /* Check that enough windows and old_stack are ready. */
+  make_windows_if_needed (mw, new_depth);
+  make_old_stack_space (mw, new_depth);
+  windows = mw->menu.windows;
+  old_stack = mw->menu.old_stack;
+  new_stack = mw->menu.new_stack;
+
+  /* compute the last identical different entry */
+  for (i = 1; i < old_depth && i < new_depth; i++)
+    if (old_stack [i] != new_stack [i])
+      break;
+  last_same = i - 1;
+
+  /* Memorize the previously selected item to be able to refresh it */
+  old_selection = last_same + 1 < old_depth ? old_stack [last_same + 1] : NULL;
+  if (old_selection && !old_selection->enabled)
+    old_selection = NULL;
+  new_selection = last_same + 1 < new_depth ? new_stack [last_same + 1] : NULL;
+  if (new_selection && !new_selection->enabled)
+    new_selection = NULL;
+
+  /* updates old_state from new_state.  It has to be done now because
+     display_menu (called below) uses the old_stack to know what to display. */
+  for (i = last_same + 1; i < new_depth; i++)
+    old_stack [i] = new_stack [i];
+  mw->menu.old_depth = new_depth;
+
+  /* refresh the last seletion */
+  selection_position.x = 0;
+  selection_position.y = 0;
+  display_menu (mw, last_same, new_selection == old_selection,
+		&selection_position, NULL, NULL, old_selection, new_selection);
+
+  /* Now popup the new menus */
+  for (i = last_same + 1; i < new_depth && new_stack [i]->contents; i++)
+    {
+      window_state* previous_ws = &windows [i - 1];
+      window_state* ws = &windows [i];
+
+      ws->x =
+	previous_ws->x + selection_position.x + mw->menu.shadow_thickness;
+      if (!mw->menu.horizontal || i > 1)
+	ws->x += mw->menu.shadow_thickness;
+      ws->y =
+	previous_ws->y + selection_position.y + mw->menu.shadow_thickness;
+
+      size_menu (mw, i);
+
+      fit_to_screen (mw, ws, previous_ws, mw->menu.horizontal && i == 1);
+
+      XClearWindow (XtDisplay (mw), ws->window);
+      XMoveResizeWindow (XtDisplay (mw), ws->window, ws->x, ws->y,
+			 ws->width, ws->height);
+      XMapRaised (XtDisplay (mw), ws->window);
+      display_menu (mw, i, False, &selection_position, NULL, NULL, NULL, NULL);
+    }
+
+  /* unmap the menus that popped down */
+  for (i = new_depth - 1; i < old_depth; i++)
+    if (i >= new_depth || !new_stack [i]->contents)
+      XUnmapWindow (XtDisplay (mw), windows [i].window);
+}
+
+static Boolean
+motion_event_is_in_menu (XlwMenuWidget mw, XMotionEvent* ev, int level,
+			 XPoint* relative_pos)
+{
+  window_state* ws = &mw->menu.windows [level];
+  int x = level == 0 ? ws->x : ws->x + mw->menu.shadow_thickness;
+  int y = level == 0 ? ws->y : ws->y + mw->menu.shadow_thickness;
+  relative_pos->x = ev->x_root - x;
+  relative_pos->y = ev->y_root - y;
+  return (x < ev->x_root && ev->x_root < x + ws->width
+	  && y < ev->y_root && ev->y_root < y + ws->height);
+}
+
+static Boolean
+map_event_to_widget_value (XlwMenuWidget mw, XMotionEvent* ev,
+			   widget_value** val, int* level)
+{
+  int 		i;
+  XPoint	relative_pos;
+  window_state*	ws;
+
+  *val = NULL;
+  
+  /* Find the window */
+  for (i = mw->menu.old_depth - 1; i >= 0; i--)
+    {
+      ws = &mw->menu.windows [i];
+      if (ws && motion_event_is_in_menu (mw, ev, i, &relative_pos))
+	{
+	  display_menu (mw, i, True, NULL, &relative_pos, val, NULL, NULL);
+
+	  if (*val)
+	    {
+	      *level = i + 1;
+	      return True;
+	    }
+	}
+    }
+  return False;
+}
+
+/* Procedures */
+static void
+make_drawing_gcs (XlwMenuWidget mw)
+{
+  XGCValues xgcv;
+
+  xgcv.font = mw->menu.font->fid;
+  xgcv.foreground = mw->menu.foreground;
+  xgcv.background = mw->core.background_pixel;
+  mw->menu.foreground_gc = XtGetGC ((Widget)mw,
+				    GCFont | GCForeground | GCBackground,
+				    &xgcv);
+  
+  xgcv.font = mw->menu.font->fid;
+  xgcv.foreground = mw->menu.button_foreground;
+  xgcv.background = mw->core.background_pixel;
+  mw->menu.button_gc = XtGetGC ((Widget)mw,
+				GCFont | GCForeground | GCBackground,
+				&xgcv);
+  
+  xgcv.font = mw->menu.font->fid;
+  xgcv.foreground = mw->menu.foreground;
+  xgcv.background = mw->core.background_pixel;
+  xgcv.fill_style = FillStippled;
+  xgcv.stipple = mw->menu.gray_pixmap;
+  mw->menu.inactive_gc = XtGetGC ((Widget)mw,
+				  (GCFont | GCForeground | GCBackground
+				   | GCFillStyle | GCStipple), &xgcv);
+  
+  xgcv.font = mw->menu.font->fid;
+  xgcv.foreground = mw->menu.button_foreground;
+  xgcv.background = mw->core.background_pixel;
+  xgcv.fill_style = FillStippled;
+  xgcv.stipple = mw->menu.gray_pixmap;
+  mw->menu.inactive_button_gc = XtGetGC ((Widget)mw,
+				  (GCFont | GCForeground | GCBackground
+				   | GCFillStyle | GCStipple), &xgcv);
+  
+  xgcv.font = mw->menu.font->fid;
+  xgcv.foreground = mw->core.background_pixel;
+  xgcv.background = mw->menu.foreground;
+  mw->menu.background_gc = XtGetGC ((Widget)mw,
+				    GCFont | GCForeground | GCBackground,
+				    &xgcv);
+}
+
+static void
+release_drawing_gcs (XlwMenuWidget mw)
+{
+  XtReleaseGC ((Widget) mw, mw->menu.foreground_gc);
+  XtReleaseGC ((Widget) mw, mw->menu.button_gc);
+  XtReleaseGC ((Widget) mw, mw->menu.inactive_gc);
+  XtReleaseGC ((Widget) mw, mw->menu.inactive_button_gc);
+  XtReleaseGC ((Widget) mw, mw->menu.background_gc);
+  /* let's get some segvs if we try to use these... */
+  mw->menu.foreground_gc = (GC) -1;
+  mw->menu.button_gc = (GC) -1;
+  mw->menu.inactive_gc = (GC) -1;
+  mw->menu.inactive_button_gc = (GC) -1;
+  mw->menu.background_gc = (GC) -1;
+}
+
+#define MINL(x,y) ((((unsigned long) (x)) < ((unsigned long) (y))) \
+		   ? ((unsigned long) (x)) : ((unsigned long) (y)))
+
+static void
+make_shadow_gcs (XlwMenuWidget mw)
+{
+  XGCValues xgcv;
+  unsigned long pm = 0;
+  Display *dpy = XtDisplay ((Widget) mw);
+  Colormap cmap = DefaultColormapOfScreen (XtScreen ((Widget) mw));
+  XColor topc, botc;
+  int top_frobbed = 0, bottom_frobbed = 0;
+
+  if (mw->menu.top_shadow_color == -1)
+    mw->menu.top_shadow_color = mw->core.background_pixel;
+  if (mw->menu.bottom_shadow_color == -1)
+    mw->menu.bottom_shadow_color = mw->menu.foreground;
+
+  if (mw->menu.top_shadow_color == mw->core.background_pixel ||
+      mw->menu.top_shadow_color == mw->menu.foreground)
+    {
+      topc.pixel = mw->core.background_pixel;
+      XQueryColor (dpy, cmap, &topc);
+      /* don't overflow/wrap! */
+      topc.red   = MINL (65535, topc.red   * 1.2);
+      topc.green = MINL (65535, topc.green * 1.2);
+      topc.blue  = MINL (65535, topc.blue  * 1.2);
+      if (XAllocColor (dpy, cmap, &topc))
+	{
+	  mw->menu.top_shadow_color = topc.pixel;
+	  top_frobbed = 1;
+	}
+    }
+  if (mw->menu.bottom_shadow_color == mw->menu.foreground ||
+      mw->menu.bottom_shadow_color == mw->core.background_pixel)
+    {
+      botc.pixel = mw->core.background_pixel;
+      XQueryColor (dpy, cmap, &botc);
+      botc.red   *= 0.6;
+      botc.green *= 0.6;
+      botc.blue  *= 0.6;
+      if (XAllocColor (dpy, cmap, &botc))
+	{
+	  mw->menu.bottom_shadow_color = botc.pixel;
+	  bottom_frobbed = 1;
+	}
+    }
+
+  if (top_frobbed && bottom_frobbed)
+    {
+      int top_avg = ((topc.red / 3) + (topc.green / 3) + (topc.blue / 3));
+      int bot_avg = ((botc.red / 3) + (botc.green / 3) + (botc.blue / 3));
+      if (bot_avg > top_avg)
+	{
+	  Pixel tmp = mw->menu.top_shadow_color;
+	  mw->menu.top_shadow_color = mw->menu.bottom_shadow_color;
+	  mw->menu.bottom_shadow_color = tmp;
+	}
+      else if (topc.pixel == botc.pixel)
+	{
+	  if (botc.pixel == mw->menu.foreground)
+	    mw->menu.top_shadow_color = mw->core.background_pixel;
+	  else
+	    mw->menu.bottom_shadow_color = mw->menu.foreground;
+	}
+    }
+
+  if (!mw->menu.top_shadow_pixmap &&
+      mw->menu.top_shadow_color == mw->core.background_pixel)
+    {
+      mw->menu.top_shadow_pixmap = mw->menu.gray_pixmap;
+      mw->menu.top_shadow_color = mw->menu.foreground;
+    }
+  if (!mw->menu.bottom_shadow_pixmap &&
+      mw->menu.bottom_shadow_color == mw->core.background_pixel)
+    {
+      mw->menu.bottom_shadow_pixmap = mw->menu.gray_pixmap;
+      mw->menu.bottom_shadow_color = mw->menu.foreground;
+    }
+
+  xgcv.fill_style = FillStippled;
+  xgcv.foreground = mw->menu.top_shadow_color;
+  xgcv.stipple = mw->menu.top_shadow_pixmap;
+  pm = (xgcv.stipple ? GCStipple|GCFillStyle : 0);
+  mw->menu.shadow_top_gc = XtGetGC ((Widget)mw, GCForeground | pm, &xgcv);
+
+  xgcv.foreground = mw->menu.bottom_shadow_color;
+  xgcv.stipple = mw->menu.bottom_shadow_pixmap;
+  pm = (xgcv.stipple ? GCStipple|GCFillStyle : 0);
+  mw->menu.shadow_bottom_gc = XtGetGC ((Widget)mw, GCForeground | pm, &xgcv);
+}
+
+
+static void
+release_shadow_gcs (XlwMenuWidget mw)
+{
+  XtReleaseGC ((Widget) mw, mw->menu.shadow_top_gc);
+  XtReleaseGC ((Widget) mw, mw->menu.shadow_bottom_gc);
+}
+
+static void
+XlwMenuInitialize (Widget request, Widget new, ArgList args,
+		   Cardinal *num_args)
+{
+  /* Get the GCs and the widget size */
+  XlwMenuWidget mw = (XlwMenuWidget)new;
+  
+  XSetWindowAttributes xswa;
+  int mask;
+  
+  Window window = RootWindowOfScreen (DefaultScreenOfDisplay (XtDisplay (mw)));
+  Display* display = XtDisplay (mw);
+  
+/*  mw->menu.cursor = XCreateFontCursor (display, mw->menu.cursor_shape); */
+  mw->menu.cursor = mw->menu.cursor_shape;
+  
+  mw->menu.gray_pixmap = XCreatePixmapFromBitmapData (display, window,
+						      gray_bits, gray_width,
+						      gray_height, 1, 0, 1);
+  
+  make_drawing_gcs (mw);
+  make_shadow_gcs (mw);
+  
+  xswa.background_pixel = mw->core.background_pixel;
+  xswa.border_pixel = mw->core.border_pixel;
+  mask = CWBackPixel | CWBorderPixel;
+  
+  mw->menu.popped_up = False;
+  
+  mw->menu.old_depth = 1;
+  mw->menu.old_stack = (widget_value**)XtMalloc (sizeof (widget_value*));
+  mw->menu.old_stack_length = 1;
+  mw->menu.old_stack [0] = mw->menu.contents;
+  
+  mw->menu.new_depth = 0;
+  mw->menu.new_stack = 0;
+  mw->menu.new_stack_length = 0;
+  push_new_stack (mw, mw->menu.contents);
+  
+  mw->menu.windows = (window_state*)XtMalloc (sizeof (window_state));
+  mw->menu.windows_length = 1;
+  mw->menu.windows [0].x = 0;
+  mw->menu.windows [0].y = 0;
+  mw->menu.windows [0].width = 0;
+  mw->menu.windows [0].height = 0;
+  size_menu (mw, 0);
+  
+  mw->core.width = mw->menu.windows [0].width;
+  mw->core.height = mw->menu.windows [0].height;
+}
+
+static void
+XlwMenuClassInitialize ()
+{
+}
+
+static void
+XlwMenuRealize (Widget w, Mask *valueMask, XSetWindowAttributes *attributes)
+{
+  XlwMenuWidget mw = (XlwMenuWidget)w;
+  XSetWindowAttributes xswa;
+  int mask;
+
+  (*xlwMenuWidgetClass->core_class.superclass->core_class.realize)
+    (w, valueMask, attributes);
+
+  xswa.save_under = True;
+  xswa.cursor = mw->menu.cursor_shape;
+  mask = CWSaveUnder | CWCursor;
+  XChangeWindowAttributes (XtDisplay (w), XtWindow (w), mask, &xswa);
+
+  mw->menu.windows [0].window = XtWindow (w);
+  mw->menu.windows [0].x = w->core.x;
+  mw->menu.windows [0].y = w->core.y;
+  mw->menu.windows [0].width = w->core.width;
+  mw->menu.windows [0].height = w->core.height;
+}
+
+/* Only the toplevel menubar/popup is a widget so it's the only one that
+   receives expose events through Xt.  So we repaint all the other panes
+   when receiving an Expose event. */
+static void 
+XlwMenuRedisplay (Widget w, XEvent* ev, Region region)
+{
+  XlwMenuWidget mw = (XlwMenuWidget)w;
+  int i;
+
+  for (i = 0; i < mw->menu.old_depth; i++)
+    display_menu (mw, i, False, NULL, NULL, NULL, NULL, NULL);
+}
+
+static void 
+XlwMenuDestroy (Widget w)
+{
+  int i;
+  XlwMenuWidget mw = (XlwMenuWidget) w;
+
+  release_drawing_gcs (mw);
+  release_shadow_gcs (mw);
+
+  /* this doesn't come from the resource db but is created explicitly
+     so we must free it ourselves. */
+  XFreePixmap (XtDisplay (mw), mw->menu.gray_pixmap);
+  mw->menu.gray_pixmap = (Pixmap) -1;
+
+  /* Don't free mw->menu.contents because that comes from our creator.
+     The `*_stack' elements are just pointers into `contents' so leave
+     that alone too.  But free the stacks themselves. */
+  if (mw->menu.old_stack) XtFree ((char *) mw->menu.old_stack);
+  if (mw->menu.new_stack) XtFree ((char *) mw->menu.new_stack);
+
+  /* Remember, you can't free anything that came from the resource
+     database.  This includes:
+         mw->menu.cursor
+         mw->menu.top_shadow_pixmap
+         mw->menu.bottom_shadow_pixmap
+         mw->menu.font
+     Also the color cells of top_shadow_color, bottom_shadow_color,
+     foreground, and button_foreground will never be freed until this
+     client exits.  Nice, eh?
+   */
+
+  /* start from 1 because the one in slot 0 is w->core.window */
+  for (i = 1; i < mw->menu.windows_length; i++)
+    XDestroyWindow (XtDisplay (mw), mw->menu.windows [i].window);
+  if (mw->menu.windows)
+    XtFree ((char *) mw->menu.windows);
+}
+
+static Boolean 
+XlwMenuSetValues (Widget current, Widget request, Widget new)
+{
+  XlwMenuWidget oldmw = (XlwMenuWidget)current;
+  XlwMenuWidget newmw = (XlwMenuWidget)new;
+  Boolean redisplay = False;
+  int i;
+
+  if (newmw->menu.contents
+      && newmw->menu.contents->contents
+      && newmw->menu.contents->contents->change >= VISIBLE_CHANGE)
+    redisplay = True;
+
+  if (newmw->core.background_pixel != oldmw->core.background_pixel
+      || newmw->menu.foreground != oldmw->menu.foreground)
+    {
+      release_drawing_gcs (newmw);
+      make_drawing_gcs (newmw);
+      redisplay = True;
+      
+      for (i = 0; i < oldmw->menu.windows_length; i++)
+	{
+	  XSetWindowBackground (XtDisplay (oldmw),
+				oldmw->menu.windows [i].window,
+				newmw->core.background_pixel);
+	  /* clear windows and generate expose events */
+	  XClearArea (XtDisplay (oldmw), oldmw->menu.windows[i].window,
+		      0, 0, 0, 0, True);
+	}
+    }
+
+  return redisplay;
+}
+
+static void 
+XlwMenuResize (Widget w)
+{
+  XlwMenuWidget mw = (XlwMenuWidget)w;
+
+  mw->menu.windows [0].width = mw->core.width;
+  mw->menu.windows [0].height = mw->core.height;
+}
+
+/* Action procedures */
+static void
+handle_single_motion_event (XlwMenuWidget mw, XMotionEvent* ev)
+{
+  widget_value*	val;
+  int 		level;
+
+  if (!map_event_to_widget_value (mw, ev, &val, &level))
+    pop_new_stack_if_no_contents (mw);
+  else
+    set_new_state (mw, val, level);
+  remap_menubar (mw);
+  
+  /* Sync with the display.  Makes it feel better on X terms. */
+  XSync (XtDisplay (mw), False);
+}
+
+static void
+handle_motion_event (XlwMenuWidget mw, XMotionEvent* ev)
+{
+  int x = ev->x_root;
+  int y = ev->y_root;
+  int state = ev->state;
+
+  handle_single_motion_event (mw, ev);
+
+  /* allow motion events to be generated again */
+  if (ev->is_hint
+      && XQueryPointer (XtDisplay (mw), ev->window,
+			&ev->root, &ev->subwindow,
+			&ev->x_root, &ev->y_root,
+			&ev->x, &ev->y,
+			&ev->state)
+      && ev->state == state
+      && (ev->x_root != x || ev->y_root != y))
+    handle_single_motion_event (mw, ev);
+}
+
+static void 
+Start (Widget w, XEvent *ev, String *params, Cardinal *num_params)
+{
+  XlwMenuWidget mw = (XlwMenuWidget)w;
+
+  XtCallCallbackList ((Widget)mw, mw->menu.open, NULL);
+  
+  /* notes the absolute position of the menubar window */
+  mw->menu.windows [0].x = ev->xmotion.x_root - ev->xmotion.x;
+  mw->menu.windows [0].y = ev->xmotion.y_root - ev->xmotion.y;
+
+  /* handles the down like a move, slots are compatible */
+  handle_motion_event (mw, &ev->xmotion);
+}
+
+static void 
+Drag (Widget w, XEvent *ev, String *params, Cardinal *num_params)
+{
+  XlwMenuWidget mw = (XlwMenuWidget)w;
+  handle_motion_event (mw, &ev->xmotion);
+}
+
+static void 
+Select (Widget w, XEvent *ev, String *params, Cardinal *num_params)
+{
+  XlwMenuWidget mw = (XlwMenuWidget)w;
+  widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1];
+  
+  /* pop down everything */
+  mw->menu.new_depth = 1;
+  remap_menubar (mw);
+
+  if (mw->menu.popped_up)
+    {
+      mw->menu.popped_up = False;
+      XtUngrabPointer ((Widget)mw, ev->xmotion.time);
+      XtPopdown (XtParent (mw));
+    }
+
+  /* callback */
+  XtCallCallbackList ((Widget)mw, mw->menu.select, (XtPointer)selected_item);
+  
+}
+
+
+/* Special code to pop-up a menu */
+void
+pop_up_menu (XlwMenuWidget mw, XButtonPressedEvent* event)
+{
+  int		x = event->x_root;
+  int		y = event->y_root;
+  int		w;
+  int		h;
+  int		borderwidth = mw->menu.shadow_thickness;
+  Screen*	screen = XtScreen (mw);
+
+  XtCallCallbackList ((Widget)mw, mw->menu.open, NULL);
+
+  size_menu (mw, 0);
+
+  w = mw->menu.windows [0].width;
+  h = mw->menu.windows [0].height;
+
+  x -= borderwidth;
+  y -= borderwidth;
+  if (x < borderwidth)
+    x = borderwidth;
+  if (x + w + 2 * borderwidth > WidthOfScreen (screen))
+    x = WidthOfScreen (screen) - w - 2 * borderwidth;
+  if (y < borderwidth)
+    y = borderwidth;
+  if (y + h + 2 * borderwidth> HeightOfScreen (screen))
+    y = HeightOfScreen (screen) - h - 2 * borderwidth;
+
+  mw->menu.popped_up = True;
+  XtConfigureWidget (XtParent (mw), x, y, w, h,
+		     XtParent (mw)->core.border_width);
+  XtPopup (XtParent (mw), XtGrabExclusive);
+  display_menu (mw, 0, False, NULL, NULL, NULL, NULL, NULL);
+  XtGrabPointer ((Widget)mw, False,
+		 (ButtonMotionMask | PointerMotionHintMask | ButtonReleaseMask
+		  | ButtonPressMask),
+		 GrabModeAsync, GrabModeAsync, None, mw->menu.cursor_shape,
+		 event->time);
+
+  mw->menu.windows [0].x = x + borderwidth;
+  mw->menu.windows [0].y = y + borderwidth;
+
+  handle_motion_event (mw, (XMotionEvent*)event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwlib/xlwmenu.h	Tue Jan 18 23:47:41 1994 +0000
@@ -0,0 +1,50 @@
+#ifndef _XlwMenu_h
+#define _XlwMenu_h
+
+/***********************************************************************
+ *
+ * XlwMenu Widget
+ *
+ ***********************************************************************/
+
+#include "lwlib.h"
+
+/* Resource names used by the XlwMenu widget */
+#define XtNbuttonForeground "buttonForeground"
+#define XtCButtonForeground "ButtonForeground"
+#define XtNmargin "margin"
+#define XtNhorizontalSpacing "horizontalSpacing"
+#define XtNverticalSpacing "verticalSpacing"
+#define XtNarrowSpacing "arrowSpacing"
+#define XtNmenu "menu"
+#define XtCMenu "Menu"
+#define XtNopen "open"
+#define XtNselect "select"
+#define XtNmenuBorderWidth "menuBorderWidth"
+#define XtNhorizontal "horizontal"
+#define XtCHorizontal "Horizontal"
+#define XtNcursor "cursor"
+#define XtNCursor "Cursor"
+
+/* Motif-compatible resource names */
+#define XmNshadowThickness	"shadowThickness"
+#define XmCShadowThickness	"ShadowThickness"
+#define XmNtopShadowColor	"topShadowColor"
+#define XmCTopShadowColor	"TopShadowColor"
+#define XmNbottomShadowColor	"bottomShadowColor"
+#define XmCBottomShadowColor	"BottomShadowColor"
+#define XmNtopShadowPixmap	"topShadowPixmap"
+#define XmCTopShadowPixmap	"TopShadowPixmap"
+#define XmNbottomShadowPixmap	"bottomShadowPixmap"
+#define XmCBottomShadowPixmap	"BottomShadowPixmap"
+#define XmRHorizontalDimension	"HorizontalDimension"
+
+typedef struct _XlwMenuRec *XlwMenuWidget;
+typedef struct _XlwMenuClassRec *XlwMenuWidgetClass;
+
+extern WidgetClass xlwMenuWidgetClass;
+
+void
+pop_up_menu (XlwMenuWidget mw, XButtonPressedEvent* event);
+
+#endif /* _XlwMenu_h */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/widget.c	Tue Jan 18 23:47:41 1994 +0000
@@ -0,0 +1,900 @@
+/* The emacs frame widget.
+   Copyright (C) 1992, 1993 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Emacs 19 face widget ported by Fred Pierresteguy */
+
+#include <stdio.h>
+#include "config.h"
+#include "lisp.h"
+#include "xterm.h"
+
+#include "frame.h"
+
+#include "dispextern.h"
+
+
+#include <X11/StringDefs.h>
+#include <X11/IntrinsicP.h>
+#include <X11/cursorfont.h>
+#include "widgetprv.h"
+#include <X11/Shell.h>
+#include <X11/ShellP.h>
+
+#define max(a, b) ((a) > (b) ? (a) : (b))
+
+/* This sucks: this is the first default that x-faces.el tries.  This won't
+   be used unless neither the "Emacs.EmacsFrame" resource nor the
+   "Emacs.EmacsFrame" resource is set; the frame
+   may have the wrong default size if this font doesn't exist, but some other
+   font that x-faces.el does.  The workaround is to specify some font in the
+   resource database; I don't know a solution other than duplicating the font-
+   searching code from x-faces.el in this file.
+
+   This also means that if "Emacs.EmacsFrame" is specified as a non-
+   existent font, then Xt is going to substitute "XtDefaultFont" for it,
+   which is a different size than this one.  The solution for this is to
+   make x-faces.el try to use XtDefaultFont.  The problem with that is that
+   XtDefaultFont is almost certainly variable-width.
+
+   #### Perhaps we could have this code explicitly set XtDefaultFont to this?
+ */
+#define DEFAULT_FACE_FONT "-*-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-*"
+
+
+static void EmacsFrameInitialize (Widget, Widget, ArgList, Cardinal *);
+static void EmacsFrameDestroy (Widget);
+static void EmacsFrameRealize (Widget, XtValueMask*, XSetWindowAttributes*);
+void EmacsFrameResize (Widget widget);
+static Boolean EmacsFrameSetValues (Widget, Widget, Widget,
+				     ArgList, Cardinal *);
+static XtGeometryResult EmacsFrameQueryGeometry (Widget, XtWidgetGeometry*,
+						  XtWidgetGeometry*);
+
+
+#undef XtOffset
+#define XtOffset(p_type,field) \
+	((Cardinal) (((char *) (&(((p_type)0)->field))) - ((char *)0)))
+#define offset(field) XtOffset(EmacsFrame, emacs_frame.field)
+
+static XtResource resources[] = {
+  {XtNgeometry, XtCGeometry, XtRString, sizeof(String),
+     offset (geometry), XtRString, (XtPointer) 0},
+  {XtNiconic, XtCIconic, XtRBoolean, sizeof(Boolean),
+     offset (iconic), XtRImmediate, (XtPointer) False},
+
+  {XtNemacsFrame, XtCEmacsFrame, XtRPointer, sizeof (XtPointer),
+     offset (frame), XtRImmediate, 0},
+
+  {XtNminibuffer, XtCMinibuffer, XtRInt, sizeof (int),
+     offset (minibuffer), XtRImmediate, (XtPointer)0},
+  {XtNunsplittable, XtCUnsplittable, XtRBoolean, sizeof (Boolean),
+     offset (unsplittable), XtRImmediate, (XtPointer)0},
+  {XtNinternalBorderWidth, XtCInternalBorderWidth, XtRInt, sizeof (int),
+     offset (internal_border_width), XtRImmediate, (XtPointer)4},
+  {XtNinterline, XtCInterline, XtRInt, sizeof (int),
+     offset (interline), XtRImmediate, (XtPointer)0},
+  {XtNfont,  XtCFont, XtRFontStruct, sizeof(XFontStruct *),
+     offset(font),XtRString, DEFAULT_FACE_FONT},
+  {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
+     offset(foreground_pixel), XtRString, "XtDefaultForeground"},
+  {XtNcursorColor, XtCForeground, XtRPixel, sizeof(Pixel),
+     offset(cursor_color), XtRString, "XtDefaultForeground"},
+  {XtNbarCursor, XtCBarCursor, XtRBoolean, sizeof (Boolean),
+     offset (bar_cursor), XtRImmediate, (XtPointer)0},
+  {XtNvisualBell, XtCVisualBell, XtRBoolean, sizeof (Boolean),
+     offset (visual_bell), XtRImmediate, (XtPointer)0},
+  {XtNbellVolume, XtCBellVolume, XtRInt, sizeof (int),
+     offset (bell_volume), XtRImmediate, (XtPointer)0},
+};
+
+#undef offset
+
+/*
+static XtActionsRec
+emacsFrameActionsTable [] = {
+  {"keypress",  key_press},
+  {"focus_in",  emacs_frame_focus_handler},
+  {"focus_out", emacs_frame_focus_handler},
+};
+
+static char
+emacsFrameTranslations [] = "\
+<KeyPress>: keypress()\n\
+<FocusIn>:  focus_in()\n\
+<FocusOut>: focus_out()\n\
+";
+*/
+
+EmacsFrameClassRec emacsFrameClassRec = {
+    { /* core fields */
+    /* superclass		*/	&widgetClassRec,
+    /* class_name		*/	"EmacsFrame",
+    /* widget_size		*/	sizeof(EmacsFrameRec),
+    /* class_initialize		*/	0,
+    /* class_part_initialize	*/	0,
+    /* class_inited		*/	FALSE,
+    /* initialize		*/	EmacsFrameInitialize,
+    /* initialize_hook		*/	0,
+    /* realize			*/	EmacsFrameRealize,
+    /* actions			*/	0, /*emacsFrameActionsTable*/
+    /* num_actions		*/	0, /*XtNumber (emacsFrameActionsTable)*/
+    /* resources		*/	resources,
+    /* resource_count		*/	XtNumber(resources),
+    /* xrm_class		*/	NULLQUARK,
+    /* compress_motion		*/	TRUE,
+    /* compress_exposure	*/	TRUE,
+    /* compress_enterleave	*/	TRUE,
+    /* visible_interest		*/	FALSE,
+    /* destroy			*/	EmacsFrameDestroy,
+    /* resize			*/	EmacsFrameResize,
+    /* expose			*/	XtInheritExpose,
+    /* set_values		*/	EmacsFrameSetValues,
+    /* set_values_hook		*/	0,
+    /* set_values_almost	*/	XtInheritSetValuesAlmost,
+    /* get_values_hook		*/	0,
+    /* accept_focus		*/	XtInheritAcceptFocus,
+    /* version			*/	XtVersion,
+    /* callback_private		*/	0,
+    /* tm_table			*/	0, /*emacsFrameTranslations*/
+    /* query_geometry		*/	EmacsFrameQueryGeometry,
+    /* display_accelerator	*/	XtInheritDisplayAccelerator,
+    /* extension		*/	0
+    }
+};
+
+WidgetClass emacsFrameClass = (WidgetClass) &emacsFrameClassRec;
+
+static void
+get_default_char_pixel_size (EmacsFrame ew, int* pixel_width,
+			     int* pixel_height)
+{
+/*
+  *pixel_width = XTextWidth (ew->emacs_frame.font, "n", 1);
+  *pixel_height =
+    ew->emacs_frame.font->ascent + ew->emacs_frame.font->descent;
+*/
+  struct frame* f = ew->emacs_frame.frame;
+  *pixel_width = FONT_WIDTH (f->display.x->font);
+  *pixel_height = FONT_HEIGHT (f->display.x->font);
+}
+
+static void
+pixel_to_char_size (EmacsFrame ew,
+		    Dimension pixel_width, Dimension pixel_height,
+		    int* char_width, int* char_height)
+{
+  struct frame* f = ew->emacs_frame.frame;
+  *char_width = PIXEL_TO_CHAR_WIDTH (f, pixel_width);
+  *char_height = PIXEL_TO_CHAR_HEIGHT (f, pixel_height);
+}
+
+static void
+char_to_pixel_size (EmacsFrame ew, int char_width, int char_height,
+		    Dimension* pixel_width, Dimension* pixel_height)
+{
+  struct frame* f = ew->emacs_frame.frame;
+  *pixel_width = CHAR_TO_PIXEL_WIDTH (f, char_width);
+  *pixel_height = CHAR_TO_PIXEL_HEIGHT (f, char_height);
+}
+
+static void
+round_size_to_char (EmacsFrame ew,
+		    Dimension in_width, Dimension in_height,
+		    Dimension* out_width, Dimension* out_height)
+{
+  int char_width;
+  int char_height;
+  pixel_to_char_size (ew, in_width, in_height, &char_width, &char_height);
+  char_to_pixel_size (ew, char_width, char_height, out_width, out_height);
+}
+
+static Widget
+get_wm_shell (Widget w)
+{
+  Widget wmshell;
+
+  for (wmshell = XtParent (w);
+       wmshell && !XtIsWMShell (wmshell);
+       wmshell = XtParent (wmshell));
+
+  return wmshell;
+}
+
+static void
+mark_shell_size_user_specified (Widget wmshell)
+{
+  if (! XtIsWMShell (wmshell)) abort ();
+  /* This is kind of sleazy, but I can't see how else to tell it to make it
+     mark the WM_SIZE_HINTS size as user specified when appropriate. */
+  ((WMShellWidget) wmshell)->wm.size_hints.flags |= USSize;
+}
+
+
+/* Can't have static frame locals because of some broken compilers.
+   Normally, initializing a variable like this doesn't work in emacs,
+   but it's ok in this file because it must come after lastfile (and
+   thus have its data not go into text space) because Xt needs to
+   write to initialized data objects too.
+ */
+static Boolean first_frame_p = True;
+
+static void
+set_frame_size (EmacsFrame ew)
+{
+  /* The widget hierarchy is
+
+	argv[0]			emacsShell	pane	Frame-NAME
+	ApplicationShell	EmacsShell	Paned	EmacsFrame
+
+     We accept geometry specs in this order:
+
+	*Frame-NAME.geometry
+	*EmacsFrame.geometry
+	Emacs.geometry
+
+     Other possibilities for widget hierarchies might be
+
+	argv[0]			frame		pane	Frame-NAME
+	ApplicationShell	EmacsShell	Paned	EmacsFrame
+     or
+	argv[0]			Frame-NAME	pane	Frame-NAME
+	ApplicationShell	EmacsShell	Paned	EmacsFrame
+     or
+	argv[0]			Frame-NAME	pane	emacsTextPane
+	ApplicationShell	EmacsFrame	Paned	EmacsTextPane
+
+     With the current setup, the text-display-area is the part which is
+     an emacs "frame", since that's the only part managed by emacs proper
+     (the menubar and the parent of the menubar and all that sort of thing
+     are managed by lwlib.)
+
+     The EmacsShell widget is simply a replacement for the Shell widget 
+     which is able to deal with using an externally-supplied window instead
+     of always creating its own.  It is not actually emacs specific, and
+     should possibly have class "Shell" instead of "EmacsShell" to simplify
+     the resources.
+
+   */
+
+  /* Geometry of the AppShell */
+  int app_flags = 0;
+  int app_x = 0;
+  int app_y = 0;
+  unsigned int app_w = 0;
+  unsigned int app_h = 0;
+  
+  /* Geometry of the EmacsFrame */
+  int frame_flags = 0;
+  int frame_x = 0;
+  int frame_y = 0;
+  unsigned int frame_w = 0;
+  unsigned int frame_h = 0;
+  
+  /* Hairily merged geometry */
+  int x = 0;
+  int y = 0;
+  unsigned int w = ew->emacs_frame.frame->width;
+  unsigned int h = ew->emacs_frame.frame->height;
+  int flags = 0;
+  
+  Widget wmshell = get_wm_shell ((Widget) ew);
+  Widget app_shell = XtParent ((Widget) wmshell);
+  
+  
+  if (! XtIsSubclass (wmshell, shellWidgetClass)) abort ();
+  if (! XtIsSubclass (app_shell, shellWidgetClass)) abort ();
+
+  /* If the EmacsFrame doesn't have a geometry but the shell does,
+     treat that as the geometry of the frame.  (Is this bogus?
+     I'm not sure.) */
+  if (ew->emacs_frame.geometry == 0)
+    XtVaGetValues (wmshell, XtNgeometry, &ew->emacs_frame.geometry, 0);
+
+  /* If the Shell is iconic, then the EmacsFrame is iconic.  (Is
+     this bogus? I'm not sure.) */
+  if (!ew->emacs_frame.iconic)
+    XtVaGetValues (wmshell, XtNiconic, &ew->emacs_frame.iconic, 0);
+  
+  
+  {
+    char *geom = 0;
+    XtVaGetValues (app_shell, XtNgeometry, &geom, 0);
+    if (geom)
+      app_flags = XParseGeometry (geom, &app_x, &app_y, &app_w, &app_h);
+  }
+  
+  if (ew->emacs_frame.geometry)
+    frame_flags = XParseGeometry (ew->emacs_frame.geometry,
+				   &frame_x, &frame_y,
+				   &frame_w, &frame_h);
+  
+  if (first_frame_p)
+    {
+      /* If this is the first frame created:
+         ====================================
+
+         - Use the ApplicationShell's size/position, if specified.
+           (This is "Emacs.geometry", or the "-geometry" command line arg.)
+         - Else use the EmacsFrame's size/position.
+           (This is "*Frame-NAME.geometry")
+
+	 - If the AppShell is iconic, the frame should be iconic.
+
+	 AppShell comes first so that -geometry always applies to the first
+	 frame created, even if there is an "every frame" entry in the
+	 resource database.
+       */
+      if (app_flags & (XValue | YValue))
+	{
+	  x = app_x; y = app_y;
+	  flags |= (app_flags & (XValue | YValue | XNegative | YNegative));
+	}
+      else if (frame_flags & (XValue | YValue))
+	{
+	  x = frame_x; y = frame_y;
+	  flags |= (frame_flags & (XValue | YValue | XNegative | YNegative));
+	}
+
+      if (app_flags & (WidthValue | HeightValue))
+	{
+	  w = app_w; h = app_h;
+	  flags |= (app_flags & (WidthValue | HeightValue));
+	}
+      else if (frame_flags & (WidthValue | HeightValue))
+	{
+	  w = frame_w; h = frame_h;
+	  flags |= (frame_flags & (WidthValue | HeightValue));
+	}
+
+      /* If the AppShell is iconic, then the EmacsFrame is iconic. */
+      if (!ew->emacs_frame.iconic)
+	XtVaGetValues (app_shell, XtNiconic, &ew->emacs_frame.iconic, 0);
+
+      first_frame_p = False;
+    }
+  else
+    {
+      /* If this is not the first frame created:
+         ========================================
+
+         - use the EmacsFrame's size/position if specified
+         - Otherwise, use the ApplicationShell's size, but not position.
+
+         So that means that one can specify the position of the first frame
+         with "Emacs.geometry" or `-geometry'; but can only specify the
+	 position of subsequent frames with "*Frame-NAME.geometry".
+
+	 AppShell comes second so that -geometry does not apply to subsequent
+	 frames when there is an "every frame" entry in the resource db,
+	 but does apply to the first frame.
+       */
+      if (frame_flags & (XValue | YValue))
+	{
+	  x = frame_x; y = frame_y;
+	  flags |= (frame_flags & (XValue | YValue | XNegative | YNegative));
+	}
+
+      if (frame_flags & (WidthValue | HeightValue))
+	{
+	  w = frame_w; h = frame_h;
+	  flags |= (frame_flags & (WidthValue | HeightValue));
+	}
+      else if (app_flags & (WidthValue | HeightValue))
+	{
+	  w = app_w;
+	  h = app_h;
+	  flags |= (app_flags & (WidthValue | HeightValue));
+	}
+    }
+
+  {
+    struct frame* frame = ew->emacs_frame.frame;
+    Dimension pixel_width, pixel_height;
+    char shell_position [32];
+
+    /* Take into account the size of the scrollbar */
+    frame->display.x->vertical_scroll_bar_extra
+      = (FRAME_HAS_VERTICAL_SCROLL_BARS (frame)
+	 ? VERTICAL_SCROLL_BAR_PIXEL_WIDTH (frame)
+	 : 0);
+
+
+    change_frame_size (frame, h, w, 1, 0);
+    char_to_pixel_size (ew, w, h, &pixel_width, &pixel_height);
+    ew->core.width = pixel_width;
+    ew->core.height = pixel_height;
+
+
+    /* If a position was specified, assign it to the shell widget.
+       (Else WM won't do anything with it.)
+     */
+    if (flags & (XValue | YValue))
+      {
+	/* the tricky things with the sign is to make sure that
+	   -0 is printed -0. */
+	int len;
+	char *tem;
+	sprintf (shell_position, "=%c%d%c%d",
+		 flags & XNegative ? '-' : '+', x < 0 ? -x : x,
+		 flags & YNegative ? '-' : '+', y < 0 ? -y : y);
+	len = strlen (shell_position) + 1;
+	tem = (char *) xmalloc (len);
+	strncpy (tem, shell_position, len);
+	XtVaSetValues (wmshell, XtNgeometry, tem, 0);
+      }
+    else if (flags & (WidthValue | HeightValue))
+      {
+	int len;
+	char *tem;
+	sprintf (shell_position, "=%dx%d", pixel_width, pixel_height);
+	len = strlen (shell_position) + 1;
+	tem = (char *) xmalloc (len);
+	strncpy (tem, shell_position, len);
+	XtVaSetValues (wmshell, XtNgeometry, tem, 0);
+      }
+
+    /* If the geometry spec we're using has W/H components, mark the size
+       in the WM_SIZE_HINTS as user specified. */
+    if (flags & (WidthValue | HeightValue))
+      mark_shell_size_user_specified (wmshell);
+
+    /* Also assign the iconic status of the frame to the Shell, so that
+       the WM sees it. */
+    XtVaSetValues (wmshell, XtNiconic, ew->emacs_frame.iconic, 0);
+  }
+}
+
+
+static void
+update_wm_hints (EmacsFrame ew)
+{
+  Widget wmshell = get_wm_shell ((Widget)ew);
+  int cw;
+  int ch;
+  Dimension rounded_width;
+  Dimension rounded_height;
+  int char_width;
+  int char_height;
+  int base_width;
+  int base_height;
+  int min_rows = 0, min_cols = 0;
+
+  check_frame_size (ew->emacs_frame.frame, &min_rows, &min_cols);
+
+  pixel_to_char_size (ew, ew->core.width, ew->core.height,
+		      &char_width, &char_height);
+  char_to_pixel_size (ew, char_width, char_height,
+		      &rounded_width, &rounded_height);
+  get_default_char_pixel_size (ew, &cw, &ch); 
+
+  base_width = (wmshell->core.width - ew->core.width
+		+ (rounded_width - (char_width * cw)));
+  base_height = (wmshell->core.height - ew->core.height
+		+ (rounded_height - (char_height * ch)));
+
+  /* This is kind of sleazy, but I can't see how else to tell it to
+     make it mark the WM_SIZE_HINTS size as user specified.
+   */
+/*  ((WMShellWidget) wmshell)->wm.size_hints.flags |= USSize;*/
+
+  XtVaSetValues (wmshell,
+		 XtNbaseWidth, base_width,
+		 XtNbaseHeight, base_height,
+		 XtNwidthInc, cw, 
+		 XtNheightInc, ch,
+		 XtNminWidth, base_width + min_cols * cw,
+		 XtNminHeight, base_height + min_rows * ch,
+		 0);
+}
+
+static void
+create_frame_gcs (EmacsFrame ew)
+{
+  struct frame* s = ew->emacs_frame.frame;
+
+  s->display.x->normal_gc =
+    XCreateGC (XtDisplay (ew), RootWindowOfScreen (XtScreen (ew)), 0, 0);
+  s->display.x->reverse_gc =
+    XCreateGC (XtDisplay (ew), RootWindowOfScreen (XtScreen (ew)), 0, 0);
+  s->display.x->cursor_gc =
+    XCreateGC (XtDisplay (ew), RootWindowOfScreen (XtScreen (ew)), 0, 0);
+}
+
+static void
+setup_frame_gcs (EmacsFrame ew)
+{
+  XGCValues gc_values;
+  struct frame* s = ew->emacs_frame.frame;
+  Pixmap blank_stipple, blank_tile;
+
+  static char cursor_bits[] =
+    {
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+
+  /* We have to initialize all of our GCs to have a stipple/tile, otherwise
+     XGetGCValues returns uninitialized data when we query the stipple
+     (instead of None or something sensible) and it makes things hard.
+
+     This should be fixed for real by not querying the GCs but instead having
+     some GC-based cache instead of the current face-based cache which doesn't
+     effectively cache all of the GC settings we need to use.
+   */
+
+  blank_stipple = 
+    XCreateBitmapFromData (XtDisplay (ew), RootWindowOfScreen (XtScreen (ew)),
+			   cursor_bits, 2, 2);
+
+  /* use fg = 0, bg = 1 below, but it's irrelevant since this pixmap should
+     never actually get used as a background tile!
+   */
+  blank_tile =
+    XCreatePixmapFromBitmapData (XtDisplay(ew),
+				 RootWindowOfScreen (XtScreen (ew)),
+				 cursor_bits, 2, 2, 0, 1, ew->core.depth);
+
+  /* Normal video */
+  gc_values.font = ew->emacs_frame.font->fid;
+  gc_values.foreground = ew->emacs_frame.foreground_pixel;
+  gc_values.background = ew->core.background_pixel;
+  gc_values.graphics_exposures = False;
+  gc_values.stipple = blank_stipple;
+  gc_values.tile = blank_tile;
+  XChangeGC (XtDisplay (ew), s->display.x->normal_gc,
+	     (GCFont | GCForeground | GCBackground | GCGraphicsExposures
+	      | GCStipple | GCTile),
+	     &gc_values);
+
+  /* Reverse video style. */
+  gc_values.font = ew->emacs_frame.font->fid;
+  gc_values.foreground = ew->core.background_pixel;
+  gc_values.background = ew->emacs_frame.foreground_pixel;
+  gc_values.graphics_exposures = False;
+  gc_values.stipple = blank_stipple;
+  gc_values.tile = blank_tile;
+  XChangeGC (XtDisplay (ew), s->display.x->reverse_gc,
+	     (GCFont | GCForeground | GCBackground | GCGraphicsExposures
+	      | GCStipple | GCTile),
+	     &gc_values);
+
+  /* Cursor has to have an empty stipple. */
+  gc_values.font = ew->emacs_frame.font->fid;
+  gc_values.foreground = ew->core.background_pixel;
+  gc_values.background = ew->emacs_frame.cursor_color;
+  gc_values.graphics_exposures = False;
+  gc_values.tile = blank_tile;
+  gc_values.stipple =
+    XCreateBitmapFromData (XtDisplay (ew),
+			   RootWindowOfScreen (XtScreen (ew)),
+			   cursor_bits, 16, 16);
+  XChangeGC (XtDisplay (ew), s->display.x->cursor_gc,
+	     (GCFont | GCForeground | GCBackground | GCGraphicsExposures
+	      | GCStipple | GCTile),
+	     &gc_values);
+}
+
+static void
+update_various_frame_slots (EmacsFrame ew)
+{
+  struct x_display* x = ew->emacs_frame.frame->display.x;
+  x->pixel_height = ew->core.height;
+  x->pixel_width = ew->core.width;
+  x->internal_border_width = ew->emacs_frame.internal_border_width;
+
+}
+
+static void
+update_from_various_frame_slots (EmacsFrame ew)
+{
+  struct x_display* x = ew->emacs_frame.frame->display.x;
+  ew->core.height = x->pixel_height;
+  ew->core.width = x->pixel_width;
+  ew->core.background_pixel = x->background_pixel;
+  ew->emacs_frame.internal_border_width = x->internal_border_width;
+  ew->emacs_frame.font = x->font;
+  ew->emacs_frame.foreground_pixel = x->foreground_pixel;
+  ew->emacs_frame.cursor_color = x->cursor_pixel;
+  ew->core.border_pixel = x->border_pixel;
+}
+
+static void 
+EmacsFrameInitialize (Widget request, Widget new,
+		       ArgList dum1, Cardinal *dum2)
+{
+  EmacsFrame ew = (EmacsFrame)new;
+
+  if (!ew->emacs_frame.frame)
+    {
+      fprintf (stderr,
+	       "can't create an emacs frame widget without a frame\n");
+      exit (1);
+    }
+
+#if 0 /* done in xfns.c */
+  /* If the "Emacs.EmacsFrame.{default,Face}.{attributeFont,AttributeFont}"
+     resource is set, then it always overrides "Emacs.EmacsFrame.{font,Font}".
+     It's unfortunate that we have to do this, but we need to know the font
+     size for frame-sizing purposes before the faces get initialized.  If
+     the "default.attributeFont" isn't set, then we use the font of this
+     EmacsFrame itself, defaulting to XtDefaultFont.  Up in the lisp code,
+     the "default" face will use the frame's font if its own is not set,
+     so everything stays in sync -- it's not possible for the frame's font
+     and the default face's font to be different.
+   */
+  {
+    XFontStruct *f = 0;
+    XtResource face_res;
+    face_res.resource_name = "attributeFont";
+    face_res.resource_class = "AttributeFont";
+    face_res.resource_type = XtRFontStruct;
+    face_res.resource_size = sizeof (XFontStruct *);
+    face_res.resource_offset = 0;
+    face_res.default_type = XtRImmediate;
+    face_res.default_addr = 0;
+    XtGetSubresources ((Widget) ew, (XtPointer) &f, "default", "Face",
+		       &face_res, 1, NULL, 0);
+      
+    if (f)
+	ew->emacs_frame.font = f;
+    else if (! ew->emacs_frame.font)
+      {
+	fprintf (stderr, "emacs frame widget could not load a font\n");
+	exit (1);
+      }
+  }
+
+/* Update the font field in frame */
+  ew->emacs_frame.frame->display.x->font = ew->emacs_frame.font;
+#endif
+
+  update_from_various_frame_slots (ew);
+  set_frame_size (ew); 
+/*create_frame_gcs (ew);
+  setup_frame_gcs (ew);
+  update_various_frame_slots (ew); */
+}
+
+
+static void
+EmacsFrameRealize (Widget widget, XtValueMask *mask,
+		    XSetWindowAttributes *attrs)
+{
+  EmacsFrame ew = (EmacsFrame)widget;
+
+  attrs->event_mask = (KeyPressMask | ExposureMask | ButtonPressMask |
+		       ButtonReleaseMask | StructureNotifyMask |
+		       FocusChangeMask | PointerMotionHintMask |
+		       PointerMotionMask | LeaveWindowMask | EnterWindowMask |
+		       VisibilityChangeMask | PropertyChangeMask |
+		       StructureNotifyMask | SubstructureNotifyMask |
+		       SubstructureRedirectMask);
+  *mask |= CWEventMask;
+  XtCreateWindow (widget, InputOutput, (Visual *)CopyFromParent, *mask,
+		  attrs);
+  update_wm_hints (ew); 
+}
+
+extern void free_frame_faces (struct frame *);
+
+static void
+EmacsFrameDestroy (Widget widget)
+{
+  EmacsFrame ew = (EmacsFrame) widget;
+  struct frame* s = ew->emacs_frame.frame;
+
+  if (! s) abort ();
+  if (! s->display.x) abort ();
+  if (! s->display.x->normal_gc) abort ();
+
+  /* this would be called from Fdelete_frame() but it needs to free some
+     stuff after the widget has been finalized but before the widget has
+     been freed. */
+  free_frame_faces (s);
+
+  /* need to be careful that the face-freeing code doesn't free these too */
+  XFreeGC (XtDisplay (widget), s->display.x->normal_gc);
+  XFreeGC (XtDisplay (widget), s->display.x->reverse_gc);
+  XFreeGC (XtDisplay (widget), s->display.x->cursor_gc);
+}
+
+void
+EmacsFrameResize (Widget widget)
+{
+  EmacsFrame ew = (EmacsFrame)widget;
+  struct frame *f = ew->emacs_frame.frame;
+  int columns;
+  int rows;
+
+  pixel_to_char_size (ew, ew->core.width, ew->core.height, &columns, &rows);
+  change_frame_size (f, rows, columns, 1, 0);
+  update_wm_hints (ew); 
+  {
+    Window win, child;
+    int win_x, win_y;
+
+    /* Find the position of the outside upper-left corner of
+       the window, in the root coordinate system.  Don't
+       refer to the parent window here; we may be processing
+       this event after the window manager has changed our
+       parent, but before we have reached the ReparentNotify.  */
+    XTranslateCoordinates (x_current_display,
+			   
+			   /* From-window, to-window.  */
+			   XtWindow(XtParent(ew)),
+			   ROOT_WINDOW,
+			   
+			   /* From-position, to-position.  */
+			   -f->display.x->widget->core.border_width,
+			   -f->display.x->widget->core.border_width,
+			   &win_x, &win_y,
+			   
+			   /* Child of win.  */
+			   &child);
+    f->display.x->widget->core.x = win_x;
+    f->display.x->widget->core.y = win_y;
+  }
+  update_various_frame_slots (ew);
+}
+
+static Boolean
+EmacsFrameSetValues (Widget cur_widget, Widget req_widget, Widget new_widget,
+		      ArgList dum1, Cardinal *dum2)
+{
+  EmacsFrame cur = (EmacsFrame)cur_widget;
+  EmacsFrame new = (EmacsFrame)new_widget;
+
+  Boolean needs_a_refresh = False;
+  Boolean has_to_recompute_size;
+  Boolean has_to_recompute_gcs;
+  Boolean has_to_update_hints;
+
+  int char_width, char_height;
+  Dimension pixel_width;
+  Dimension pixel_height;
+  
+  has_to_recompute_gcs = (cur->emacs_frame.font != new->emacs_frame.font
+			  || (cur->emacs_frame.foreground_pixel
+			      != new->emacs_frame.foreground_pixel)
+			  || (cur->core.background_pixel
+			      != new->core.background_pixel)
+			  );
+  
+  has_to_recompute_size = (cur->emacs_frame.font != new->emacs_frame.font
+			   && cur->core.width == new->core.width
+			   && cur->core.height == new->core.height);
+
+  has_to_update_hints = (cur->emacs_frame.font != new->emacs_frame.font);
+
+  if (has_to_recompute_gcs)
+    {
+      setup_frame_gcs (new);
+      needs_a_refresh = True;
+    }
+			  
+  if (has_to_recompute_size)
+    {
+      pixel_width = new->core.width;
+      pixel_height = new->core.height;
+      pixel_to_char_size (new, pixel_width, pixel_height, &char_width,
+			  &char_height);
+      char_to_pixel_size (new, char_width, char_height, &pixel_width,
+			  &pixel_height);
+      new->core.width = pixel_width;
+      new->core.height = pixel_height;
+
+      change_frame_size (new->emacs_frame.frame, char_height, char_width,
+			  1, 0);
+      needs_a_refresh = True;
+    }
+
+  if (has_to_update_hints)
+    update_wm_hints (new);
+
+  update_various_frame_slots (new);
+
+  /* #### This doesn't work, I haven't been able to find ANY kludge that
+     will let (x-create-frame '((iconic . t))) work.  It seems that changes
+     to wm_shell's iconic slot have no effect after it has been realized,
+     and calling XIconifyWindow doesn't work either (even thought the window
+     has been created.)  Perhaps there is some property we could smash
+     directly, but I'm sick of this for now.  Xt is a steaming pile of shit!
+   */
+  if (cur->emacs_frame.iconic != new->emacs_frame.iconic)
+    {
+      Widget wmshell = get_wm_shell ((Widget) cur);
+      XtVaSetValues (wmshell, XtNiconic, new->emacs_frame.iconic, 0);
+    }
+
+  return needs_a_refresh;
+}
+
+static XtGeometryResult
+EmacsFrameQueryGeometry (Widget widget, XtWidgetGeometry* request,
+			  XtWidgetGeometry* result)
+{
+  EmacsFrame ew = (EmacsFrame)widget;
+
+  int mask = request->request_mode;
+  Dimension ok_width, ok_height;
+
+  if (mask & (CWWidth | CWHeight))
+    {
+      round_size_to_char (ew,
+			  (mask & CWWidth) ? request->width : ew->core.width,
+			  ((mask & CWHeight) ? request->height
+			   : ew->core.height),
+			  &ok_width, &ok_height);
+      if ((mask & CWWidth) && (ok_width != request->width))
+	{
+	  result->request_mode |= CWWidth;
+	  result->width = ok_width;
+	}
+      if ((mask & CWHeight) && (ok_height != request->height))
+	{
+	  result->request_mode |= CWHeight;
+	  result->height = ok_height;
+	}
+    }
+  return result->request_mode ? XtGeometryAlmost : XtGeometryYes;
+}
+
+#if 0
+/* I don't know why this is necessary; Matthieu said he had to do
+   it to make the focus handlers work??
+ */
+static void
+key_press (Widget w, XEvent* event, String *params, Cardinal *n_params)
+{
+}
+
+static void
+emacs_frame_focus_handler (Widget w, XEvent *event, String *params,
+			    Cardinal *n_params)
+{
+  emacs_Xt_focus_event_handler (event, 0);
+}
+#endif
+
+/* Special entrypoints */
+void
+EmacsFrameSetCharSize (Widget widget, int columns, int rows)
+{
+  EmacsFrame ew = (EmacsFrame) widget;
+  Dimension pixel_width, pixel_height, granted_width, granted_height;
+  XtGeometryResult result;
+  if (columns < 3) columns = 3;  /* no way buddy */
+  if (rows < 3) rows = 3;
+
+  char_to_pixel_size (ew, columns, rows, &pixel_width, &pixel_height);
+  result = XtMakeResizeRequest ((Widget)ew,
+				pixel_width, pixel_height,
+				&granted_width, &granted_height);
+  if (result == XtGeometryAlmost)
+    XtMakeResizeRequest ((Widget) ew, granted_width, granted_height,
+			 NULL, NULL);
+  /* damn Paned widget won't ever change its width.  Force it. */
+  if (ew->core.width != pixel_width)
+    {
+      XtVaSetValues (XtParent ((Widget) ew), XtNwidth, pixel_width, 0);
+      XtVaSetValues ((Widget) ew, XtNwidth, pixel_width, 0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/widget.h	Tue Jan 18 23:47:41 1994 +0000
@@ -0,0 +1,90 @@
+/* The emacs frame widget public header file.
+   Copyright (C) 1993 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Emacs 19 face widget ported by Fred Pierresteguy */
+
+#ifndef _EmacsFrame_h
+#define _EmacsFrame_h
+
+#define XtNminibuffer "minibuffer"
+#define XtCMinibuffer "Minibuffer"
+#define XtNunsplittable "unsplittable"
+#define XtCUnsplittable "Unsplittable"
+#define XtNinternalBorderWidth "internalBorderWidth"
+#define XtCInternalBorderWidth "InternalBorderWidth"
+#define XtNinterline "interline"
+#define XtCInterline "Interline"
+
+#ifndef XtNfont
+#define XtNfont "font"
+#endif
+#ifndef XtCFont
+#define XtCFont "Font"
+#endif
+#ifndef XtNforeground
+#define XtNforeground "foreground"
+#endif
+#ifndef XtCForeground
+#define XtCForeground "Foreground"
+#endif
+
+#define XtNcursorColor "cursorColor"
+#define XtCCursorColor "CursorColor"
+#define XtNbarCursor "barCursor"
+#define XtCBarCursor "BarCursor"
+
+#define XtNvisualBell "visualBell"
+#define XtCVisualBell "VisualBell"
+#define XtCBellVolume "BellVolume"
+#define XtNbellVolume "bellVolume"
+
+#define XtNpointerBackground "pointerBackground"
+#define XtNpointerColor "pointerColor"
+
+#define XtNtextPointer "textPointer"
+#define XtNspacePointer "spacePointer"
+#define XtNmodeLinePointer "modePointer"
+#define XtNgcPointer "gcPointer"
+
+#define XtNemacsFrame "emacsFrame"
+#define XtCEmacsFrame "EmacsFrame"
+
+#ifndef XtNgeometry
+#define XtNgeometry "geometry"
+#endif
+#ifndef XtCGeometry
+#define XtCGeometry "Geometry"
+#endif
+
+#define XtNinitialGeometry "initialGeometry"
+#define XtCInitialGeometry "InitialGeometry"
+
+/* structures
+ */
+typedef struct _EmacsFrameRec *EmacsFrame;
+typedef struct _EmacsFrameClassRec *EmacsFrameClass;
+
+extern WidgetClass emacsFrameClass;
+
+extern struct _DisplayContext* display_context;
+
+/* Special entrypoints */
+void EmacsFrameSetCharSize (Widget widget, int rows, int cols);
+
+#endif /* _EmacsFrame_h */