Path: utzoo!attcan!uunet!lll-winken!lll-tis!ames!mailrus!purdue!decwrl!hplabs!hp-pcd!hpcvlx!fred
From: fred@hpcvlx.HP.COM (Fred Taft)
Newsgroups: comp.windows.x
Subject: Re: HP's Xtk Fixes (as Context Diffs)
Message-ID: <1610049@hpcvlx.HP.COM>
Date: 19 Aug 88 19:52:36 GMT
References: <1610043@hpcvlx.HP.COM>
Organization: Hewlett-Packard Co., Corvallis, OR, USA
Lines: 350


### bug number:   363
### area:         Xt
### severity:     
### assigned to:  swick
### status:       open
### comments:     


VERSION:
	Xtk release 2

SYNOPSIS:
        Adding a global translation to a realized widget destroys the
        widget's translations.

DESCRIPTION:
	As I reported in an earlier bug report, if a new translation is
        added to a realized widget (using XtOverrideTranslation), and the
        action to which the translation is tied has not been previously used
        for that widget, all of the translations for that widget get
        destroyed.

REPEAT-BY:
        Register a global action routine, and set up a translation for a
        realized widget which uses this action.

FIX:
        There were actually several problems in the translation
        manager which contributed to this problem.  They include:

        1) After the first time a widget's translations were bound, the
           proc_table size was never again changed; even if future translations
           referenced different action routines.

        2) After an augment or override request, the translations were not
           really being rebound; this is a result of the table being the
           wrong size and the fact that only NULL table entries are bound,
           and none of the entries had been NULL'ed out.

        3) The old event handler for the widget was not removed.

        4) The new translations were never installed.
        
*************************** diffs start here *******************************

