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)