This patch is a continuation of fix-13.  You must apply it at the same time
as fix-13.

cd to the top of the X tree and apply with "patch -p0".

*** /tmp/,RCSt1a29712
--- mit/lib/Xt/TMstate.c
***************
*** 1,7 ****
! #ifndef lint
! static char Xrcsid[] = "$XConsortium: TMstate.c,v 1.99 90/04/13 20:20:34 swick Exp $";
! /* $oHeader: TMstate.c,v 1.5 88/09/01 17:17:29 asente Exp $ */
! #endif /* lint */
  /*LINTLIBRARY*/
  
  /***********************************************************
--- 1,4 ----
! /* "$XConsortium: TMstate.c,v 1.110 90/07/15 21:17:38 swick Exp $"; */
  /*LINTLIBRARY*/
  
  /***********************************************************
***************
*** 31,36 ****
--- 28,34 ----
  /* TMstate.c -- maintains the state table of actions for the translation 
   *              manager.
   */
+ 
  #include <X11/Xlib.h>
  #define XK_MISCELLANY
  #define XK_LATIN1
***************
*** 39,44 ****
--- 37,49 ----
  #include <stdio.h>
  #include "IntrinsicI.h"
  
+ /* VMS linker doesn't believe relocatable addrs can be const */
+ #if defined(__STDC__) && !defined(VMS)
+ #define Const const
+ #else
+ #define Const /**/
+ #endif
+ 
  static String XtNtranslationError = "translationError";
  
  /* usual number of expected keycodes in XtKeysymToKeycodeList */
***************
*** 56,63 ****
  
  static GrabActionRec *grabActionList = NULL;
  
- #define StringToAction(string)	((XtAction) StringToQuark(string))
- 
  #define STR_THRESHOLD 25
  #define STR_INCAMOUNT 100
  #define CHECK_STR_OVERFLOW \
--- 61,66 ----
***************
*** 352,364 ****
      return str;
  }
  
! static String PrintActions(buf, len, str, actions, stateTable)
      String *buf;
      int *len;
      register String str;
      register ActionPtr actions;
