		      Release 5 Public Patch #24
			   MIT X Consortium

To apply this patch:

cd to the top of the source tree (to the directory containing the "mit"
and "contrib" subdirectories) and do:
	patch -p -s < ThisFile
Patch will work silently unless an error occurs.
If you want to watch patch do its thing, leave out the "-s" argument to patch.


Finally, to rebuild after applying this patch, cd to the "mit" subdirectory
and do:
	make -k >& make.log


Brief notes on what this patch fixes:

Xt: XtMakeGeometryRequest can emit erroneous ConfigureWindow requests
Xt: merging databases with Xlib can invalidate Xt's cached database
Xt: ExtractLocaleName() returns NULL when locale is C
Xt: XtAppAddInput might not handle maximum open file descriptors
Xt: XtRemoveInput when multiple callbacks on same source and condition
Xt: XtGrabKeyboard and XtGrabPointer with an unrealized widget
Xt: SelectionI.h assumes sizeof(long) == 32
Xt: returns selection value allocated by Xlib
Xt: selection owners that specify a done_proc, with certain requests
Xt: internal event handler unnecessarily asks for nonmaskable events
Xt: assumes all key translators use the same standard modifiers
Xt: faulty grab registration
Xt: missing parameters in unsupported DEBUG code in TMgrab.c
Xt: action proc binding reference count overflows at 4096
Xt: parsing and matching productions containing key sequences
Xt: parsing of productions containing "None" and "Any" modifiers
Xt: parsing productions with Meta as event abbreviation
Xt: semantics of productions with "Any" should be AnyModifier
Xt: XtOverrideTranslations fails to override double click translations
Xt: VarCreate.c assumes ability to assign to a va_list type
Xt: Alloc.c: conflicting typedef when XTTRACEMEMORY #defined
Xt: nonsense about uninitialized memory by Purify in Create.c
Xt: unused structure item in timeout representation

Prereq: public-patch-23

*** /tmp/da4481	Mon May 17 18:17:06 1993
--- mit/bug-report	Mon May 17 18:17:05 1993
***************
*** 2,8 ****
  Subject: [area]: [synopsis]   [replace with actual area and short description]
  
  VERSION:
!     R5, public-patch-23
      [MIT public patches will edit this line to indicate the patch level]
  
  CLIENT MACHINE and OPERATING SYSTEM:
--- 2,8 ----
  Subject: [area]: [synopsis]   [replace with actual area and short description]
  
  VERSION:
!     R5, public-patch-24
      [MIT public patches will edit this line to indicate the patch level]
  
  CLIENT MACHINE and OPERATING SYSTEM:
*** /tmp/da4530	Mon May 17 18:19:26 1993
--- mit/lib/Xt/Alloc.c	Mon May 17 18:19:25 1993
***************
*** 1,4 ****
! /* $XConsortium: Alloc.c,v 1.46 91/07/30 11:04:41 rws Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
--- 1,4 ----
! /* $XConsortium: Alloc.c,v 1.47 92/02/21 13:11:23 converse Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
***************
*** 205,218 ****
  #undef XtCalloc
  #undef XtFree
  
! typedef struct stat {
!     struct stat *prev, *next;
      char *file;
      int line;
      unsigned size;
      unsigned long seq;
      XtPointer heap;
! } Stats, *StatsPtr;
  
  static StatsPtr XtMemory = (StatsPtr)NULL;
  static unsigned long ActiveXtMemory = 0;
--- 205,219 ----
  #undef XtCalloc
  #undef XtFree
  
! typedef struct _Stats *StatsPtr;
! typedef struct _Stats {
!     StatsPtr prev, next;
      char *file;
      int line;
      unsigned size;
      unsigned long seq;
      XtPointer heap;
! } Stats;
  
  static StatsPtr XtMemory = (StatsPtr)NULL;
  static unsigned long ActiveXtMemory = 0;
*** /tmp/da4566	Mon May 17 18:19:29 1993
--- mit/lib/Xt/Create.c	Mon May 17 18:19:28 1993
***************
*** 1,4 ****
! /* $XConsortium: Create.c,v 1.89 92/08/26 14:09:28 converse Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
--- 1,4 ----
! /* $XConsortium: Create.c,v 1.90 93/04/26 19:09:28 converse Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
***************
*** 323,328 ****
--- 323,329 ----
  	XtInitializeWidgetClass(widget_class);
      if ((widget_class->core_class.class_inited & WidgetClassFlag) == 0) {
  	/* not a widget */
+ 	default_screen = NULL;
  	if (XtIsComposite(parent)) {
  	    CompositeClassExtension ext;
  	    for (ext = (CompositeClassExtension)
*** /tmp/da4602	Mon May 17 18:19:32 1993
--- mit/lib/Xt/Geometry.c	Mon May 17 18:19:32 1993
***************
*** 1,4 ****
! /* $XConsortium: Geometry.c,v 1.55 92/02/11 17:13:18 converse Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
--- 1,4 ----
! /* $XConsortium: Geometry.c,v 1.56 93/05/13 16:04:14 kaleb Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
***************
*** 242,248 ****
  	if (changeMask & CWStackMode) {
  	    changes.stack_mode = request->stack_mode;
  	    if (changeMask & CWSibling)
! 		changes.sibling = XtWindow(request->sibling);
  	}
  
  	XConfigureWindow(XtDisplay(widget), XtWindow(widget),
--- 242,251 ----
  	if (changeMask & CWStackMode) {
  	    changes.stack_mode = request->stack_mode;
  	    if (changeMask & CWSibling)
! 		if (XtIsWidget(request->sibling))
! 		    changes.sibling = XtWindow(request->sibling);
! 		else
! 		    changeMask &= ~(CWStackMode | CWSibling);
  	}
  
  	XConfigureWindow(XtDisplay(widget), XtWindow(widget),
*** /tmp/da4638	Mon May 17 18:19:36 1993
--- mit/lib/Xt/InitialI.h	Mon May 17 18:19:35 1993
***************
*** 1,4 ****
! /* $XConsortium: InitialI.h,v 1.61 91/07/12 12:33:51 rws Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
--- 1,4 ----
! /* $XConsortium: InitialI.h,v 1.64 93/01/08 16:04:57 converse Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
***************
*** 41,46 ****
--- 41,47 ----
  #endif
  #ifndef PATH_MAX
  #include <sys/param.h>
+ #ifndef PATH_MAX
  #ifdef MAXPATHLEN
  #define PATH_MAX MAXPATHLEN
  #else
***************
*** 47,67 ****
  #define PATH_MAX 1024
  #endif
  #endif
- 
- #ifndef MAX
- #define MAX(a,b) (((a) > (b)) ? (a) : (b))
  #endif
  
- #ifndef MIN
- #define MIN(a,b) (((a) < (b)) ? (a) : (b))
- #endif
- 
  #include "fd.h"
  
  typedef struct _TimerEventRec {
          struct timeval        te_timer_value;
  	struct _TimerEventRec *te_next;
- 	Display		      *te_dpy;
  	XtTimerCallbackProc   te_proc;
  	XtAppContext	      app;
  	XtPointer	      te_closure;
--- 48,60 ----
*** /tmp/da4674	Mon May 17 18:19:39 1993
--- mit/lib/Xt/Initialize.c	Mon May 17 18:19:38 1993
***************
*** 1,4 ****
! /* $XConsortium: Initialize.c,v 1.201 92/06/08 11:15:22 converse Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
--- 1,4 ----
! /* $XConsortium: Initialize.c,v 1.203 93/03/15 15:25:28 converse Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
***************
*** 373,379 ****
      }
      pd = _XtGetPerDisplay(dpy);
      if (db = pd->per_screen_db[scrno])
! 	return db;
      scr_resources = XScreenResourceString(screen);
  
      if (ScreenCount(dpy) == 1) {
--- 373,379 ----
      }
      pd = _XtGetPerDisplay(dpy);
      if (db = pd->per_screen_db[scrno])
! 	return doing_def ? XrmGetDatabase(dpy) : db;
      scr_resources = XScreenResourceString(screen);
  
      if (ScreenCount(dpy) == 1) {
*** /tmp/da4710	Mon May 17 18:19:42 1993
--- mit/lib/Xt/Intrinsic.c	Mon May 17 18:19:42 1993
***************
*** 1,4 ****
! /* $XConsortium: Intrinsic.c,v 1.172 92/04/15 19:15:24 rws Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
--- 1,4 ----
! /* $XConsortium: Intrinsic.c,v 1.173 93/02/26 16:37:13 converse Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
***************
*** 892,903 ****
      }
  #endif	/* hpux */
  
!     /*  If result is "C", return NULL instead. */
! 
!     if (strcmp(lang, "C"))
!         return lang;
!     else
!       return NULL;
  }
  
  static void FillInLangSubs(subs, pd)
--- 892,898 ----
      }
  #endif	/* hpux */
  