*** TMstate.c	Fri Aug 19 12:19:50 1988
--- TMstate.new.c	Fri Aug 19 12:18:02 1988
***************
*** 725,730
  if (tm->proc_table == NULL) 
      tm->proc_table= (XtActionProc*) XtCalloc(
                        stateTable->numQuarks,sizeof(XtActionProc));
  do {
  /* ||| */
      class = w->core.widget_class;

--- 725,731 -----
  if (tm->proc_table == NULL) 
      tm->proc_table= (XtActionProc*) XtCalloc(
                        stateTable->numQuarks,sizeof(XtActionProc));
+ 
  do {
  /* ||| */
      class = w->core.widget_class;
***************
*** 1040,1046
      /* merge in extra bindings, keeping old binding if any */
      XtTranslations temp;
      _XtInitializeStateTable(&temp);
!     temp->clickTime = old->clickTime;
      MergeTables(temp, old, FALSE);
      MergeTables(temp, new, FALSE);
      *merged= temp;

--- 1041,1048 -----
      /* merge in extra bindings, keeping old binding if any */
      XtTranslations temp;
      _XtInitializeStateTable(&temp);
!     if (old != NULL)
! 	temp->clickTime = old->clickTime;
      MergeTables(temp, old, FALSE);
      MergeTables(temp, new, FALSE);
      *merged= temp;
***************
*** 1075,1084
      Widget widget;
      XtTranslations new;
  {
! /*
!     MergeTables(widget->core.translations, new, TRUE);
! */
!      Cardinal  numQuarks =0;
      XrmValue from,to;
      TMConvertRec foo;
      from.addr = (caddr_t)&foo;

--- 1077,1083 -----
      Widget widget;
      XtTranslations new;
  {
!     Cardinal  numQuarks = 0;
      XrmValue from,to;
      TMConvertRec foo;
  
***************
*** 1081,1086
       Cardinal  numQuarks =0;
      XrmValue from,to;
      TMConvertRec foo;
      from.addr = (caddr_t)&foo;
      from.size = sizeof(TMConvertRec);
      foo.old = widget->core.tm.translations;

--- 1080,1086 -----
      Cardinal  numQuarks = 0;
      XrmValue from,to;
      TMConvertRec foo;
+ 
      from.addr = (caddr_t)&foo;
      from.size = sizeof(TMConvertRec);
      foo.old = widget->core.tm.translations;
***************
*** 1086,1092
      foo.old = widget->core.tm.translations;
      foo.new = new;
      foo.operation = override;
!      if (widget->core.tm.translations != NULL)
        numQuarks = widget->core.tm.translations->numQuarks;
      XtDirectConvert((XtConverter) _MergeTranslations, (XrmValuePtr) NULL,
  	    0, &from, &to);

--- 1086,1093 -----
      foo.old = widget->core.tm.translations;
      foo.new = new;
      foo.operation = override;
! 
!     if (widget->core.tm.translations != NULL)
        numQuarks = widget->core.tm.translations->numQuarks;
  
      XtDirectConvert((XtConverter) _MergeTranslations, (XrmValuePtr) NULL,
***************
*** 1088,1093
      foo.operation = override;
       if (widget->core.tm.translations != NULL)
        numQuarks = widget->core.tm.translations->numQuarks;
      XtDirectConvert((XtConverter) _MergeTranslations, (XrmValuePtr) NULL,
  	    0, &from, &to);
  /*    _XtOverrideTranslations(widget->core.tm.translations, new);*/

--- 1089,1095 -----
  
      if (widget->core.tm.translations != NULL)
        numQuarks = widget->core.tm.translations->numQuarks;
+ 
      XtDirectConvert((XtConverter) _MergeTranslations, (XrmValuePtr) NULL,
  	    0, &from, &to);
  
***************
*** 1090,1100
        numQuarks = widget->core.tm.translations->numQuarks;
      XtDirectConvert((XtConverter) _MergeTranslations, (XrmValuePtr) NULL,
  	    0, &from, &to);
! /*    _XtOverrideTranslations(widget->core.tm.translations, new);*/
!       widget->core.tm.translations =(*(XtTranslations*)to.addr);
!      if (XtIsRealized(widget))
!         _XtBindActions(widget,&widget->core.tm,numQuarks);
!         
  }
  
  void XtAugmentTranslations(widget, new)

--- 1092,1130 -----
  
      XtDirectConvert((XtConverter) _MergeTranslations, (XrmValuePtr) NULL,
  	    0, &from, &to);
! 
!     widget->core.tm.translations =(*(XtTranslations*)to.addr);
! 
!     if (XtIsRealized(widget))
!     {
!         int i;
! 
!         if (numQuarks != widget->core.tm.translations->numQuarks)
!         {
!            widget->core.tm.proc_table= (XtActionProc*) XtRealloc(
!                widget->core.tm.proc_table,
!                widget->core.tm.translations->numQuarks * sizeof(XtActionProc));
!         }
! 
!         /*
!          * Since the old table was merged into the new table,
!          * we need to force all translations to be rebound; this
!          * is because the indices into the proc_table have changed,
!          * and duplicate actions will have been removed by MergeTables().
!          */
!         for (i=0; i < widget->core.tm.translations->numQuarks; i++)
!            widget->core.tm.proc_table[i] = 0;
! 
!         /*
!          * Bind the new actions (rebind the old actions); we must
!          * also remove the old event handler, and then install the
!          * new set of translations.
!          */
!         _XtBindActions(widget, &widget->core.tm, 0);
!         XtRemoveEventHandler (widget, XtAllEvents, True, _XtTranslateEvent,
!                               (caddr_t)&widget->core.tm);
!         _XtInstallTranslations (widget, widget->core.tm.translations);
!     }
  }
  
  void XtAugmentTranslations(widget, new)
***************
*** 1101,1107
      Widget widget;
      XtTranslations new;
  {
!     Cardinal  numQuarks =0;
      XrmValue from,to;
      TMConvertRec foo;
      from.addr = (caddr_t)&foo;

--- 1131,1137 -----
      Widget widget;
      XtTranslations new;
  {
!     Cardinal  numQuarks = 0;
      XrmValue from,to;
      TMConvertRec foo;
  
***************
*** 1104,1109
      Cardinal  numQuarks =0;
      XrmValue from,to;
      TMConvertRec foo;
      from.addr = (caddr_t)&foo;
      from.size = sizeof(TMConvertRec);
      foo.old = widget->core.tm.translations;

--- 1134,1140 -----
      Cardinal  numQuarks = 0;
      XrmValue from,to;
      TMConvertRec foo;
+ 
      from.addr = (caddr_t)&foo;
      from.size = sizeof(TMConvertRec);
      foo.old = widget->core.tm.translations;
***************
*** 1109,1115
      foo.old = widget->core.tm.translations;
      foo.new = new;
      foo.operation = augment;
!      if (widget->core.tm.translations != NULL)
        numQuarks = widget->core.tm.translations->numQuarks;
      XtDirectConvert((XtConverter) _MergeTranslations, (XrmValuePtr) NULL,
  	    0, &from, &to);

--- 1140,1147 -----
      foo.old = widget->core.tm.translations;
      foo.new = new;
      foo.operation = augment;
! 
!     if (widget->core.tm.translations != NULL)
        numQuarks = widget->core.tm.translations->numQuarks;
  
      XtDirectConvert((XtConverter) _MergeTranslations, (XrmValuePtr) NULL,
***************
*** 1111,1116
      foo.operation = augment;
       if (widget->core.tm.translations != NULL)
        numQuarks = widget->core.tm.translations->numQuarks;
      XtDirectConvert((XtConverter) _MergeTranslations, (XrmValuePtr) NULL,
  	    0, &from, &to);
  /*    _XtAugmentTranslations(widget->core.tm.translations, new);*/

--- 1143,1149 -----
  
      if (widget->core.tm.translations != NULL)
        numQuarks = widget->core.tm.translations->numQuarks;
+ 
      XtDirectConvert((XtConverter) _MergeTranslations, (XrmValuePtr) NULL,
  	    0, &from, &to);
  
***************
*** 1113,1122
        numQuarks = widget->core.tm.translations->numQuarks;
      XtDirectConvert((XtConverter) _MergeTranslations, (XrmValuePtr) NULL,
  	    0, &from, &to);
- /*    _XtAugmentTranslations(widget->core.tm.translations, new);*/
-      widget->core.tm.translations = (*(XtTranslations*)to.addr);
-      if (XtIsRealized(widget)) 
-         _XtBindActions(widget,&widget->core.tm,numQuarks);
  
  }
  

--- 1146,1151 -----
  
      XtDirectConvert((XtConverter) _MergeTranslations, (XrmValuePtr) NULL,
  	    0, &from, &to);
  
      widget->core.tm.translations = (*(XtTranslations*)to.addr);
  
***************
*** 1118,1123
       if (XtIsRealized(widget)) 
          _XtBindActions(widget,&widget->core.tm,numQuarks);
  
  }
  
  static void PrintState(start, str, state, quarkTable, eot)

--- 1147,1184 -----
      XtDirectConvert((XtConverter) _MergeTranslations, (XrmValuePtr) NULL,
  	    0, &from, &to);
  
+     widget->core.tm.translations = (*(XtTranslations*)to.addr);
+ 
+     if (XtIsRealized(widget)) 
+     {
+         int i;
+ 
+         if (numQuarks != widget->core.tm.translations->numQuarks)
+         {
+            widget->core.tm.proc_table= (XtActionProc*) XtRealloc(
+                widget->core.tm.proc_table,
+                widget->core.tm.translations->numQuarks * sizeof(XtActionProc));
+         }
+ 
+         /* Force all entries to be bound (see note below) */
+         for (i = 0; i < widget->core.tm.translations->numQuarks; i++)
+            widget->core.tm.proc_table[i] = 0;
+ 
+         /*
+          * Bind the new actions and all existing actions; we must rebind
+          * the old actions because MergeTables() may have compressed the
+          * proc_table, and we thus no longer know where the new entries
+          * start (This really is caused by a bug in ParseActionSeq(),
+          * which doesn't check to see if an action already has an entry
+          * in the proc_table; thus, an action can initially appear more
+          * than once).  We must also remove the old event handler, 
+          * and then install the new set of translations.
+          */
+         _XtBindActions(widget, &widget->core.tm, 0);
+         XtRemoveEventHandler (widget, XtAllEvents, True, _XtTranslateEvent,
+                               (caddr_t)&widget->core.tm);
+         _XtInstallTranslations (widget, widget->core.tm.translations);
+     }
  }
  
  static void PrintState(start, str, state, quarkTable, eot)