!     XtTranslations stateTable;
  {
      while (actions != NULL) {
  	String proc;
  	*str++ = ' ';
--- 355,368 ----
      return str;
  }
  
! static String PrintActions(buf, len, str, actions, translateData)
      String *buf;
      int *len;
      register String str;
      register ActionPtr actions;
!     XtTranslations translateData;
  {
+     StateTablePtr stateTable = translateData->stateTable;
      while (actions != NULL) {
  	String proc;
  	*str++ = ' ';
***************
*** 368,375 ****
  	} else {
  	    /* accelerator */
  	    int temp = -(actions->index+1);
! 	    if (stateTable->accProcTbl != NULL) {
! 		Widget w = stateTable->accProcTbl[temp].widget;
  		if (w != NULL) {
  		    String name = XtName(w);
  		    int nameLen = strlen(name);
--- 372,379 ----
  	} else {
  	    /* accelerator */
  	    int temp = -(actions->index+1);
! 	    if (translateData->accProcTbl != NULL) {
! 		Widget w = translateData->accProcTbl[temp].widget;
  		if (w != NULL) {
  		    String name = XtName(w);
  		    int nameLen = strlen(name);
***************
*** 600,606 ****
  }
  
  static int MatchEvent(translations, eventSeq) 
!   XtTranslations translations;
    register TMEventPtr eventSeq;
  {
      register EventObjPtr eventTbl = translations->eventObjTbl;
--- 604,610 ----
  }
  
  static int MatchEvent(translations, eventSeq) 
!   StateTablePtr translations;
    register TMEventPtr eventSeq;
  {
      register EventObjPtr eventTbl = translations->eventObjTbl;
***************
*** 620,630 ****
   * order"
   */
      for (i=0; i < translations->numEvents; i++) {
!         if (eventTbl[i].event.eventType ==
!                 (eventSeq->event.eventType /* & 0x7f */)
              && (eventTbl[i].event.matchEvent != NULL) 
!             && ((*eventTbl[i].event.matchEvent)(
!                        &eventTbl[i].event,eventSeq)))
                      return i;
              
      }    
--- 624,632 ----
   * order"
   */
      for (i=0; i < translations->numEvents; i++) {
!         if (eventTbl[i].event.eventType == eventSeq->event.eventType
              && (eventTbl[i].event.matchEvent != NULL) 
!             && ((*eventTbl[i].event.matchEvent)(&eventTbl[i].event, eventSeq)))
                      return i;
              
      }    
***************
*** 759,771 ****
  
  
  /* ARGSUSED */
! static void _XtTranslateEvent (w, closure, event, continue_to_dispatch)
      Widget w;
      XtPointer closure;		/* XtTM */
      register    XEvent * event;
      Boolean *continue_to_dispatch; /* unused */
  {
!     register XtTranslations stateTable = ((XtTM)closure)->translations;
      StatePtr oldState;
      TMEventRec curEvent;
      StatePtr current_state = ((XtTM)closure)->current_state;
--- 761,774 ----
  
  
  /* ARGSUSED */
! void _XtTranslateEvent (w, closure, event, continue_to_dispatch)
      Widget w;
      XtPointer closure;		/* XtTM */
      register    XEvent * event;
      Boolean *continue_to_dispatch; /* unused */
  {
!     XtTranslations translateData = ((XtTM)closure)->translations;
!     register StateTablePtr stateTable = translateData->stateTable;
      StatePtr oldState;
      TMEventRec curEvent;
      StatePtr current_state = ((XtTM)closure)->current_state;
***************
*** 772,790 ****
      int     index;
      register ActionPtr actions;
      XtBoundActions proc_table = ((XtTM)closure)->proc_table;
!     XtBoundAccActions accProcTbl = stateTable->accProcTbl;
      XtTM tm = (XtTM)closure;
      ActionHook actionHookList
  	= XtWidgetToApplicationContext(w)->action_hook_list;
  
- #ifdef notdef
- /* gross disgusting special case ||| */
-     if ((event->type == EnterNotify || event->type == LeaveNotify)
-         &&( event->xcrossing.detail == NotifyInferior
-         ||  event->xcrossing.mode != NotifyNormal) )
- 	return;
- #endif
- 
      XEventToTMEvent (event, &curEvent);
  
      if (stateTable == NULL) {
--- 775,785 ----
      int     index;
      register ActionPtr actions;
      XtBoundActions proc_table = ((XtTM)closure)->proc_table;
!     XtBoundAccActions accProcTbl = translateData->accProcTbl;
      XtTM tm = (XtTM)closure;
      ActionHook actionHookList
  	= XtWidgetToApplicationContext(w)->action_hook_list;
  
      XEventToTMEvent (event, &curEvent);
  
      if (stateTable == NULL) {
***************
*** 962,968 ****
  }
  
  static int GetEventIndex(stateTable, event)
!     XtTranslations stateTable;
      register EventPtr event;
  {
      register int	index;
--- 957,963 ----
  }
  
  static int GetEventIndex(stateTable, event)
!     StateTablePtr stateTable;
      register EventPtr event;
  {
      register int	index;
***************
*** 989,995 ****
  
  static StatePtr NewState(index, stateTable)
      int index;
!     XtTranslations stateTable;
  {
      register StatePtr state = XtNew(StateRec);
  
--- 984,990 ----
  
  static StatePtr NewState(index, stateTable)
      int index;
!     StateTablePtr stateTable;
  {
      register StatePtr state = XtNew(StateRec);
  
***************
*** 1008,1015 ****
      return state;
  }
  
! typedef NameValueRec CompiledAction;
! typedef NameValueTable CompiledActionTable;
  
  #ifdef lint
  Opaque _CompileActionTable(actions, count)
--- 1003,1013 ----
      return state;
  }
  
! typedef struct {
!     String	 name;
!     XrmQuark	 signature;
!     XtActionProc proc;
! } CompiledAction, *CompiledActionTable;
  
  #ifdef lint
  Opaque _CompileActionTable(actions, count)
***************
*** 1027,1039 ****
  
      for (i=0; i<count; i++) {
  	compiledActionTable[i].name = actions[i].string;
! 	compiledActionTable[i].signature = StringToAction(actions[i].string);
! 	compiledActionTable[i].value = (Value) actions[i].proc;
      }
  
      compiledActionTable[count].name = NULL;
      compiledActionTable[count].signature = NULL;
!     compiledActionTable[count].value = NULL;
  
  #ifdef lint
      return (Opaque) compiledActionTable;
--- 1025,1037 ----
  
      for (i=0; i<count; i++) {
  	compiledActionTable[i].name = actions[i].string;
! 	compiledActionTable[i].signature = StringToQuark(actions[i].string);
! 	compiledActionTable[i].proc = actions[i].proc;
      }
  
      compiledActionTable[count].name = NULL;
      compiledActionTable[count].signature = NULL;
!     compiledActionTable[count].proc = NULL;
  
  #ifdef lint
      return (Opaque) compiledActionTable;
***************
*** 1045,1051 ****
  static EventMask EventToMask(event)
      EventObjPtr	event;
  {
! static EventMask masks[] = {
          0,			    /* Error, should never see  */
          0,			    /* Reply, should never see  */
          KeyPressMask,		    /* KeyPress			*/
--- 1043,1049 ----
  static EventMask EventToMask(event)
      EventObjPtr	event;
  {
! static EventMask Const masks[] = {
          0,			    /* Error, should never see  */
          0,			    /* Reply, should never see  */
          KeyPressMask,		    /* KeyPress			*/
***************
*** 1138,1144 ****
      _XtTranslateEvent( widget, closure, (XEvent*)call_data, &bool );
  }
  
! 
  static void RemoveFromMappingCallbacks(widget, closure, call_data)
      Widget widget;
      XtPointer closure;		/* XtTM */
--- 1136,1143 ----
      _XtTranslateEvent( widget, closure, (XEvent*)call_data, &bool );
  }
  
!   
! /*ARGSUSED*/
  static void RemoveFromMappingCallbacks(widget, closure, call_data)
      Widget widget;
      XtPointer closure;		/* XtTM */
***************
*** 1153,1168 ****
  }
  
  
! void _XtInstallTranslations(widget, stateTable)
      Widget widget;
!     XtTranslations stateTable;
  {
      register EventMask	eventMask = 0;
      register Boolean	nonMaskable = FALSE;
      register Cardinal	i;
  
  /*    widget->core.translations = stateTable; */
!     if (stateTable == NULL) return;
  
      for (i = 0; i < stateTable->numEvents; i++) {
  	register EventMask mask = EventToMask(&stateTable->eventObjTbl[i]);
--- 1152,1169 ----
  }
  
  
! void _XtInstallTranslations(widget, translateData)
      Widget widget;
!     XtTranslations translateData;
  {
      register EventMask	eventMask = 0;
      register Boolean	nonMaskable = FALSE;
      register Cardinal	i;
+     StateTablePtr stateTable;
  
  /*    widget->core.translations = stateTable; */
!     if (translateData == NULL) return;
!     stateTable = translateData->stateTable;
  
      for (i = 0; i < stateTable->numEvents; i++) {
  	register EventMask mask = EventToMask(&stateTable->eventObjTbl[i]);
***************
*** 1204,1210 ****
  			   (XtPointer)&widget->core.tm
  			  );
      }
- 
  }
  
  void _XtRemoveTranslations(widget)
--- 1205,1210 ----
***************
*** 1214,1221 ****
  			 (XtPointer)&widget->core.tm);
  
      if ( widget->core.tm.translations &&
! 	 widget->core.tm.translations->mappingNotifyInterest)
  	RemoveFromMappingCallbacks(widget, (XtPointer)&widget->core.tm, NULL);
  }
  
  
--- 1214,1222 ----
  			 (XtPointer)&widget->core.tm);
  
      if ( widget->core.tm.translations &&
! 	 widget->core.tm.translations->stateTable->mappingNotifyInterest) {
  	RemoveFromMappingCallbacks(widget, (XtPointer)&widget->core.tm, NULL);
+     }
  }
  
  
***************
*** 1222,1235 ****
  
  /*** Public procedures ***/
  
  void XtUninstallTranslations(widget)
      Widget widget;
  {
      _XtRemoveTranslations(widget);
      widget->core.tm.translations = NULL;
!     if (widget->core.tm.proc_table != NULL)
          XtFree((char *)widget->core.tm.proc_table);
!     widget->core.tm.proc_table = NULL;
      widget->core.tm.current_state = NULL;
  }
  
--- 1223,1242 ----
  
  /*** Public procedures ***/
  
+ 
  void XtUninstallTranslations(widget)
      Widget widget;
  {
      _XtRemoveTranslations(widget);
+     if (widget->core.tm.translations &&
+ 	widget->core.tm.translations->accProcTbl) {
+ 	  XtFree((char*)widget->core.tm.translations);
+     }
      widget->core.tm.translations = NULL;
!     if (widget->core.tm.proc_table != NULL) {
          XtFree((char *)widget->core.tm.proc_table);
! 	widget->core.tm.proc_table = NULL;
!     }
      widget->core.tm.current_state = NULL;
  }
  
***************
*** 1242,1248 ****
  
  static void ReportUnboundActions(tm, stateTable)
      XtTM tm;
!     XtTranslations stateTable;
  {
      Cardinal num_unbound;
      char     message[10000];
--- 1249,1255 ----
  
  static void ReportUnboundActions(tm, stateTable)
      XtTM tm;
!     StateTablePtr stateTable;
  {
      Cardinal num_unbound;
      char     message[10000];
***************
*** 1277,1284 ****
      CompiledActionTable compiledActionTable;
      Cardinal *indexP;
  {
!     XtTranslations stateTable=tm->translations;
!     int unbound = stateTable->numQuarks;
      CompiledAction* action;
      Cardinal index;
      Boolean savedIndex = False;
--- 1284,1292 ----
      CompiledActionTable compiledActionTable;
      Cardinal *indexP;
  {
!     XtTranslations  translateData = tm->translations;
!     StateTablePtr   stateTable = translateData->stateTable;
!     int unbound = stateTable->numQuarks - *indexP;
      CompiledAction* action;
      Cardinal index;
      Boolean savedIndex = False;
***************
*** 1290,1296 ****
  	   Boolean found = False;
             for (action = compiledActionTable; action->name != NULL; action++) {
                 if (action->signature == q) {
! 		   tm->proc_table[index] = (XtActionProc)action->value;
                     unbound--;
  		   found = True;
                     break;
--- 1298,1304 ----
  	   Boolean found = False;
             for (action = compiledActionTable; action->name != NULL; action++) {
                 if (action->signature == q) {
! 		   tm->proc_table[index] = action->proc;
                     unbound--;
  		   found = True;
                     break;
***************
*** 1313,1324 ****
  static int BindAccActions(widget, stateTable, compiledActionTable,
  			  accBindings, indexP)
      Widget widget;
!     XtTranslations stateTable;
      CompiledActionTable compiledActionTable;
      XtBoundAccActions accBindings;
      Cardinal *indexP;
  {
!     int unbound = stateTable->accNumQuarks;
      int i;
      Cardinal index;
      Boolean savedIndex = False;
--- 1321,1332 ----
  static int BindAccActions(widget, stateTable, compiledActionTable,
  			  accBindings, indexP)
      Widget widget;
!     StateTablePtr stateTable;
      CompiledActionTable compiledActionTable;
      XtBoundAccActions accBindings;
      Cardinal *indexP;
  {
!     int unbound = stateTable->accNumQuarks - *indexP;
      int i;
      Cardinal index;
      Boolean savedIndex = False;
***************
*** 1330,1338 ****
  	   Boolean found = False;
             for (i = 0; compiledActionTable[i].name != NULL; i++) {
                 if (compiledActionTable[i].signature == q) {
!                    accBindings[index].widget =widget;
! 		   accBindings[index].proc=
!                      (XtActionProc) compiledActionTable[i].value;
                     unbound--;
  		   found = True;
                     break;
--- 1338,1345 ----
  	   Boolean found = False;
             for (i = 0; compiledActionTable[i].name != NULL; i++) {
                 if (compiledActionTable[i].signature == q) {
!                    accBindings[index].widget = widget;
! 		   accBindings[index].proc = compiledActionTable[i].proc;
                     unbound--;
  		   found = True;
                     break;
***************
*** 1355,1369 ****
      Widget widget;
      XtTM tm;
  {
!     XtTranslations  stateTable=tm->translations;
      register Widget	    w;
      register WidgetClass    class;
      register ActionList     actionList;
!     int unbound = -1; /* initialize to non-zero */
!     XtAppContext app;
!     Cardinal index = 0;
  
!     if (stateTable == NULL) return;
      tm->proc_table= (XtBoundActions) XtCalloc(
                        stateTable->numQuarks,(Cardinal)sizeof(XtBoundActions));
      w = widget;
--- 1362,1379 ----
      Widget widget;
      XtTM tm;
  {
!     XtTranslations  translateData = tm->translations;
!     StateTablePtr   stateTable;
      register Widget	    w;
      register WidgetClass    class;
      register ActionList     actionList;
!     int unbound;
!     Cardinal index;
  
!     if (translateData == NULL) return;
!     unbound = -1;
!     index = 0;
!     stateTable = translateData->stateTable;
      tm->proc_table= (XtBoundActions) XtCalloc(
                        stateTable->numQuarks,(Cardinal)sizeof(XtBoundActions));
      w = widget;
***************
*** 1381,1413 ****
      w = w->core.parent;
      } while (unbound != 0 && w != NULL);
  
!     app = XtWidgetToApplicationContext(widget);
!     for (actionList = app->action_table;
! 	 unbound != 0 && actionList != NULL;
! 	 actionList = actionList->next) {
! 	unbound = BindActions(tm, actionList->table, &index);
      }
!     if (unbound != 0) ReportUnboundActions(tm, stateTable);
  }
  
! static
! void _XtBindAccActions(widget, stateTable)
      Widget	    widget;
!     XtTranslations  stateTable;
  {
      register Widget	    w;
      register WidgetClass    class;
      register ActionList     actionList;
!     int unbound = -1; /* initialize to non-zero */
      XtBoundAccActions accTemp;
      XtAppContext app;
!     Cardinal index = 0;
  
      w = widget;
!     if (stateTable == NULL) return;
!     accTemp = (XtBoundAccActions) XtCalloc(
!                       stateTable->accNumQuarks,
! 		      (Cardinal)sizeof(XtBoundAccActionRec));
      do {
  	class = w->core.widget_class;
  	do {
--- 1391,1431 ----
      w = w->core.parent;
      } while (unbound != 0 && w != NULL);
  
!     if (unbound) {
! 	XtAppContext app = XtWidgetToApplicationContext(widget);
! 	for (actionList = app->action_table;
! 	     unbound != 0 && actionList != NULL;
! 	     actionList = actionList->next) {
! 	    unbound = BindActions(tm, actionList->table, &index);
! 	}
      }
!     if (unbound) ReportUnboundActions(tm, stateTable);
  }
  
! static XtTranslations _XtBindAccActions(widget, translateData)
      Widget	    widget;
!     XtTranslations  translateData;
  {
+     StateTablePtr stateTable = translateData->stateTable;
      register Widget	    w;
      register WidgetClass    class;
      register ActionList     actionList;
!     int unbound;
      XtBoundAccActions accTemp;
      XtAppContext app;
!     Cardinal index;
!     XtTranslations accTempTable;
  
      w = widget;
!     unbound = -1; /* initialize to non-zero */
!     index  = 0;
!     accTempTable = (XtTranslations) XtCalloc(
! 	     1,
!              (stateTable->accNumQuarks * (Cardinal)sizeof(XtBoundAccActionRec))
!               + sizeof(TranslationData));
!     accTemp = (XtBoundAccActions)(accTempTable + 1);
!     accTempTable->stateTable = stateTable;
!     accTempTable->accProcTbl = accTemp;
      do {
  	class = w->core.widget_class;
  	do {
***************
*** 1434,1440 ****
  				  &index);
      }
  /*    if (unbound != 0) ReportUnboundActions(tm, stateTable);*/
!     stateTable->accProcTbl = accTemp;
  }
  
  void XtAddActions(actions, num_actions)
--- 1452,1458 ----
  				  &index);
      }
  /*    if (unbound != 0) ReportUnboundActions(tm, stateTable);*/
!     return (accTempTable);
  }
  
  void XtAddActions(actions, num_actions)
***************
*** 1460,1468 ****
  void _XtInitializeStateTable(pStateTable)
      XtTranslations *pStateTable;
  {
!     register XtTranslations  stateTable;
  
!     (*pStateTable) = stateTable = XtNew(TranslationData);
      stateTable->operation = XtTableReplace;
      stateTable->numEvents = 0;
      stateTable->eventTblSize = 0;
--- 1478,1488 ----
  void _XtInitializeStateTable(pStateTable)
      XtTranslations *pStateTable;
  {
!     register StateTablePtr  stateTable;
  
!     (*pStateTable) = XtNew(TranslationData);
!     (*pStateTable)->stateTable = stateTable = XtNew(StateTableData);
!     (*pStateTable)->accProcTbl = NULL;
      stateTable->operation = XtTableReplace;
      stateTable->numEvents = 0;
      stateTable->eventTblSize = 0;
***************
*** 1474,1491 ****
      stateTable->numQuarks = 0;
      stateTable->accNumQuarks = 0;
      stateTable->accQuarkTable = NULL;
-     stateTable->accProcTbl= NULL;
      stateTable->accQuarkTblSize = 0;
      stateTable->mappingNotifyInterest = False;
  }
  
! void _XtAddEventSeqToStateTable(eventSeq, stateTable)
      register EventSeqPtr eventSeq;
!     XtTranslations stateTable;
  {
      register int     index;
      register StatePtr *state;
      EventSeqPtr initialEvent = eventSeq;
  
      if (eventSeq == NULL) return;
  
--- 1494,1511 ----
      stateTable->numQuarks = 0;
      stateTable->accNumQuarks = 0;
      stateTable->accQuarkTable = NULL;
      stateTable->accQuarkTblSize = 0;
      stateTable->mappingNotifyInterest = False;
  }
  
! void _XtAddEventSeqToStateTable(eventSeq, translateData)
      register EventSeqPtr eventSeq;
!     XtTranslations translateData;
  {
      register int     index;
      register StatePtr *state;
      EventSeqPtr initialEvent = eventSeq;
+     StateTablePtr stateTable = translateData->stateTable;
  
      if (eventSeq == NULL) return;
  
***************
*** 1528,1538 ****
  		    str = str - old + buf;
  		}
  		*str++ = ':';
! 		(void)PrintActions( &buf, &len, str, (*state)->actions, stateTable );
  		params[0] = buf;
  		XtWarningMsg (XtNtranslationError,"oldActions",XtCXtToolkitError,
  			      "Previous entry was: %s", params, &num_params);
! 		(void)PrintActions( &buf, &len, buf, eventSeq->actions, stateTable );
  		params[0] = buf;
  		XtWarningMsg (XtNtranslationError,"newActions",XtCXtToolkitError,
  			      "New actions are:%s", params, &num_params);
--- 1548,1558 ----
  		    str = str - old + buf;
  		}
  		*str++ = ':';
! 		(void)PrintActions( &buf, &len, str, (*state)->actions, translateData);
  		params[0] = buf;
  		XtWarningMsg (XtNtranslationError,"oldActions",XtCXtToolkitError,
  			      "Previous entry was: %s", params, &num_params);
! 		(void)PrintActions( &buf, &len, buf, eventSeq->actions, translateData);
  		params[0] = buf;
  		XtWarningMsg (XtNtranslationError,"newActions",XtCXtToolkitError,
  			      "New actions are:%s", params, &num_params);
***************
*** 1586,1592 ****
      register StatePtr *old, new;
      Boolean override;
      Cardinal *indexMap, *quarkIndexMap,*accQuarkIndexMap;
!     XtTranslations oldTable;
      StateMap stateMap;
  {
      register StatePtr state;
--- 1606,1612 ----
      register StatePtr *old, new;
      Boolean override;
      Cardinal *indexMap, *quarkIndexMap,*accQuarkIndexMap;
!     StateTablePtr oldTable;
      StateMap stateMap;
  {
      register StatePtr state;
***************
*** 1682,1693 ****
  }
  
  
! static void MergeTables(old, new, override,accProcTbl)
!     register XtTranslations old, new;
      Boolean override;
-     XtBoundAccActions accProcTbl;
  {
!     register Cardinal i,j,k;
      Cardinal *indexMap,*quarkIndexMap,*accQuarkIndexMap;
  
      if (new == NULL) return;
--- 1702,1712 ----
  }
  
  
! static void MergeTables(old, new, override)
!     register StateTablePtr old, new;
      Boolean override;
  {
!     register Cardinal i,j;
      Cardinal *indexMap,*quarkIndexMap,*accQuarkIndexMap;
  
      if (new == NULL) return;
***************
*** 1759,1765 ****
  /* merge accelerator quark tables */
    accQuarkIndexMap = (Cardinal *)XtCalloc(
        new->accQuarkTblSize, (Cardinal)sizeof(Cardinal));
-     k = old->accNumQuarks;
  
      for (i=0,j=old->accNumQuarks; i < new->accNumQuarks; ) {
          if (j == old->accQuarkTblSize) {
--- 1778,1783 ----
***************
*** 1773,1792 ****
           accQuarkIndexMap[i++] = j++;
      }
  
! /* merge accelerator action bindings */
  
-     if (old->accProcTbl == NULL) {
-         old->accProcTbl = (XtBoundAccActionRec*)XtCalloc(
-             old->accQuarkTblSize,(Cardinal)sizeof(XtBoundAccActionRec) );
-     }
-     else old->accProcTbl = (XtBoundAccActionRec*)XtRealloc(
-         (char *)old->accProcTbl,
- 	old->accQuarkTblSize*sizeof(XtBoundAccActionRec) );
-     for (i=0/*,k=k*/;i<new->accNumQuarks;){
-         old->accProcTbl[k].widget = accProcTbl[i].widget;
-         old->accProcTbl[k++].proc = accProcTbl[i++].proc;
-     }
- 
      for (i=0; i < new->numEvents; i++)
  	MergeStates(
  	    &old->eventObjTbl[indexMap[i]].state,
--- 1791,1798 ----
           accQuarkIndexMap[i++] = j++;
      }
  
! /* merge state tables */
  
      for (i=0; i < new->numEvents; i++)
  	MergeStates(
  	    &old->eventObjTbl[indexMap[i]].state,
***************
*** 1812,1818 ****
      XrmValuePtr from,to;
      XtPointer	*closure_ret;
  {
!     XtTranslations old, new, merged;
      TMkind operation;
  
      if (*num_args != 0)
--- 1818,1825 ----
      XrmValuePtr from,to;
      XtPointer	*closure_ret;
  {
!     StateTablePtr old, new;
!     XtTranslations merged;
      TMkind operation;
  
      if (*num_args != 0)
***************
*** 1829,1852 ****
      new = ((TMConvertRec*)from->addr)->new;
      operation = ((TMConvertRec*)from->addr)->operation;
  
!     if (old == NULL)
  #ifdef REFCNT_TRANSLATIONS
-     {
  	_XtInitializeStateTable(&merged);
! 	MergeTables(merged, new, FALSE, new->accProcTbl);
!     }
  #else
! 	merged = new;
  #endif
      else {
  	_XtInitializeStateTable(&merged);
  	if (operation == override) {
! 	    MergeTables(merged, new, FALSE, new->accProcTbl);
! 	    MergeTables(merged, old, FALSE, old->accProcTbl);
  	}
  	else if (operation == augment) {
! 	    MergeTables(merged, old, FALSE, old->accProcTbl);
! 	    MergeTables(merged, new, FALSE, new->accProcTbl);
  	}
      }
  
--- 1836,1861 ----
      new = ((TMConvertRec*)from->addr)->new;
      operation = ((TMConvertRec*)from->addr)->operation;
  
! 
!     if (old == NULL) {
  #ifdef REFCNT_TRANSLATIONS
  	_XtInitializeStateTable(&merged);
! 	MergeTables(merged->stateTable, new, FALSE);
  #else
! 	merged = XtNew(TranslationData);
! 	merged->stateTable = new;
! 	merged->accProcTbl = NULL;
  #endif
+     }
      else {
  	_XtInitializeStateTable(&merged);
  	if (operation == override) {
! 	    MergeTables(merged->stateTable, new, FALSE);
! 	    MergeTables(merged->stateTable, old, FALSE);
  	}
  	else if (operation == augment) {
! 	    MergeTables(merged->stateTable, old, FALSE);
! 	    MergeTables(merged->stateTable, new, FALSE);
  	}
      }
  
***************
*** 1862,1901 ****
      return True;
  }
  
! void XtOverrideTranslations(widget, new)
!     Widget widget;
!     XtTranslations new;
  {
! /*
!     MergeTables(widget->core.translations, new, TRUE);
! */
!     XrmValue from,to;
!     TMConvertRec foo;
      XtTranslations newTable;
      XtCacheRef cache_ref;
!     from.addr = (XtPointer)&foo;
      from.size = sizeof(TMConvertRec);
!     foo.old = widget->core.tm.translations;
!     foo.new = new;
!     foo.operation = override;
!     to.addr = (XtPointer)&newTable;
      to.size = sizeof(XtTranslations);
!     if ( ! XtCallConverter( XtDisplay(widget), _XtCvtMergeTranslations,
  			    (XrmValuePtr)NULL, (Cardinal)0, &from, &to,
! 			    &cache_ref ))
  	return;
  
      if (XtIsRealized(widget)) {
! 	   XtUninstallTranslations(widget);
             widget->core.tm.translations = newTable;
             _XtBindActions(widget, &widget->core.tm);
             _XtInstallTranslations(widget,newTable);
      }
!     else widget->core.tm.translations = newTable;
! 
!     if (cache_ref != NULL) {
! 	XtAddCallback( widget, XtNdestroyCallback,
! 		       XtCallbackReleaseCacheRef, (XtPointer)cache_ref );
      }
  }
  
--- 1871,2030 ----
      return True;
  }
  
! static void MergeAccProcTbls (mergedT, oldT, newT)
!     XtTranslations* mergedT;
!     XtTranslations oldT;
!     XtTranslations newT;
  {
!     StateTablePtr stateTable = (*mergedT)->stateTable;
!     XtBoundAccActions accProcTbl;
!     int i;
! 
!     if (stateTable->accNumQuarks == 0) return;
!     if (oldT == NULL && newT == NULL) return;
!     *mergedT = (XtTranslations)XtMalloc(
! 	     (stateTable->accNumQuarks * (Cardinal)sizeof(XtBoundAccActionRec))
! 	      + sizeof(TranslationData));
!     (*mergedT)->stateTable = stateTable;
!     (*mergedT)->accProcTbl = accProcTbl = (XtBoundAccActions)(*mergedT + 1);
!     if (oldT) {
! 	XtBoundAccActions opt = oldT->accProcTbl;
! 	for (i = oldT->stateTable->accNumQuarks; i; i--){
! 	    accProcTbl	 ->widget = opt	  ->widget;
! 	    accProcTbl++ ->proc	  = opt++ ->proc;
! 	}
!     }
!     if (newT) {
! 	XtBoundAccActions npt = newT->accProcTbl;
! 	for (i = newT->stateTable->accNumQuarks; i; i--){
! 	    accProcTbl	 ->widget = npt	  ->widget;
! 	    accProcTbl++ ->proc	  = npt++ ->proc;
! 	}
!     }
! }    
! 
! static XtTranslations
! ConvertATranslation(widget, new_translations, operation, acceleratorSource)
! Widget widget;
! XtTranslations new_translations;
! TMkind operation;
! Widget acceleratorSource; /* Non-NULL if new_translations are an unbound 
! 			       accelerator table */
! {
!     XrmValue from, to;
!     TMConvertRec convert_rec;
      XtTranslations newTable;
      XtCacheRef cache_ref;
!     ConverterTable table =XtWidgetToApplicationContext(widget)->converterTable;
!     ConverterPtr cP;
!     Boolean        free_bound_translations = FALSE;
! 
!     static XrmQuark from_type = NULLQUARK, to_type;
! 
!     if (from_type == NULLQUARK) {
! 	from_type = XrmStringToRepresentation(_XtRStateTablePair);
! 	to_type = XrmStringToRepresentation(XtRTranslationTable);
!     }
! 
!     from.addr = (XtPointer)&convert_rec;
      from.size = sizeof(TMConvertRec);
!     convert_rec.old = widget->core.tm.translations
! 			? widget->core.tm.translations->stateTable
! 			: NULL;
!     convert_rec.new = new_translations->stateTable;
!     convert_rec.operation = operation;
!     to.addr = (XtPointer) &newTable;
      to.size = sizeof(XtTranslations);
! 
!     cP = table[ProcHash(from_type, to_type) & CONVERTHASHMASK];
!     
!     if ( ! _XtCallConverter( XtDisplay(widget), _XtCvtMergeTranslations,
  			    (XrmValuePtr)NULL, (Cardinal)0, &from, &to,
! 			    &cache_ref, cP ))
! 	return(NULL);
! 
!     /*
!      *  If the new translations are an unbound accelerator table,
!      *  bind it now
!      */
!     if (acceleratorSource && new_translations) {
! 	new_translations =
! 	    _XtBindAccActions( acceleratorSource, new_translations );
! 	free_bound_translations = TRUE;
!     }
! 
!     /*
!      *  If either translation table has an accProcTbl, merge the
!      *  accProcTbls
!      */
!     if (operation == augment)
!         MergeAccProcTbls (&newTable,
! 		          widget->core.tm.translations,
!         	          new_translations);
!     else /* operation == override */
!         MergeAccProcTbls (&newTable,
!         	          new_translations,
! 		          widget->core.tm.translations);
! 
!     /*
!      *  Free the TranslationData of bound translations if it is not needed
!      */
!     if (free_bound_translations && new_translations != newTable)
! 	XtFree ((char*)new_translations);
! 
!     if (cache_ref != NULL) {
! 	XtAddCallback( widget, XtNdestroyCallback,
! 		       XtCallbackReleaseCacheRef, (XtPointer)cache_ref );
!     }
! 
!     return(newTable);
! }
! 
! /*
!  * Return a copy of the translation table if it contains a bound
!  * action proc table, else return the original.
!  */
! XtTranslations _XtCondCopyTranslations(translations)
!     XtTranslations translations;
! {
!     XtTranslations copy;
!     Cardinal size;
! 
!     if (translations == NULL || translations->accProcTbl == NULL)
! 	return translations;
!     
!     size = translations->stateTable->
! 	accNumQuarks * sizeof(XtBoundAccActionRec);
! 
!     copy = (XtTranslations)XtMalloc(size + sizeof(TranslationData));
!     copy->stateTable = translations->stateTable;
!     copy->accProcTbl = (XtBoundAccActions)(copy + 1);
!     bcopy(translations->accProcTbl, copy->accProcTbl, size);
!     return copy;
! }
! 
! void XtOverrideTranslations(widget, new)
!     Widget widget;
!     XtTranslations new;
! {
!     XtTranslations newTable = ConvertATranslation(widget, new, override, NULL);
! 
!     if (newTable == NULL) 
  	return;
  
      if (XtIsRealized(widget)) {
!            XtUninstallTranslations(widget);
             widget->core.tm.translations = newTable;
             _XtBindActions(widget, &widget->core.tm);
             _XtInstallTranslations(widget,newTable);
+ 	   _XtRegisterGrabs(widget, False);
      }
!     else {
! 	if (widget->core.tm.translations &&
! 	    widget->core.tm.translations->accProcTbl) {
! 	      XtFree((char*)widget->core.tm.translations);
! 	}
! 	widget->core.tm.translations = newTable;
      }
  }
  
***************
*** 1907,1913 ****
      XrmValuePtr	args;
      Cardinal	*num_args;
  {
!     XtTranslations stateTable;
      register StatePtr state;
      register EventObjPtr eventObj;
      register int i;
--- 2036,2043 ----
      XrmValuePtr	args;
      Cardinal	*num_args;
  {
!     XtTranslations translateData;
!     StateTablePtr stateTable;
      register StatePtr state;
      register EventObjPtr eventObj;
      register int i;
***************
*** 1919,1925 ****
            "Freeing XtTranslations requires no extra arguments",
  	  (String *)NULL, (Cardinal *)NULL);
  
!     stateTable = *(XtTranslations*)toVal->addr;
      for (i = stateTable->numEvents, eventObj = stateTable->eventObjTbl; i;) {
  	XtFree( (char*)eventObj->event.lateModifiers );
  	i--; eventObj++;
--- 2049,2056 ----
            "Freeing XtTranslations requires no extra arguments",
  	  (String *)NULL, (Cardinal *)NULL);
  
!     translateData = *(XtTranslations*)toVal->addr;
!     stateTable = translateData->stateTable;
      for (i = stateTable->numEvents, eventObj = stateTable->eventObjTbl; i;) {
  	XtFree( (char*)eventObj->event.lateModifiers );
  	i--; eventObj++;
***************
*** 1927,1935 ****
      XtFree( (char*)stateTable->eventObjTbl );
      XtFree( (char*)stateTable->quarkTable );
      XtFree( (char*)stateTable->accQuarkTable );
-     XtFree( (char*)stateTable->accProcTbl );
      for (state = stateTable->head; state;) {
! 	register StatePtr nextState = state->forw;
  	for (action = state->actions; action;) {
  	    ActionPtr nextAction = action->next;
  	    for (i = action->num_params; i;) {
--- 2058,2066 ----
      XtFree( (char*)stateTable->eventObjTbl );
      XtFree( (char*)stateTable->quarkTable );
      XtFree( (char*)stateTable->accQuarkTable );
      for (state = stateTable->head; state;) {
! 	register StatePtr nextState;
! 	nextState = state->forw;
  	for (action = state->actions; action;) {
  	    ActionPtr nextAction = action->next;
  	    for (i = action->num_params; i;) {
***************
*** 1941,1946 ****
--- 2072,2079 ----
  	XtFree( (char*)state );
  	state = nextState;
      }
+     XtFree( (char*)stateTable);
+     XtFree( (char*)translateData);
  }
  
  /* ARGSUSED */
***************
*** 1950,1958 ****
  {
      int i;
      XtTranslations table = (XtTranslations)closure;
      if (table == NULL) {
          XtAppWarningMsg(XtWidgetToApplicationContext(widget),
! 		XtNtranslationError,"nullTable",XtCXtToolkitError,
              "Can't remove accelerators from NULL table",
              (String *)NULL, (Cardinal *)NULL);
          return;
--- 2083,2092 ----
  {
      int i;
      XtTranslations table = (XtTranslations)closure;
+     StateTablePtr stateTable = table->stateTable;
      if (table == NULL) {
          XtAppWarningMsg(XtWidgetToApplicationContext(widget),
!             XtNtranslationError,"nullTable",XtCXtToolkitError,
              "Can't remove accelerators from NULL table",
              (String *)NULL, (Cardinal *)NULL);
          return;
***************
*** 1959,1970 ****
      }
      if (table->accProcTbl == NULL) {
          XtAppWarningMsg(XtWidgetToApplicationContext(widget),
! 		XtNtranslationError,"nullTable",XtCXtToolkitError,
              "Tried to remove non-existant accelerators",
              (String *)NULL, (Cardinal *)NULL);
          return;
      }
!     for (i=0;i<table->accNumQuarks;i++) {
          if (table->accProcTbl[i].widget == widget)
              table->accProcTbl[i].widget = 0;
      }
--- 2093,2104 ----
      }
      if (table->accProcTbl == NULL) {
          XtAppWarningMsg(XtWidgetToApplicationContext(widget),
!             XtNtranslationError,"nullTable",XtCXtToolkitError,
              "Tried to remove non-existant accelerators",
              (String *)NULL, (Cardinal *)NULL);
          return;
      }
!     for (i=0;i<stateTable->accNumQuarks;i++) {
          if (table->accProcTbl[i].widget == widget)
              table->accProcTbl[i].widget = 0;
      }
***************
*** 1975,2022 ****
  void XtInstallAccelerators(destination, source)
      Widget destination, source;
  {
      if ((!XtIsWidget(source)) || source->core.accelerators == NULL) return;
! /*    if (source->core.accelerators->accProcTbl == NULL)
!  *  %%%
!  *  The spec is not clear on when actions specified in accelerators are bound;
   *  The most useful (and easiest) thing seems to be to bind them at this time
!  *  (rather than at Realize).  Under the current code the preceeding test
!  *  seems always to be True, thus guaranteeing accBindings is always set
!  *  before being used below.
   */
!         _XtBindAccActions( source, source->core.accelerators );
      if (destination->core.tm.translations == NULL)
! 	destination->core.tm.translations = source->core.accelerators;
      else {
! 	XrmValue from, to;
! 	TMConvertRec cvt;
! 	XtCacheRef cache_ref;
! 	XtTranslations temp;
! 	from.addr = (XtPointer)&cvt;
! 	from.size = sizeof(TMConvertRec);
! 	cvt.old = destination->core.tm.translations;
! 	cvt.new = source->core.accelerators;
! 	to.addr = (XtPointer)&temp;
! 	to.size = sizeof(XtTranslations);
! 	if (source->core.accelerators->operation == XtTableOverride)
! 	    cvt.operation = override;
! 	else
! 	    cvt.operation = augment;
! 	if ( ! XtCallConverter( XtDisplay(destination),
! 			        _XtCvtMergeTranslations,
! 			        (XrmValue*)NULL, (Cardinal)0, &from, &to,
! 			        &cache_ref )) {
  	    return;
! 	}
! 	destination->core.tm.translations = temp;
! 	if (cache_ref != NULL) {
! 	    XtAddCallback( destination, XtNdestroyCallback,
! 			   XtCallbackReleaseCacheRef, (XtPointer)cache_ref );
! 	}
      }
!     if (XtIsRealized(destination))
!         _XtInstallTranslations(destination,
!              destination->core.tm.translations);
      XtAddCallback(source, XtNdestroyCallback,
          RemoveAccelerators,(XtPointer)destination->core.tm.translations);
      if (XtClass(source)->core_class.display_accelerator != NULL){
--- 2109,2151 ----
  void XtInstallAccelerators(destination, source)
      Widget destination, source;
  {
+     StateTablePtr stateTable;
      if ((!XtIsWidget(source)) || source->core.accelerators == NULL) return;
! 
! /*  The spec is not clear on when actions specified in accelerators are bound;
   *  The most useful (and easiest) thing seems to be to bind them at this time
!  *  (rather than at Realize).
   */
! 
!     stateTable = source->core.accelerators->stateTable;
      if (destination->core.tm.translations == NULL)
! 	destination->core.tm.translations =
! 	    _XtBindAccActions( source, source->core.accelerators );
      else {
! 	XtTranslations new_table;
! 	TMkind operation;
! 
!   	if (stateTable->operation == XtTableOverride)
! 	    operation = override;
!   	else
! 	    operation = augment;
! 	
! 	new_table = ConvertATranslation(destination, 
! 					source->core.accelerators, operation,
! 					source);
! 	if (new_table == NULL)
  	    return;
! 
! 	if (destination->core.tm.translations->accProcTbl)
! 	    XtFree((char*)destination->core.tm.translations);
! 
! 	destination->core.tm.translations = new_table;
      }
!     if (XtIsRealized(destination)) {
! 	_XtInstallTranslations(destination, destination->core.tm.translations);
! 	_XtRegisterGrabs(destination, True);
!     }
! 
      XtAddCallback(source, XtNdestroyCallback,
          RemoveAccelerators,(XtPointer)destination->core.tm.translations);
      if (XtClass(source)->core_class.display_accelerator != NULL){
***************
*** 2025,2032 ****
  	 String str = buf;
  	 int i;
           *str = '\0';
! 	 for (i = 0; i < source->core.accelerators->numEvents; i++) {
! 	     StatePtr state = source->core.accelerators->eventObjTbl[i].state;
  	     if (state != NULL) {
  		 if (str != buf) *str++ = '\n';
  		 str = PrintState( &buf, &len, str, str-buf, state,
--- 2154,2161 ----
  	 String str = buf;
  	 int i;
           *str = '\0';
! 	 for (i = 0; i < stateTable->numEvents; i++) {
! 	     StatePtr state = stateTable->eventObjTbl[i].state;
  	     if (state != NULL) {
  		 if (str != buf) *str++ = '\n';
  		 str = PrintState( &buf, &len, str, str-buf, state,
***************
*** 2068,2100 ****
      Widget widget;
      XtTranslations new;
  {
!     XrmValue from,to;
!     TMConvertRec foo;
!     XtTranslations newTable;
!     XtCacheRef cache_ref;
!     from.addr = (XtPointer)&foo;
!     from.size = sizeof(TMConvertRec);
!     foo.old = widget->core.tm.translations;
!     foo.new = new;
!     foo.operation = augment;
!     to.addr = (XtPointer)&newTable;
!     to.size = sizeof(XtTranslations);
!     if ( ! XtCallConverter( XtDisplay(widget), _XtCvtMergeTranslations,
! 			    (XrmValue*)NULL, (Cardinal)0, &from, &to,
! 			    &cache_ref ))
  	return;
  
      if (XtIsRealized(widget)) {
!         XtUninstallTranslations((Widget)widget);
!         widget->core.tm.translations = newTable;
!         _XtBindActions(widget,&widget->core.tm);
!         _XtInstallTranslations(widget,newTable);
      }
!     else widget->core.tm.translations = newTable;
! 
!     if (cache_ref != NULL) {
! 	XtAddCallback( widget, XtNdestroyCallback,
! 		       XtCallbackReleaseCacheRef, (XtPointer)cache_ref );
      }
  }
  
--- 2197,2220 ----
      Widget widget;
      XtTranslations new;
  {
!     XtTranslations newTable = ConvertATranslation(widget, new, augment, NULL);
! 
!     if (newTable == NULL) 
  	return;
  
      if (XtIsRealized(widget)) {
!  	   XtUninstallTranslations(widget);
!            widget->core.tm.translations = newTable;
!            _XtBindActions(widget, &widget->core.tm);
!            _XtInstallTranslations(widget,newTable);
! 	   _XtRegisterGrabs(widget, False);
      }
!     else {
! 	if (widget->core.tm.translations &&
! 	    widget->core.tm.translations->accProcTbl) {
! 	      XtFree((char*)widget->core.tm.translations);
! 	}
! 	widget->core.tm.translations = newTable;
      }
  }
  
***************
*** 2143,2166 ****
      return False;
  }
  
! static String PrintState(buf, len, str, start, state, stateTable, dpy)
      String *buf;
      int *len;
      register String str;
      int start;			/* offset of current LHS; -1 =>print *buf */
      StatePtr state;
!     XtTranslations stateTable;
      Display *dpy;
  {
!     int oldOffset = str - *buf;
      int clickCount;
      Boolean cycle;
      StatePtr nextLevel;
      StatePtr sameLevel;
  
      /* print the current state */
      if (state == NULL) return str;
  
      sameLevel = state->next;
      str = PrintEvent( buf, len, str,
  		      &stateTable->eventObjTbl[state->index].event,
--- 2263,2289 ----
      return False;
  }
  
! static String PrintState(buf, len, str, start, state, translateData, dpy)
      String *buf;
      int *len;
      register String str;
      int start;			/* offset of current LHS; -1 =>print *buf */
      StatePtr state;
!     XtTranslations translateData;
      Display *dpy;
  {
!     int oldOffset;
      int clickCount;
      Boolean cycle;
      StatePtr nextLevel;
      StatePtr sameLevel;
+     StateTablePtr stateTable;
  
      /* print the current state */
      if (state == NULL) return str;
  
+     oldOffset = str - *buf;
+     stateTable = translateData->stateTable;
      sameLevel = state->next;
      str = PrintEvent( buf, len, str,
  		      &stateTable->eventObjTbl[state->index].event,
***************
*** 2185,2191 ****
  	    int offset = str - *buf;
  	    CHECK_STR_OVERFLOW;
  	    *str++ = ':';
! 	    (void) PrintActions(buf, len, str, state->actions, stateTable);
  	    (void) printf("%s\n", *buf);
  	    str = *buf + offset;
  	}
--- 2308,2314 ----
  	    int offset = str - *buf;
  	    CHECK_STR_OVERFLOW;
  	    *str++ = ':';
! 	    (void) PrintActions(buf, len, str, state->actions, translateData);
  	    (void) printf("%s\n", *buf);
  	    str = *buf + offset;
  	}
***************
*** 2202,2209 ****
  	    bcopy( *buf+start, str, oldOffset - start );
  	    str += oldOffset - start;
      	}
! 	str = PrintState( buf, len, str, start, state->nextLevel,
! 			  stateTable, dpy );
      }
  
      if (sameLevel != NULL) {	/* print sibling states */
--- 2325,2332 ----
  	    bcopy( *buf+start, str, oldOffset - start );
  	    str += oldOffset - start;
      	}
! 	str = PrintState( buf, len, str, start,
! 			  state->nextLevel, translateData, dpy );
      }
  
      if (sameLevel != NULL) {	/* print sibling states */
***************
*** 2215,2221 ****
  	    bcopy( *buf+start, str, oldOffset - start );
  	    str += oldOffset - start;
  	}
! 	str = PrintState(buf, len, str, start, sameLevel, stateTable, dpy);
      }
  
      if (start == -1) str = *buf + oldOffset;
--- 2338,2344 ----
  	    bcopy( *buf+start, str, oldOffset - start );
  	    str += oldOffset - start;
  	}
! 	str = PrintState(buf, len, str, start, sameLevel, translateData, dpy);
      }
  
      if (start == -1) str = *buf + oldOffset;
***************
*** 2224,2237 ****
  }
  
  #ifndef NO_MIT_HACKS
! void _XtTranslateTablePrint(translations)
!     XtTranslations translations;
  {
      register Cardinal i;
      int len = 1000;
      char *buf;
  
!     if (translations == NULL) return;
      buf = XtMalloc((Cardinal)1000);
      for (i = 0; i < translations->numEvents; i++) {
  	buf[0] = '\0';
--- 2347,2362 ----
  }
  
  #ifndef NO_MIT_HACKS
! void _XtTranslateTablePrint(translateData)
!     XtTranslations translateData;
  {
+     StateTablePtr translations;
      register Cardinal i;
      int len = 1000;
      char *buf;
  
!     if (translateData == NULL) return;
!     translations = translateData->stateTable;
      buf = XtMalloc((Cardinal)1000);
      for (i = 0; i < translations->numEvents; i++) {
  	buf[0] = '\0';
***************
*** 2241,2247 ****
  			   buf,
  			   -1,
  			   translations->eventObjTbl[i].state,
! 			   translations,
  			   NULL
  			 );
      }
--- 2366,2372 ----
  			   buf,
  			   -1,
  			   translations->eventObjTbl[i].state,
! 			   translateData,
  			   NULL
  			 );
      }
***************
*** 2277,2283 ****
  {
      Widget eventWidget
  	= XtWindowToWidget(event->xany.display, event->xany.window);
!     XtTranslations translations;
      register Cardinal i;
      int len = 1000;
      char *buf;
--- 2402,2409 ----
  {
      Widget eventWidget
  	= XtWindowToWidget(event->xany.display, event->xany.window);
!     XtTranslations translateData;
!     StateTablePtr  translations;
      register Cardinal i;
      int len = 1000;
      char *buf;
***************
*** 2284,2290 ****
  
      if (eventWidget == NULL) return;
  
!     if ((translations = eventWidget->core.tm.translations) == NULL) return;
      buf = XtMalloc((Cardinal)1000);
      for (i = 0; i < translations->numEvents; i++) {
  	register ActionPtr actions
--- 2410,2417 ----
  
      if (eventWidget == NULL) return;
  
!     if ((translateData = eventWidget->core.tm.translations) == NULL) return;
!     translations = translateData->stateTable;
      buf = XtMalloc((Cardinal)1000);
      for (i = 0; i < translations->numEvents; i++) {
  	register ActionPtr actions
***************
*** 2299,2305 ****
  			       buf,
  			       -1,
  			       translations->eventObjTbl[i].state,
! 			       translations,
  			       XtDisplay(eventWidget)
  			     );
  	}
--- 2426,2432 ----
  			       buf,
  			       -1,
  			       translations->eventObjTbl[i].state,
! 			       translateData,
  			       XtDisplay(eventWidget)
  			     );
  	}
***************
*** 2467,2479 ****
      XtFree((XtPointer)keycodes);
  }
  
! void _XtRegisterGrabs(widget,tm)
      Widget widget;
!     XtTM  tm;
  {
!     XtTranslations stateTable=tm->translations;
!     unsigned int count;
  
      if (! XtIsRealized(widget)) return;
  
      /* walk the widget instance action bindings table looking for */
--- 2594,2665 ----
      XtFree((XtPointer)keycodes);
  }
  
! static void RegisterGrab(widget, stateTable, index, grabP)
      Widget widget;
!     StateTablePtr stateTable;
!     int index;
!     GrabActionRec* grabP;
  {
!     register StatePtr state;
!     /* we've found a "grabber" in the action table. Find the */
!     /* states that call this action. */
!     /* note that if there is more than one "grabber" in the action */
!     /* table, we end up searching all of the states multiple times. */
!     for (state=stateTable->head; state != NULL; state=state->forw) {
! 	register ActionPtr action;
! 	for (
! 	    action = state->actions;
! 	    action != NULL;
! 	    action=action->next) {
! 	    if (action->index == index) {
! 		/* this action is a "grabber" */
! 		register Event *event;
! 		event = &stateTable->eventObjTbl[state->index].event;
! 		switch (event->eventType) {
! 		    case ButtonPress:
! 		    case ButtonRelease:
! 			XtGrabButton(
! 			    widget,
! 			    (unsigned) event->eventCode,
! 			    (unsigned) event->modifiers,
! 			    grabP->owner_events,
! 			    grabP->event_mask,
! 			    grabP->pointer_mode,
! 			    grabP->keyboard_mode,
! 			    None,
! 			    None
! 			);
! 			break;
  
+ 		    case KeyPress:
+ 		    case KeyRelease:
+ 			GrabAllCorrectKeys(widget, event, grabP);
+ 			break;
+ 
+ 		    case EnterNotify:
+ 			break;
+ 
+ 		    default:
+       XtAppWarningMsg(XtWidgetToApplicationContext(widget),
+ 	    "invalidPopup","unsupportedOperation",XtCXtToolkitError,
+ "Pop-up menu creation is only supported on Button, Key or EnterNotify events.",
+ 	    (String *)NULL, (Cardinal *)NULL);
+ 		    break;
+ 		}
+ 	    }
+ 	}
+     }
+ }
+ 
+ 
+ void _XtRegisterGrabs(widget, acceleratorsOnly)
+     Widget widget;
+     Boolean acceleratorsOnly;
+ {
+     XtTranslations translateData = widget->core.tm.translations;
+     StateTablePtr stateTable;
+     int count;
+ 
      if (! XtIsRealized(widget)) return;
  
      /* walk the widget instance action bindings table looking for */
***************
*** 2480,2545 ****
      /* actions registered as grab actions. */
      /* when you find one, do a grab on the triggering event */
  
      if (stateTable == NULL) return;
!     for (count=0; count < stateTable->numQuarks; count++) {
        GrabActionRec* grabP;
        for (grabP = grabActionList; grabP != NULL; grabP = grabP->next) {
!         if (grabP->action_proc == tm->proc_table[count]) {
! 	    register StatePtr state;
! 	    /* we've found a "grabber" in the action table. Find the */
! 	    /* states that call this action. */
! 	    /* note that if there is more than one "grabber" in the action */
! 	    /* table, we end up searching all of the states multiple times. */
! 	    for (state=stateTable->head; state != NULL; state=state->forw) {
! 		register ActionPtr action;
! 	        for (
! 		    action = state->actions;
! 		    action != NULL;
! 		    action=action->next) {
! 		    if (action->index == count) {
! 			/* this action is a "grabber" */
! 			register Event *event;
! 			event = &stateTable->eventObjTbl[state->index].event;
! 			switch (event->eventType) {
! 			    case ButtonPress:
! 			    case ButtonRelease:
! 				XtGrabButton(
! 				    widget,
! 				    (unsigned) event->eventCode,
! 				    (unsigned) event->modifiers,
! 				    grabP->owner_events,
! 				    grabP->event_mask,
! 				    grabP->pointer_mode,
! 				    grabP->keyboard_mode,
! 				    None,
! 				    None
! 				);
! 				break;
! 	    
! 			    case KeyPress:
! 			    case KeyRelease:
! 				GrabAllCorrectKeys(widget, event, grabP);
! 				break;
! 	    
! 			    case EnterNotify:
! 				break;
! 
! 			    default:
!               XtAppWarningMsg(XtWidgetToApplicationContext(widget),
! 		    "invalidPopup","unsupportedOperation",XtCXtToolkitError,
! "Pop-up menu creation is only supported on Button, Key or EnterNotify events.",
!                   (String *)NULL, (Cardinal *)NULL);
! 			    break;
! 			}
! 		    }
! 		}
! 	    }
  	}
        }
      }
  }
  
! static XtActionsRec tmActions[] = {
      {"XtMenuPopup", XtMenuPopupAction},
      {"XtMenuPopdown", _XtMenuPopdownAction},
      {"MenuPopup", XtMenuPopupAction}, /* old & obsolete */
--- 2666,2695 ----
      /* actions registered as grab actions. */
      /* when you find one, do a grab on the triggering event */
  
+     if (translateData == NULL) return;
+     stateTable = translateData->stateTable;
      if (stateTable == NULL) return;
!     if (!acceleratorsOnly) {
! 	for (count=0; count < stateTable->numQuarks; count++) {
! 	  GrabActionRec* grabP;
! 	  for (grabP = grabActionList; grabP != NULL; grabP = grabP->next) {
! 	    if (grabP->action_proc == widget->core.tm.proc_table[count]) {
! 		RegisterGrab(widget, stateTable, count, grabP);
! 	    }
! 	  }
! 	}
!     }
!     for (count=0; count < stateTable->accNumQuarks; count++) {
        GrabActionRec* grabP;
        for (grabP = grabActionList; grabP != NULL; grabP = grabP->next) {
!         if (grabP->action_proc == translateData->accProcTbl[count].proc) {
! 	    RegisterGrab(widget, stateTable, -(count+1), grabP);
  	}
        }
      }
  }
  
! static XtActionsRec Const tmActions[] = {
      {"XtMenuPopup", XtMenuPopupAction},
      {"XtMenuPopdown", _XtMenuPopdownAction},
      {"MenuPopup", XtMenuPopupAction}, /* old & obsolete */
***************
*** 2555,2561 ****
  void _XtPopupInitialize(app)
      XtAppContext app;
  {
!     XtAppAddActions(app, tmActions, XtNumber(tmActions));
      if (grabActionList == NULL)
  	XtRegisterGrabAction( XtMenuPopupAction, True,
  			      (unsigned)(ButtonPressMask | ButtonReleaseMask),
--- 2705,2711 ----
  void _XtPopupInitialize(app)
      XtAppContext app;
  {
!     XtAppAddActions(app, (XtActionList) tmActions, XtNumber(tmActions));
      if (grabActionList == NULL)
  	XtRegisterGrabAction( XtMenuPopupAction, True,
  			      (unsigned)(ButtonPressMask | ButtonReleaseMask),
***************
*** 2710,2715 ****
--- 2860,2866 ----
  	    (*pd->defaultCaseConverter)(dpy, syms[0], &lsym, &usym);
  	*keysym_return = usym;
      }
+ 
      if (*keysym_return == XK_VoidSymbol)
  	*keysym_return = NoSymbol;
  }
***************
*** 2911,2918 ****
  				     );
  			hook= hook->next;
  		    }
! 		    (*(XtActionProc)(actionP->value))
! 			(widget, event, params, &num_params);
  		    return;
  		}
  	    }
--- 3062,3068 ----
  				     );
  			hook= hook->next;
  		    }
! 		    (*actionP->proc)(widget, event, params, &num_params);
  		    return;
  		}
  	    }
***************
*** 2938,2945 ****
  				 );
  		    hook= hook->next;
  		}
! 		(*(XtActionProc)(actionP->value))
! 		    (widget, event, params, &num_params);
  		return;
  	    }
  	}
--- 3088,3094 ----
  				 );
  		    hook= hook->next;
  		}
! 		(*actionP->proc)(widget, event, params, &num_params);
  		return;
  	    }
  	}
*** /tmp/,RCSt1a29727
--- mit/lib/Xt/TranslateI.h
***************
*** 1,5 ****
! /* $XConsortium: TranslateI.h,v 1.17 90/04/13 20:12:37 swick Exp $ */
! /* $oHeader: TranslateI.h,v 1.2 88/08/18 15:56:37 asente Exp $ */
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
  and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
--- 1,5 ----
! /* $XConsortium: TranslateI.h,v 1.23 90/07/13 07:35:51 swick Exp $ */
! 
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
  and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
***************
*** 36,41 ****
--- 36,43 ----
  /*#define REFCNT_TRANSLATIONS*/
  #define CACHE_TRANSLATIONS
  
+ #define _XtRStateTablePair "_XtStateTablePair"
+ 
  typedef Boolean (*MatchProc)();
    /* Event parsed;
       XEvent incoming;
***************
*** 68,79 ****
  
  typedef enum _TMkind {override,augment} TMkind;
  
- typedef struct _TMConvertRec {
-    XtTranslations old; /* table to merge into */
-    XtTranslations new; /* table to merge from */
-    TMkind  operation; /* merge or augment     */
- } TMConvertRec;
- 
  typedef struct _EventObjRec {
      Event event;	/* X event description */
      StatePtr state;	/* pointer to linked lists of state info */
--- 70,75 ----
***************
*** 98,109 ****
  }  StateRec;
  typedef enum {XtTableReplace,XtTableAugment,XtTableOverride} _XtTranslateOp;
  
! typedef struct _TranslationData {
      _XtTranslateOp	operation; /*replace,augment,override*/
      unsigned int	numEvents;
      unsigned int	eventTblSize;
      EventObjPtr		eventObjTbl;
-     unsigned long	lastEventTime;
      unsigned int	numQuarks;   /* # of entries in quarkTable */
      unsigned int	quarkTblSize; /*total size of quarkTable */
      XrmQuark*		quarkTable;  /* table of quarkified rhs*/
--- 94,104 ----
  }  StateRec;
  typedef enum {XtTableReplace,XtTableAugment,XtTableOverride} _XtTranslateOp;
  
! typedef struct _StateTableData {
      _XtTranslateOp	operation; /*replace,augment,override*/
      unsigned int	numEvents;
      unsigned int	eventTblSize;
      EventObjPtr		eventObjTbl;
      unsigned int	numQuarks;   /* # of entries in quarkTable */
      unsigned int	quarkTblSize; /*total size of quarkTable */
      XrmQuark*		quarkTable;  /* table of quarkified rhs*/
***************
*** 110,120 ****
      unsigned int	accNumQuarks;
      unsigned int	accQuarkTblSize;
      XrmQuark*		accQuarkTable;
-     struct _XtBoundAccActionRec* accProcTbl;
      StatePtr		head;	/* head of list of all states */
      Boolean		mappingNotifyInterest;
  } TranslationData;
  
  #define _XtEventTimerEventType ((unsigned long)-1L)
  #define KeysymModMask		(1<<27) /* private to TM */
  #define AnyButtonMask		(1<<28)	/* private to TM */
--- 105,130 ----
      unsigned int	accNumQuarks;
      unsigned int	accQuarkTblSize;
      XrmQuark*		accQuarkTable;
      StatePtr		head;	/* head of list of all states */
      Boolean		mappingNotifyInterest;
+ } StateTableData, *StateTablePtr;
+ 
+ typedef struct _XtBoundAccActionRec {
+     Widget widget;    /*widgetID to pass to action Proc*/
+     XtActionProc proc; /*action procedure */
+ } XtBoundAccActionRec;
+ 
+ typedef struct _TranslationData {
+     StateTablePtr	 stateTable;
+     XtBoundAccActionRec* accProcTbl;
  } TranslationData;
  
+ typedef struct _TMConvertRec {
+    StateTablePtr old; /* table to merge into */
+    StateTablePtr new; /* table to merge from */
+    TMkind  operation; /* merge or augment     */
+ } TMConvertRec;
+ 
  #define _XtEventTimerEventType ((unsigned long)-1L)
  #define KeysymModMask		(1<<27) /* private to TM */
  #define AnyButtonMask		(1<<28)	/* private to TM */
***************
*** 134,158 ****
      Event event;
  }TMEventRec,*TMEventPtr;
  
- typedef struct _XtBoundAccActionRec {
-     Widget widget;    /*widgetID to pass to action Proc*/
-     XtActionProc proc; /*action procedure */
- } XtBoundAccActionRec;
- 
- 
  extern void _XtAddEventSeqToStateTable();
  extern void _XtInitializeStateTable(); /* stateTable */
      /* _XtTranslations *stateTable; */
  
- typedef XrmQuark XtAction;
- 
- typedef unsigned int	Value;
- typedef struct {
-     char	*name;
-     XrmQuark	signature;
-     Value	value;
- } NameValueRec, *NameValueTable;
- 
  typedef struct _ActionHookRec {
      struct _ActionHookRec* next; /* must remain first */
      XtAppContext app;
--- 144,153 ----
***************
*** 189,198 ****
  extern XtTranslations _XtParseTranslationTable(); /* source */
      /* String source; */
  
! extern void _XtRegisterGrabs(); /* widget */
!     /* Widget widget; */
  
  extern void _XtPopup(); /* widget, grab_kind, spring_loaded */
      /* Widget      widget; */
      /* XtGrabKind  grab_kind; */
      /* Boolean     spring_loaded; */
--- 184,207 ----
  extern XtTranslations _XtParseTranslationTable(); /* source */
      /* String source; */
  
! extern void _XtRegisterGrabs(
! #if NeedFunctionPrototypes
!     Widget /* widget */,
! #if NeedWidePrototypes
!     int /* acceleratorsOnly */
! #else
!     Boolean /* acceleratorsOnly */
! #endif
! #endif
! );
  
  extern void _XtPopup(); /* widget, grab_kind, spring_loaded */
      /* Widget      widget; */
      /* XtGrabKind  grab_kind; */
      /* Boolean     spring_loaded; */
+ 
+ extern XtTranslations _XtCondCopyTranslations(
+ #if NeedFunctionPrototypes
+     XtTranslations	translations
+ #endif
+ );