!     return lang;
  }
  
  static void FillInLangSubs(subs, pd)
*** /tmp/da4746	Mon May 17 18:19:46 1993
--- mit/lib/Xt/NextEvent.c	Mon May 17 18:19:45 1993
***************
*** 1,4 ****
! /* $XConsortium: NextEvent.c,v 1.108 91/07/12 11:00:21 rws Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
--- 1,4 ----
! /* $XConsortium: NextEvent.c,v 1.110 93/02/10 15:47:39 converse Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
***************
*** 33,49 ****
  static TimerEventRec* freeTimerRecs;
  static WorkProcRec* freeWorkRecs;
  
- #undef MIN
- #undef MAX
- #ifndef OPEN_MAX
- #ifndef NOFILE
- #include <sys/param.h>
- #endif
- #ifdef NOFILE
- #define OPEN_MAX NOFILE
- #endif
- #endif
- 
  /* Some systems running NTP daemons are known to return strange usec
   * values from gettimeofday.  At present (3/90) this has only been
   * reported on SunOS...
--- 33,38 ----
***************
*** 503,517 ****
  			  "invalid condition passed to XtAppAddInput",
  			  (String *)NULL, (Cardinal *)NULL);
  
! 	if (app->input_list == NULL) {
! #ifdef OPEN_MAX
! 	    app->input_max = OPEN_MAX;
! #else
! 	    app->input_max = sysconf(_SC_OPEN_MAX);
! #endif
! 	    app->input_list = (InputEvent**)
! 	       _XtHeapAlloc(&app->heap,(Cardinal)app->input_max*sizeof(InputEvent*));
! 	    bzero((char*)app->input_list,(unsigned)app->input_max*sizeof(InputEvent*));
  	}
  	sptr = XtNew(InputEvent);
  	sptr->ie_proc = proc;
--- 492,504 ----
  			  "invalid condition passed to XtAppAddInput",
  			  (String *)NULL, (Cardinal *)NULL);
  
! 	if (app->input_max <= source) {
! 	    Cardinal n = source + 1;
! 	    app->input_list = (InputEvent**)XtRealloc((char*) app->input_list,
! 						      n * sizeof(InputEvent*));
! 	    bzero((char *) &app->input_list[app->input_max],
! 		  (unsigned) (n - app->input_max) * sizeof(InputEvent*));
! 	    app->input_max = n;
  	}
  	sptr = XtNew(InputEvent);
  	sptr->ie_proc = proc;
***************
*** 554,566 ****
  	if(app->input_list && (sptr = app->input_list[source]) != NULL) {
  		for( lptr = NULL ; sptr; sptr = sptr->ie_next ){
  			if(sptr == (InputEvent *) id) {
! 				XtInputMask condition;
  				if(lptr == NULL) {
  				    app->input_list[source] = sptr->ie_next;
  				} else {
  				    lptr->ie_next = sptr->ie_next;
  				}
! 				for (condition = 0, lptr = sptr->ie_next;
  				     lptr; lptr = lptr->ie_next)
  				    condition |= lptr->ie_condition;
  				if ((sptr->ie_condition & XtInputReadMask) &&
--- 541,553 ----
  	if(app->input_list && (sptr = app->input_list[source]) != NULL) {
  		for( lptr = NULL ; sptr; sptr = sptr->ie_next ){
  			if(sptr == (InputEvent *) id) {
! 				XtInputMask condition = 0;
  				if(lptr == NULL) {
  				    app->input_list[source] = sptr->ie_next;
  				} else {
  				    lptr->ie_next = sptr->ie_next;
  				}
! 				for (lptr = app->input_list[source];
  				     lptr; lptr = lptr->ie_next)
  				    condition |= lptr->ie_condition;
  				if ((sptr->ie_condition & XtInputReadMask) &&
***************
*** 600,605 ****
--- 587,593 ----
  	    ep = next;
  	}
      }
+     XtFree((char *) app->input_list);
  }
  
  /* Do alternate input and timer callbacks if there are any */
*** /tmp/da4782	Mon May 17 18:19:50 1993
--- mit/lib/Xt/PassivGrab.c	Mon May 17 18:19:49 1993
***************
*** 1,4 ****
! /* $XConsortium: PassivGrab.c,v 1.20 92/05/11 17:44:00 converse Exp $ */
  
  /********************************************************
  
--- 1,4 ----
! /* $XConsortium: PassivGrab.c,v 1.22 93/01/28 18:43:44 converse Exp $ */
  
  /********************************************************
  
***************
*** 30,37 ****
  #include "StringDefs.h"
  #include "PassivGraI.h"
  
- static String XtNinvalidWidget = "invalidWidget";
- 
  /* typedef unsigned long Mask; */
  #define BITMASK(i) (((Mask)1) << ((i) & 31))
  #define MASKIDX(i) ((i) >> 5)
--- 30,35 ----
***************
*** 670,682 ****
      XtPerDisplayInput	pdi;
      
      
!     if (!XtIsWidget(widget)){
! 	XtAppWarningMsg(XtWidgetToApplicationContext(widget),
! 		     XtNinvalidWidget, "grabKeyOrButton", XtCXtToolkitError,
! 		     "Widget specified in grab is not a widget",
! 		     (String *)NULL, (Cardinal *)NULL);
! 	return;
!     }
      
      pwi = _XtGetPerWidgetInput(widget, TRUE);
      if (isKeyboard)
--- 668,674 ----
      XtPerDisplayInput	pdi;
      
      
!     XtCheckSubclass(widget, coreWidgetClass, "in XtGrabKey or XtGrabButton");
      
      pwi = _XtGetPerWidgetInput(widget, TRUE);
      if (isKeyboard)
***************
*** 722,734 ****
      XtServerGrabRec 	tempGrab;
      XtPerWidgetInput	pwi;
      
!     if (!XtIsWidget(widget)){
! 	XtAppWarningMsg(XtWidgetToApplicationContext(widget),
! 		     XtNinvalidWidget, "ungrabKeyOrButton", XtCXtToolkitError,
! 		     "Widget specified in ungrab is not a widget",
! 		     (String *)NULL, (Cardinal *)NULL);
! 	return;
!     }
      
      /* Build a temporary grab list entry */
      tempGrab.widget = widget;
--- 714,721 ----
      XtServerGrabRec 	tempGrab;
      XtPerWidgetInput	pwi;
      
!     XtCheckSubclass(widget, coreWidgetClass,
! 		    "in XtUngrabKey or XtUngrabButton");
      
      /* Build a temporary grab list entry */
      tempGrab.widget = widget;
***************
*** 877,887 ****
      XtPerDisplayInput	pdi;
      int			returnVal;
      
!     if (!XtIsWidget(widget) || !XtIsRealized(widget))
!       XtAppErrorMsg(XtWidgetToApplicationContext(widget),
! 		    XtNinvalidWidget, "grabDevice", XtCXtToolkitError,
! 		    "Grab widget must be a realized widget",
! 		    (String*)NULL, (Cardinal*)NULL);
      
      pdi = _XtGetPerDisplayInput(XtDisplay(widget));
      
--- 864,873 ----
      XtPerDisplayInput	pdi;
      int			returnVal;
      
!     XtCheckSubclass(widget, coreWidgetClass,
! 		    "in XtGrabKeyboard or XtGrabPointer");
!     if (!XtIsRealized(widget))
! 	return GrabNotViewable;
      
      pdi = _XtGetPerDisplayInput(XtDisplay(widget));
      
***************
*** 921,931 ****
      XtPerDisplayInput	pdi = _XtGetPerDisplayInput(XtDisplay(widget));
      XtDevice		device = isKeyboard ? &pdi->keyboard : &pdi->pointer;
  
!     if (!XtIsWidget(widget) || !XtIsRealized(widget))
!       XtAppErrorMsg(XtWidgetToApplicationContext(widget),
! 		    XtNinvalidWidget, "ungrabDevice", XtCXtToolkitError,
! 		    "Grab widget must be a realized widget",
! 		    (String*)NULL, (Cardinal*)NULL);
       
      if (device->grabType != XtNoServerGrab)
        {
--- 907,916 ----
      XtPerDisplayInput	pdi = _XtGetPerDisplayInput(XtDisplay(widget));
      XtDevice		device = isKeyboard ? &pdi->keyboard : &pdi->pointer;
  
!     XtCheckSubclass(widget, coreWidgetClass,
! 		    "in XtUngrabKeyboard or XtUngrabPointer");
!     if (!XtIsRealized(widget))
! 	return;
       
      if (device->grabType != XtNoServerGrab)
        {
*** /tmp/da4818	Mon May 17 18:19:53 1993
--- mit/lib/Xt/SelectionI.h	Mon May 17 18:19:53 1993
***************
*** 1,4 ****
! /* $XConsortium: SelectionI.h,v 1.33 92/11/13 17:38:21 converse Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
--- 1,4 ----
! /* $XConsortium: SelectionI.h,v 1.34 93/01/26 16:25:31 converse Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
***************
*** 28,36 ****
  #define _XtselectionI_h
  
  #include "Intrinsic.h"
- 
- #define BYTELENGTH(length, format) ((length)*((format)>>3))
- #define NUMELEM(bytelength, format) ((bytelength) / ((format)>>3))
  
  typedef struct _RequestRec *Request;
  typedef struct _SelectRec *Select;
--- 28,33 ----
*** /tmp/da4854	Mon May 17 18:19:57 1993
--- mit/lib/Xt/Selection.c	Mon May 17 18:19:56 1993
***************
*** 1,4 ****
! /* $XConsortium: Selection.c,v 1.74 92/11/13 17:40:46 converse Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
--- 1,4 ----
! /* $XConsortium: Selection.c,v 1.78 93/05/13 11:09:15 converse Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
***************
*** 70,75 ****
--- 70,90 ----
  
  static XContext selectPropertyContext = 0;
  
+ static int StorageSize[3] = {1, sizeof(short), sizeof(long)};
+ #define BYTELENGTH(length, format) ((length) * StorageSize[(format)>>4])
+ #define NUMELEM(bytelength, format) ((bytelength) / StorageSize[(format)>>4])
+ 
+ /* Xlib and Xt are permitted to have different memory allocators, and in the
+  * XtSelectionCallbackProc the client is instructed to free the selection
+  * value with XtFree, so the selection value received from XGetWindowProperty
+  * should be copied to memory allocated through Xt.  But copying is
+  * undesirable since the selection value may be large, and, under normal
+  * library configuration copying is unnecessary.
+  */
+ #ifdef XTTRACEMEMORY
+ #define XT_COPY_SELECTION	1
+ #endif
+ 
  /*ARGSUSED*/
  static void FreePropList(w, closure, callData)
   Widget w;			/* unused */
***************
*** 346,359 ****
  {
      Display *dpy = req->ctx->dpy;
      Window window = req->requestor;
!     Widget widget = req->widget;
  
      if (XtWindow(widget) == window)
! 	XtAddEventHandler(widget, mask, TRUE, proc, closure);
      else {
- 	Widget w = XtWindowToWidget(dpy, window);
  	RequestWindowRec *requestWindowRec;
- 	if (w != NULL && w != widget) widget = w;
  	if (selectWindowContext == 0)
  	    selectWindowContext = XUniqueContext();
  	if (XFindContext(dpy, window, selectWindowContext,
--- 361,375 ----
  {
      Display *dpy = req->ctx->dpy;
      Window window = req->requestor;
!     Widget widget = XtWindowToWidget(dpy, window);
  
+     if (widget != NULL) req->widget = widget;
+     else widget = req->widget;
+ 
      if (XtWindow(widget) == window)
! 	XtAddEventHandler(widget, mask, False, proc, closure);
      else {
  	RequestWindowRec *requestWindowRec;
  	if (selectWindowContext == 0)
  	    selectWindowContext = XUniqueContext();
  	if (XFindContext(dpy, window, selectWindowContext,
***************
*** 1068,1073 ****
--- 1084,1096 ----
         XtFree((char*)info);
      } else { /* add increment to collection */
        if (info->incremental) {
+ #ifdef XT_COPY_SELECTION
+ 	  int size = BYTELENGTH(length, info->format) + 1;
+ 	  char *tmp = XtMalloc((Cardinal) size);
+ 	  bcopy(value, tmp, size);
+ 	  XFree(value);
+ 	  value = tmp;
+ #endif
          (*info->callback)(widget, *info->req_closure, &ctx->selection, 
  			  &info->type, value, &length, &info->format);
        } else {
***************
*** 1176,1181 ****
--- 1199,1213 ----
      }
  
      XDeleteProperty(dpy, XtWindow(widget), property);
+ #ifdef XT_COPY_SELECTION
+     if (value) {   /* it could have been deleted after the SelectionNotify */
+ 	int size = BYTELENGTH(length, info->format) + 1;
+ 	char *tmp = XtMalloc((Cardinal) size);
+ 	bcopy(value, tmp, size);
+ 	XFree(value);
+ 	value = (unsigned char *) tmp;
+     }
+ #endif
      (*info->callback)(widget, closure, &selection, 
  			  &type, (XtPointer)value, &length, &format);
  
*** /tmp/da4890	Mon May 17 18:20:01 1993
--- mit/lib/Xt/TranslateI.h	Mon May 17 18:20:00 1993
***************
*** 1,4 ****
! /* $XConsortium: TranslateI.h,v 1.43 92/02/24 17:42:20 converse Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
--- 1,4 ----
! /* $XConsortium: TranslateI.h,v 1.45 92/12/22 17:17:33 converse Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
***************
*** 275,283 ****
  #define TMKEYCACHESIZE (1<<TMKEYCACHELOG2)
  
  typedef struct _KeyCacheRec {
!     Modifiers modifiers_return; /* constant for a give XtKeyProc */
      KeyCode keycode[TMKEYCACHESIZE];
!     unsigned short modifiers[TMKEYCACHESIZE];
      KeySym keysym[TMKEYCACHESIZE];
  } TMKeyCache;
  
--- 275,283 ----
  #define TMKEYCACHESIZE (1<<TMKEYCACHELOG2)
  
  typedef struct _KeyCacheRec {
!     unsigned char modifiers_return[256]; /* constant per KeyCode, key proc */
      KeyCode keycode[TMKEYCACHESIZE];
!     unsigned char modifiers[TMKEYCACHESIZE];
      KeySym keysym[TMKEYCACHESIZE];
  } TMKeyCache;
  
***************
*** 469,476 ****
  
  extern Boolean _XtComputeLateBindings(
  #if NeedFunctionPrototypes
      LateBindingsPtr	/* lateModifiers */,
-     TMEventPtr		/* eventSeq */,
      Modifiers*		/* computed */,
      Modifiers*		/* computedMask */
  #endif
--- 469,476 ----
  
  extern Boolean _XtComputeLateBindings(
  #if NeedFunctionPrototypes
+     Display*		/* dpy */,
      LateBindingsPtr	/* lateModifiers */,
      Modifiers*		/* computed */,
      Modifiers*		/* computedMask */
  #endif
*** /tmp/da4926	Mon May 17 18:20:04 1993
--- mit/lib/Xt/TMaction.c	Mon May 17 18:20:03 1993
***************
*** 1,4 ****
! /* $XConsortium: TMaction.c,v 1.16 91/07/31 13:12:13 swick Exp $ */
  /*LINTLIBRARY*/
  
  /***********************************************************
--- 1,4 ----
! /* $XConsortium: TMaction.c,v 1.18 93/05/13 15:14:24 converse Exp $ */
  /*LINTLIBRARY*/
  
  /***********************************************************
***************
*** 32,38 ****
  #include "IntrinsicI.h"
  #include "StringDefs.h"
  
! #if __STDC__ && !defined(VMS)
  #define RConst const
  #else
  #define RConst /**/
--- 32,38 ----
  #include "IntrinsicI.h"
  #include "StringDefs.h"
  
! #if __STDC__ && !defined(NORCONST)
  #define RConst const
  #else
  #define RConst /**/
***************
*** 211,217 ****
      unsigned int	boundInHierarchy:1;
      unsigned int	boundInContext:1;
      unsigned int	notFullyBound:1;
!     unsigned int	refCount:12;
  }TMBindCacheStatusRec, *TMBindCacheStatus;
  
  typedef struct _TMBindCacheRec{
--- 211,217 ----
      unsigned int	boundInHierarchy:1;
      unsigned int	boundInContext:1;
      unsigned int	notFullyBound:1;
!     unsigned int	refCount:28;
  }TMBindCacheStatusRec, *TMBindCacheStatus;
  
  typedef struct _TMBindCacheRec{
*** /tmp/da4962	Mon May 17 18:20:08 1993
--- mit/lib/Xt/TMgrab.c	Mon May 17 18:20:08 1993
***************
*** 1,4 ****
! /* $XConsortium: TMgrab.c,v 1.4 91/04/12 14:02:15 converse Exp $ */
  /*LINTLIBRARY*/
  
  /***********************************************************
--- 1,4 ----
! /* $XConsortium: TMgrab.c,v 1.9 92/12/24 10:41:47 converse Exp $ */
  /*LINTLIBRARY*/
  
  /***********************************************************
***************
*** 46,51 ****
--- 46,63 ----
      Display *dpy = XtDisplay(widget);
      KeyCode *keycodes, *keycodeP;
      Cardinal keycount;
+     Modifiers careOn = 0;
+     Modifiers careMask = 0;
+ 
+     if (modMatch->lateModifiers) {
+ 	Boolean resolved;
+ 	resolved = _XtComputeLateBindings(dpy, modMatch->lateModifiers,
+ 					  &careOn, &careMask);
+ 	if (!resolved) return;
+     }
+     careOn |= modMatch->modifiers;
+     careMask |= modMatch->modifierMask;
+ 
      XtKeysymToKeycodeList(
  	    dpy,
  	    (KeySym)typeMatch->eventCode,
***************
*** 57,69 ****
  	if (modMatch->standard) {
  	    /* find standard modifiers that produce this keysym */
  	    KeySym keysym;
! 	    int std_mods, least_mod = 1;
  	    Modifiers modifiers_return;
  	    XtTranslateKeycode( dpy, *keycodeP, (Modifiers)0,
  			        &modifiers_return, &keysym );
  	    if (keysym == typeMatch->eventCode) {
! 		XtGrabKey(widget, *keycodeP,
! 			  (unsigned)modMatch->modifiers,
  			  grabP->owner_events,
  			  grabP->pointer_mode,
  			  grabP->keyboard_mode
--- 69,82 ----
  	if (modMatch->standard) {
  	    /* find standard modifiers that produce this keysym */
  	    KeySym keysym;
! 	    int std_mods, least_mod;
  	    Modifiers modifiers_return;
  	    XtTranslateKeycode( dpy, *keycodeP, (Modifiers)0,
  			        &modifiers_return, &keysym );
+ 	    if (careOn & modifiers_return)
+ 		return;
  	    if (keysym == typeMatch->eventCode) {
! 		XtGrabKey(widget, *keycodeP, careOn,
  			  grabP->owner_events,
  			  grabP->pointer_mode,
  			  grabP->keyboard_mode
***************
*** 70,86 ****
  			);
  		/* continue; */		/* grab all modifier combinations */
  	    }
! 	    while ((least_mod & modifiers_return)==0) least_mod <<= 1;	    
  	    for (std_mods = modifiers_return;
  		 std_mods >= least_mod; std_mods--) {
  		 /* check all useful combinations of modifier bits */
! 		if (modifiers_return & std_mods) {
  		    XtTranslateKeycode( dpy, *keycodeP,
  					(Modifiers)std_mods,
! 					&modifiers_return, &keysym );
  		    if (keysym == typeMatch->eventCode) {
  			XtGrabKey(widget, *keycodeP,
! 				  (unsigned)modMatch->modifiers | std_mods,
  				  grabP->owner_events,
  				  grabP->pointer_mode,
  				  grabP->keyboard_mode
--- 83,101 ----
  			);
  		/* continue; */		/* grab all modifier combinations */
  	    }
! 	    least_mod = modifiers_return & (~modifiers_return + 1);
  	    for (std_mods = modifiers_return;
  		 std_mods >= least_mod; std_mods--) {
+ 		Modifiers dummy;
  		 /* check all useful combinations of modifier bits */
! 		if (modifiers_return & std_mods &&
! 		    !(~modifiers_return & std_mods)) {
  		    XtTranslateKeycode( dpy, *keycodeP,
  					(Modifiers)std_mods,
! 					&dummy, &keysym );
  		    if (keysym == typeMatch->eventCode) {
  			XtGrabKey(widget, *keycodeP,
! 				  careOn | (Modifiers) std_mods,
  				  grabP->owner_events,
  				  grabP->pointer_mode,
  				  grabP->keyboard_mode
***************
*** 90,97 ****
  		}
  	    }
  	} else /* !event->standard */ {
! 	    XtGrabKey(widget, *keycodeP,
! 		      (unsigned)modMatch->modifiers,
  		      grabP->owner_events,
  		      grabP->pointer_mode,
  		      grabP->keyboard_mode
--- 105,111 ----
  		}
  	    }
  	} else /* !event->standard */ {
! 	    XtGrabKey(widget, *keycodeP, careOn,
  		      grabP->owner_events,
  		      grabP->pointer_mode,
  		      grabP->keyboard_mode
***************
*** 120,125 ****
--- 134,142 ----
      ActionRec		*action;
      TMTypeMatch		typeMatch = TMGetTypeMatch(typeIndex);
      TMModifierMatch	modMatch = TMGetModifierMatch(modIndex);
+     Modifiers		careOn = 0;
+     Modifiers		careMask = 0;
+     Boolean		resolved;
  
      for (action = state->actions; action; action = action->next)
        if (count == action->idx) break;
***************
*** 128,137 ****
      switch (typeMatch->eventType) {
        case ButtonPress:
        case ButtonRelease:
  	XtGrabButton(
  		     widget,
  		     (unsigned) typeMatch->eventCode,
! 		     (unsigned) modMatch->modifiers,
  		     grabP->owner_events,
  		     grabP->event_mask,
  		     grabP->pointer_mode,
--- 145,161 ----
      switch (typeMatch->eventType) {
        case ButtonPress:
        case ButtonRelease:
+ 	if (modMatch->lateModifiers) {
+ 	    resolved = _XtComputeLateBindings(XtDisplay(widget),
+ 					      modMatch->lateModifiers,
+ 					      &careOn, &careMask);
+ 	    if (!resolved) break;
+ 	}
+ 	careOn |= modMatch->modifiers;
  	XtGrabButton(
  		     widget,
  		     (unsigned) typeMatch->eventCode,
! 		     careOn,
  		     grabP->owner_events,
  		     grabP->event_mask,
  		     grabP->pointer_mode,
***************
*** 240,249 ****
  	    || actionP->event_mask != event_mask
  	    || actionP->pointer_mode != pointer_mode
  	    || actionP->keyboard_mode != keyboard_mode) {
  	    XtWarningMsg(
  		"argsReplaced", "xtRegisterGrabAction", XtCXtToolkitError,
! 		"XtRegisterGrabAction called on same proc with different args"
! 			);
  	}
  #endif /*DEBUG*/
  
--- 264,274 ----
  	    || actionP->event_mask != event_mask
  	    || actionP->pointer_mode != pointer_mode
  	    || actionP->keyboard_mode != keyboard_mode) {
+ 	    Cardinal n = 0;
  	    XtWarningMsg(
  		"argsReplaced", "xtRegisterGrabAction", XtCXtToolkitError,
! 		"XtRegisterGrabAction called on same proc with different args",
! 			 NULL, &n);
  	}
  #endif /*DEBUG*/
  
*** /tmp/da4998	Mon May 17 18:20:12 1993
--- mit/lib/Xt/TMkey.c	Mon May 17 18:20:11 1993
***************
*** 1,4 ****
! /* $XConsortium: TMkey.c,v 1.17 92/11/23 15:44:37 converse Exp $ */
  /*LINTLIBRARY*/
  
  /***********************************************************
--- 1,4 ----
! /* $XConsortium: TMkey.c,v 1.19 92/12/22 17:20:52 converse Exp $ */
  /*LINTLIBRARY*/
  
  /***********************************************************
***************
*** 86,91 ****
--- 86,93 ----
  };
  #undef FM
  
+ #define MOD_RETURN(ctx, key) (ctx)->keycache.modifiers_return[key]
+ 
  #define TRANSLATE(ctx,pd,dpy,key,mod,mod_ret,sym_ret) \
  { \
      int _i_ = (((key) - (pd)->min_keycode + modmix[(mod) & 0xff]) & \
***************
*** 93,126 ****
      if ((key) != 0 && /* Xlib XIM composed input */ \
  	(ctx)->keycache.keycode[_i_] == (key) && \
  	(ctx)->keycache.modifiers[_i_] == (mod)) { \
! 	mod_ret = (ctx)->keycache.modifiers_return; \
  	sym_ret = (ctx)->keycache.keysym[_i_]; \
      } else { \
  	XtTranslateKeycode(dpy, key, mod, &mod_ret, &sym_ret); \
  	(ctx)->keycache.keycode[_i_] = key; \
! 	(ctx)->keycache.modifiers[_i_] = (unsigned short)(mod); \
  	(ctx)->keycache.keysym[_i_] = sym_ret; \
! 	(ctx)->keycache.modifiers_return = mod_ret; \
      } \
  }
  
  /* usual number of expected keycodes in XtKeysymToKeycodeList */
  #define KEYCODE_ARRAY_SIZE 10
  
  static void _XtConvertCase();
  
! Boolean _XtComputeLateBindings(lateModifiers,eventSeq,computed,computedMask)
      LateBindingsPtr lateModifiers;
-     TMEventPtr eventSeq;
      Modifiers *computed,*computedMask;
  {
      int i,j,ref;
      ModToKeysymTable* temp;
      XtPerDisplay perDisplay;
-     Display *dpy;
      Boolean found;
      KeySym tempKeysym = NoSymbol;
!     dpy = eventSeq->xev->xany.display;
      perDisplay = _XtGetPerDisplay(dpy);
      if (perDisplay == NULL) {
          XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
--- 95,137 ----
      if ((key) != 0 && /* Xlib XIM composed input */ \
  	(ctx)->keycache.keycode[_i_] == (key) && \
  	(ctx)->keycache.modifiers[_i_] == (mod)) { \
! 	mod_ret = MOD_RETURN(ctx, key); \
  	sym_ret = (ctx)->keycache.keysym[_i_]; \
      } else { \
  	XtTranslateKeycode(dpy, key, mod, &mod_ret, &sym_ret); \
  	(ctx)->keycache.keycode[_i_] = key; \
! 	(ctx)->keycache.modifiers[_i_] = (unsigned char)(mod); \
  	(ctx)->keycache.keysym[_i_] = sym_ret; \
! 	MOD_RETURN(ctx, key) = (unsigned char)mod_ret; \
      } \
  }
  
+ #define UPDATE_CACHE(ctx, pd, key, mod, mod_ret, sym_ret) \
+ { \
+     int _i_ = (((key) - (pd)->min_keycode + modmix[(mod) & 0xff]) & \
+ 	       (TMKEYCACHESIZE-1)); \
+     (ctx)->keycache.keycode[_i_] = key; \
+     (ctx)->keycache.modifiers[_i_] = (unsigned char)(mod); \
+     (ctx)->keycache.keysym[_i_] = sym_ret; \
+     MOD_RETURN(ctx, key) = (unsigned char)mod_ret; \
+ }
+ 
  /* usual number of expected keycodes in XtKeysymToKeycodeList */
  #define KEYCODE_ARRAY_SIZE 10
  
  static void _XtConvertCase();
  
! Boolean _XtComputeLateBindings(dpy, lateModifiers, computed, computedMask)
!     Display *dpy;
      LateBindingsPtr lateModifiers;
      Modifiers *computed,*computedMask;
  {
      int i,j,ref;
      ModToKeysymTable* temp;
      XtPerDisplay perDisplay;
      Boolean found;
      KeySym tempKeysym = NoSymbol;
! 
      perDisplay = _XtGetPerDisplay(dpy);
      if (perDisplay == NULL) {
          XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
***************
*** 191,198 ****
      TMKeyContext tm_context;
      
      if (modMatch->lateModifiers != NULL)
!       resolved = _XtComputeLateBindings(modMatch->lateModifiers,
! 					eventSeq,&computed,&computedMask);
      if (!resolved) return FALSE;
      computed |= modMatch->modifiers;
      computedMask |= modMatch->modifierMask; /* gives do-care mask */
--- 202,209 ----
      TMKeyContext tm_context;
      
      if (modMatch->lateModifiers != NULL)
! 	resolved = _XtComputeLateBindings(dpy, modMatch->lateModifiers,
! 					  &computed, &computedMask);
      if (!resolved) return FALSE;
      computed |= modMatch->modifiers;
      computedMask |= modMatch->modifierMask; /* gives do-care mask */
***************
*** 267,284 ****
      TMKeyContext tm_context = pd->tm_context;
      Modifiers translateModifiers;
  
!     _InitializeKeysymTables(dpy, pd);
!     translateModifiers =(Modifiers)
!       (eventSeq->event.modifiers & ((ShiftMask|LockMask) | pd->mode_switch));
  
!     TRANSLATE(tm_context, pd, dpy, (KeyCode)eventSeq->event.eventCode,
! 			translateModifiers, modifiers_return, keysym_return);
  
      if ((typeMatch->eventCode & typeMatch->eventCodeMask) ==
               (keysym_return & typeMatch->eventCodeMask)) {
          if (modMatch->lateModifiers != NULL) 
!             resolved = _XtComputeLateBindings(modMatch->lateModifiers,
! 					   eventSeq,&computed,&computedMask);
          if (!resolved) return FALSE;
          computed |= modMatch->modifiers;
          computedMask |= modMatch->modifierMask;
--- 278,308 ----
      TMKeyContext tm_context = pd->tm_context;
      Modifiers translateModifiers;
  
!     /* To maximize cache utilization, we mask off nonstandard modifiers
!        before cache lookup.  For a given key translator, standard modifiers
!        are constant per KeyCode.  If a key translator uses no standard
!        modifiers this implementation will never reference the cache.
!      */
  
!     modifiers_return = MOD_RETURN(tm_context, eventSeq->event.eventCode);
!     if (!modifiers_return) {
! 	XtTranslateKeycode(dpy, (KeyCode)eventSeq->event.eventCode, 
! 			   eventSeq->event.modifiers, &modifiers_return,
! 			   &keysym_return);
! 	translateModifiers = eventSeq->event.modifiers & modifiers_return;
! 	UPDATE_CACHE(tm_context, pd, eventSeq->event.eventCode, 
! 		     translateModifiers, modifiers_return, keysym_return);
!     } else {
! 	translateModifiers = eventSeq->event.modifiers & modifiers_return;
! 	TRANSLATE(tm_context, pd, dpy, (KeyCode)eventSeq->event.eventCode,
! 		  translateModifiers, modifiers_return, keysym_return);
!     }
  
      if ((typeMatch->eventCode & typeMatch->eventCodeMask) ==
               (keysym_return & typeMatch->eventCodeMask)) {
          if (modMatch->lateModifiers != NULL) 
!             resolved = _XtComputeLateBindings(dpy, modMatch->lateModifiers,
! 					      &computed, &computedMask);
          if (!resolved) return FALSE;
          computed |= modMatch->modifiers;
          computedMask |= modMatch->modifierMask;
*** /tmp/da5034	Mon May 17 18:20:16 1993
--- mit/lib/Xt/TMparse.c	Mon May 17 18:20:14 1993
***************
*** 1,4 ****
! /* $XConsortium: TMparse.c,v 1.128 92/03/05 18:48:55 converse Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
--- 1,4 ----
! /* $XConsortium: TMparse.c,v 1.134 92/12/30 13:02:26 converse Exp $ */
  
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
***************
*** 43,48 ****
--- 43,56 ----
  # define CACHED XtCacheNone
  #endif
  
+ #ifndef MAX
+ #define MAX(a,b) (((a) > (b)) ? (a) : (b))
+ #endif
+ 
+ #ifndef MIN
+ #define MIN(a,b) (((a) < (b)) ? (a) : (b))
+ #endif
+ 
  static String XtNtranslationParseError = "translationParseError";
  
  typedef int		EventType;
***************
*** 83,89 ****
  static String CheckForPoundSign();
  static KeySym StringToKeySym();
  static ModifierRec modifiers[] = {
-     {"None",    0,      ParseModImmed,None},
      {"Shift",	0,	ParseModImmed,ShiftMask},
      {"Lock",	0,	ParseModImmed,LockMask},
      {"Ctrl",	0,	ParseModImmed,ControlMask},
--- 91,96 ----
***************
*** 105,113 ****
      {"Button3",	0,	ParseModImmed,Button3Mask},
      {"Button4",	0,	ParseModImmed,Button4Mask},
      {"Button5",	0,	ParseModImmed,Button5Mask},
- 
-     {"Any",	0,	ParseModImmed,AnyModifier},
- 
      {"c",	0,	ParseModImmed,ControlMask},
      {"s",	0,	ParseModImmed,ShiftMask},
      {"l",	0,	ParseModImmed,LockMask},
--- 112,117 ----
***************
*** 344,349 ****
--- 348,357 ----
  
  
  static Boolean initialized = FALSE;
+ static XrmQuark QMeta;
+ static XrmQuark QCtrl;
+ static XrmQuark QNone;
+ static XrmQuark QAny;
  
  static void FreeEventSeq(eventSeq)
      EventSeqPtr eventSeq;
***************
*** 556,563 ****
      }
  }
  
! static Boolean _XtLookupModifier(name,lateBindings,notFlag,valueP,constMask)
!     String name;
      LateBindingsPtr* lateBindings;
      Boolean notFlag;
      Value *valueP;
--- 564,572 ----
      }
  }
  
! static Boolean _XtLookupModifier(signature, lateBindings, notFlag, valueP,
! 				 constMask)
!     XrmQuark signature;
      LateBindingsPtr* lateBindings;
      Boolean notFlag;
      Value *valueP;
***************
*** 564,570 ****
      Bool constMask;
  {
     register int i, left, right;
-    register XrmQuark signature = StringToQuark(name);
     static int previous = 0;
     
     if (signature == modifiers[previous].signature) {
--- 573,578 ----
***************
*** 571,577 ****
         if (constMask)  *valueP = modifiers[previous].value;
         else /* if (modifiers[previous].modifierParseProc) always true */
  	   (*modifiers[previous].modifierParseProc)
! 	      (name, modifiers[previous].value, lateBindings, notFlag, valueP);
         return TRUE;
     }
  
--- 579,585 ----
         if (constMask)  *valueP = modifiers[previous].value;
         else /* if (modifiers[previous].modifierParseProc) always true */
  	   (*modifiers[previous].modifierParseProc)
! 	      (modifiers[previous].value, lateBindings, notFlag, valueP);
         return TRUE;
     }
  
***************
*** 588,594 ****
  	   if (constMask)  *valueP = modifiers[i].value;
  	   else /* if (modifiers[i].modifierParseProc) always true */
  	       (*modifiers[i].modifierParseProc)
! 		   (name, modifiers[i].value, lateBindings, notFlag, valueP);
  	   return TRUE;
         }
     }
--- 596,602 ----
  	   if (constMask)  *valueP = modifiers[i].value;
  	   else /* if (modifiers[i].modifierParseProc) always true */
  	       (*modifiers[i].modifierParseProc)
! 		   (modifiers[i].value, lateBindings, notFlag, valueP);
  	   return TRUE;
         }
     }
***************
*** 611,637 ****
      return str;
  }
  
! static String FetchModifierToken(str,modStr)
!     String str,modStr;
  {
      String start = str;
!     String metaString = "Meta";
!     String ctrlString = "Ctrl";
      if (*str == '$') {
!         strcpy(modStr,metaString);
          str++;
          return str;
      }
      if (*str == '^') {
!         strcpy(modStr,ctrlString);
          str++;
          return str;
      }
      str = ScanIdent(str);
      if (start != str) {
! 	 bcopy(start, modStr, str-start);
!           modStr[str-start] = '\0';
!           return str;
      }
      return str;
  }        
--- 619,647 ----
      return str;
  }
  
! static String FetchModifierToken(str, token_return)
!     String str;
!     XrmQuark *token_return;
  {
      String start = str;
! 
      if (*str == '$') {
!         *token_return = QMeta;
          str++;
          return str;
      }
      if (*str == '^') {
!         *token_return = QCtrl;
          str++;
          return str;
      }
      str = ScanIdent(str);
      if (start != str) {
! 	char modStr[100];
! 	bcopy(start, modStr, str-start);
! 	modStr[str-start] = '\0';
! 	*token_return = XrmStringToQuark(modStr);
! 	return str;
      }
      return str;
  }        
***************
*** 644,672 ****
      register String start;
      Boolean notFlag, exclusive, keysymAsMod;
      Value maskBit;
!     char modStr[100];
   
      ScanWhitespace(str);
      start = str;
!     str = FetchModifierToken(str,modStr);
      exclusive = FALSE;
      if (start != str) {
!           if (_XtLookupModifier(modStr,(LateBindingsPtr *) NULL,
! 		  FALSE,&maskBit,TRUE)) {
! 	      if (maskBit== None) {
! 		  event->event.modifierMask = ~0;
! 		  event->event.modifiers = 0;
! 		  ScanWhitespace(str);
! 		  return str;
! 	      }
! 	      if (maskBit == AnyModifier) {/*backward compatability*/
! 		  event->event.modifierMask = 0;
! 		  event->event.modifiers = 0;
! 		  ScanWhitespace(str);
! 		  return str;
! 	      }
! 	  }
! 	  str = start; /*if plain modifier, reset to beginning */
      }
      else while (*str == '!' || *str == ':') {
          if (*str == '!') {
--- 654,678 ----
      register String start;
      Boolean notFlag, exclusive, keysymAsMod;
      Value maskBit;
!     XrmQuark Qmod;
   
      ScanWhitespace(str);
      start = str;
!     str = FetchModifierToken(str, &Qmod);
      exclusive = FALSE;
      if (start != str) {
! 	if (Qmod == QNone) {
! 	    event->event.modifierMask = ~0;
! 	    event->event.modifiers = 0;
! 	    ScanWhitespace(str);
! 	    return str;
! 	} else if (Qmod == QAny) { /*backward compatability*/
! 	    event->event.modifierMask = 0;
! 	    event->event.modifiers = AnyModifier;
! 	    ScanWhitespace(str);
! 	    return str;
! 	}
! 	str = start; /*if plain modifier, reset to beginning */
      }
      else while (*str == '!' || *str == ':') {
          if (*str == '!') {
***************
*** 693,699 ****
          }
          else keysymAsMod = FALSE;
  	start = str;
!         str = FetchModifierToken(str,modStr);
          if (start == str) {
              Syntax("Modifier or '<' expected","");
              *error = TRUE;
--- 699,705 ----
          }
          else keysymAsMod = FALSE;
  	start = str;
!         str = FetchModifierToken(str, &Qmod);
          if (start == str) {
              Syntax("Modifier or '<' expected","");
              *error = TRUE;
***************
*** 700,714 ****
              return PanicModeRecovery(str);
          }
           if (keysymAsMod) {
!              _XtParseKeysymMod(modStr,&event->event.lateModifiers,
  			       notFlag,&maskBit, error);
  	     if (*error)
                   return PanicModeRecovery(str);
  
           } else
!   	     if (!_XtLookupModifier( modStr,
! 	   &event->event.lateModifiers, notFlag, &maskBit,FALSE)) {
! 	         Syntax("Unknown modifier name:  ",modStr);
                   *error = TRUE;
                   return PanicModeRecovery(str);
               }
--- 706,721 ----
              return PanicModeRecovery(str);
          }
           if (keysymAsMod) {
!              _XtParseKeysymMod(XrmQuarkToString(Qmod),
! 			       &event->event.lateModifiers,
  			       notFlag,&maskBit, error);
  	     if (*error)
                   return PanicModeRecovery(str);
  
           } else
!   	     if (!_XtLookupModifier(Qmod, &event->event.lateModifiers,
! 				    notFlag, &maskBit, FALSE)) {
! 	         Syntax("Unknown modifier name:  ", XrmQuarkToString(Qmod));
                   *error = TRUE;
                   return PanicModeRecovery(str);
               }
***************
*** 823,830 ****
      return NoSymbol;
  }
  /* ARGSUSED */
! static void ParseModImmed(name,value,lateBindings,notFlag,valueP)
!     String name;
      Value value;
      LateBindingsPtr* lateBindings;
      Boolean notFlag;
--- 830,836 ----
      return NoSymbol;
  }
  /* ARGSUSED */
! static void ParseModImmed(value, lateBindings, notFlag, valueP)
      Value value;
      LateBindingsPtr* lateBindings;
      Boolean notFlag;
***************
*** 832,843 ****
  {
      *valueP = value;
  }
! /* ARGSUSED */
! static void ParseModSym (name,value,lateBindings,notFlag,valueP)
   /* is only valid with keysyms that have an _L and _R in their name;
    * and ignores keysym lookup errors (i.e. assumes only valid keysyms)
    */
-     String name;
      Value value;
      LateBindingsPtr* lateBindings;
      Boolean notFlag;
--- 838,848 ----
  {
      *valueP = value;
  }
! 
! static void ParseModSym(value, lateBindings, notFlag, valueP)
   /* is only valid with keysyms that have an _L and _R in their name;
    * and ignores keysym lookup errors (i.e. assumes only valid keysyms)
    */
      Value value;
      LateBindingsPtr* lateBindings;
      Boolean notFlag;
***************
*** 897,906 ****
      Boolean* error;
  {
      str = ParseKeySym(str, closure, event,error);
! 
!     event->event.modifiers |= (unsigned long)closure;
!     event->event.modifierMask |= (unsigned long)closure;
! 
      return str;
  }
  
--- 902,915 ----
      Boolean* error;
  {
      str = ParseKeySym(str, closure, event,error);
!     if ((unsigned long) closure == 0) {
! 	Value metaMask; /* unused */
! 	(void) _XtLookupModifier(QMeta, &event->event.lateModifiers, False,
! 				 &metaMask, False);
!     } else {
! 	event->event.modifiers |= (unsigned long) closure;
! 	event->event.modifierMask |= (unsigned long) closure;
!     }
      return str;
  }
  
***************
*** 1101,1139 ****
      register EventPtr event;
      Boolean *error;
  {
-     register int j;
- 
-     Value ctrlMask;
      Value metaMask;
-     Value shiftMask;
-     register char	c;
      char	s[2];
!     (void) _XtLookupModifier("Ctrl",(LateBindingsPtr*)NULL,
!                  FALSE,(Value *) &ctrlMask,TRUE);
!     (void) _XtLookupModifier("Meta", &event->event.lateModifiers,
!                  FALSE,(Value *) &metaMask,FALSE);
!     (void) _XtLookupModifier("Shift",(LateBindingsPtr*)NULL,
!                  FALSE,(Value *) &shiftMask,TRUE);
!     for (j=0; j < 2; j++)
! 	if (*str=='^' && !(event->event.modifiers | ctrlMask)) {
! 	    str++;
! 	    event->event.modifiers |= ctrlMask;
! 	} else if (*str == '$' && !(event->event.modifiers | metaMask)) {
! 	    str++;
! 	    event->event.modifiers |= metaMask;
! 	} else if (*str == '\\') {
! 	    str++;
! 	    c = *str;
! 	    if (*str != '\0' && *str != '\n') str++;
! 	    break;
! 	} else {
! 	    c = *str;
! 	    if (*str != '\0' && *str != '\n') str++;
! 	    break;
! 	}
!     event->event.eventType = KeyPress;
!     s[0] = c;
      s[1] = '\0';
      event->event.eventCode = StringToKeySym(s, error);
      if (*error) return PanicModeRecovery(str);
      event->event.eventCodeMask = ~0L;
--- 1110,1132 ----
      register EventPtr event;
      Boolean *error;
  {
      Value metaMask;
      char	s[2];
! 
!     if (*str=='^') {
! 	str++;
! 	event->event.modifiers = ControlMask;
!     } else if (*str == '$') {
! 	str++;
! 	(void) _XtLookupModifier(QMeta, &event->event.lateModifiers, FALSE,
! 				 &metaMask, FALSE);
!     }
!     if (*str == '\\')
! 	str++;
!     s[0] = *str;
      s[1] = '\0';
+     if (*str != '\0' && *str != '\n') str++;
+     event->event.eventType = KeyPress;
      event->event.eventCode = StringToKeySym(s, error);
      if (*error) return PanicModeRecovery(str);
      event->event.eventCodeMask = ~0L;
***************
*** 2012,2017 ****
--- 2005,2014 ----
      }
  
      initialized = TRUE;
+     QMeta = XrmPermStringToQuark("Meta");
+     QCtrl = XrmPermStringToQuark("Ctrl");
+     QNone = XrmPermStringToQuark("None");
+     QAny  = XrmPermStringToQuark("Any");
  
      Compile_XtEventTable( events, XtNumber(events) );
      Compile_XtModifierTable( modifiers, XtNumber(modifiers) );
*** /tmp/da5070	Mon May 17 18:20:22 1993
--- mit/lib/Xt/TMstate.c	Mon May 17 18:20:21 1993
***************
*** 1,4 ****
! /* $XConsortium: TMstate.c,v 1.162 92/03/25 16:47:39 converse Exp $ */
  /*LINTLIBRARY*/
  
  /***********************************************************
--- 1,4 ----
! /* $XConsortium: TMstate.c,v 1.164 93/02/05 16:47:46 converse Exp $ */
  /*LINTLIBRARY*/
  
  /***********************************************************
***************
*** 378,388 ****
      if (typeMatch->eventCode != (eventSeq->event.eventCode &
  				  typeMatch->eventCodeMask)) return FALSE;
      if (modMatch->lateModifiers != NULL)
!       resolved = 
! 	_XtComputeLateBindings(modMatch->lateModifiers,
! 			       eventSeq,
! 			       &computed,
! 			       &computedMask);
      if (!resolved) return FALSE;
      computed |= modMatch->modifiers;
      computedMask |= modMatch->modifierMask;
--- 378,386 ----
      if (typeMatch->eventCode != (eventSeq->event.eventCode &
  				  typeMatch->eventCodeMask)) return FALSE;
      if (modMatch->lateModifiers != NULL)
! 	resolved = _XtComputeLateBindings(eventSeq->xev->xany.display,
! 					  modMatch->lateModifiers,
! 					  &computed, &computedMask);
      if (!resolved) return FALSE;
      computed |= modMatch->modifiers;
      computedMask |= modMatch->modifierMask;
***************
*** 929,938 ****
  	    (candState = TryCurrentTree(stateTreePtr,
  				       tmRecPtr,
  				       curEventPtr))) {
! 	    matchTreeIndex = i;
! 	    matchState = candState;
! 	    if (candState->actions)
! 	      break;
  	}
      }
      if (matchState == NULL){
--- 927,938 ----
  	    (candState = TryCurrentTree(stateTreePtr,
  				       tmRecPtr,
  				       curEventPtr))) {
! 	    if (!matchState || candState->actions) {
! 		matchTreeIndex = i;
! 		matchState = candState;
! 		if (candState->actions)
! 		    break;
! 	    }
  	}
      }
      if (matchState == NULL){
*** /tmp/da5106	Mon May 17 18:20:25 1993
--- mit/lib/Xt/VarCreate.c	Mon May 17 18:20:24 1993
***************
*** 1,4 ****
! /* $XConsortium: VarCreate.c,v 1.24 91/12/10 18:57:25 converse Exp $ */
  
  /*
  
--- 1,4 ----
! /* $XConsortium: VarCreate.c,v 1.26 93/05/13 16:20:25 kaleb Exp $ */
  
  /*
  
***************
*** 20,27 ****
  */
  
  #include "IntrinsicI.h"
! #include <X11/StringDefs.h>
! #include <X11/Shell.h>
  #include "VarargsI.h"
  
  #if (defined(SUNSHLIB) || defined(AIXSHLIB)) && defined(SHAREDCODE)
--- 20,27 ----
  */
  
  #include "IntrinsicI.h"
! #include "StringDefs.h"
! #include "Shell.h"
  #include "VarargsI.h"
  
  #if (defined(SUNSHLIB) || defined(AIXSHLIB)) && defined(SHAREDCODE)
***************
*** 297,303 ****
      va_list var_args;
  #endif
  {
-     va_list var;
      XtAppContext app_con;
      Display * dpy;
      register int saved_argc = *argc_in_out;
--- 297,302 ----
***************
*** 311,333 ****
      dpy = _XtAppInit(&app_con, (String)application_class, options, num_options,
  		     argc_in_out, &argv_in_out, fallback_resources);
  
!     var = var_args;
!     for(attr = va_arg(var,String); attr != NULL; attr = va_arg(var,String)) {
!         ++count;
          if (strcmp(attr, XtVaTypedArg) == 0) {
!             va_arg(var, String);
!             va_arg(var, String);
!             va_arg(var, XtArgVal);
!             va_arg(var, int);
          } else {
!             va_arg(var, XtArgVal);
          }
      }
!     va_end(var);
  
!     var = var_args;
!     typed_args = _XtVaCreateTypedArgList(var, count);
!     va_end(var);
  
      root =
  	XtVaAppCreateShell( NULL, application_class, 
--- 310,337 ----
      dpy = _XtAppInit(&app_con, (String)application_class, options, num_options,
  		     argc_in_out, &argv_in_out, fallback_resources);
  
!     typed_args = (XtTypedArgList) XtMalloc((unsigned) sizeof(XtTypedArg));
!     attr = va_arg (var_args, String);
!     for(; attr != NULL; attr = va_arg (var_args, String)) {
          if (strcmp(attr, XtVaTypedArg) == 0) {
!             typed_args[count].name = va_arg(var_args, String);
!             typed_args[count].type = va_arg(var_args, String);
!             typed_args[count].value = va_arg(var_args, XtArgVal);
!             typed_args[count].size = va_arg(var_args, int);
          } else {
! 	    typed_args[count].name = attr;
! 	    typed_args[count].type = NULL;
! 	    typed_args[count].value = va_arg(var_args, XtArgVal);
! 	    typed_args[count].size = 0;
          }
+ 	count++;
+ 	typed_args = (XtTypedArgList) 
+ 	    XtRealloc((char *) typed_args, 
+ 		       (unsigned) (count + 1) * sizeof(XtTypedArg));
      }
!     typed_args[count].name = NULL;
  
!     va_end (var_args);
  
      root =
  	XtVaAppCreateShell( NULL, application_class, 
