[comp.sources.x] v03i009: X11 Release 3, Patch8

mikew@wyse.wyse.com (Mike Wexler) (02/04/89)

Submitted-by: mikew@wyse.com
Posting-number: Volume 3, Issue 9
Archive-name: x11.3/patch8



    Destroy procs were not being called for descendents of popups
    when the parent of the popup was destroyed.

    Routines registered with XtAddInput can get called twice for every event.

    XtAppProcessEvent may process an XEvent even if told not to in the mask.

    XtAppProcessEvent might loop consuming as much cpu as it can get if
    events are available from any source it was supposed to ignore.

    The display_accelerator method was being passed translations,
    not accelerators.

    Installing accelerators into a destination with no translations
    caused segmentation fault.

Server bugs:

    At apparently random times, when a window was destroyed, the Sun server
    dumped core.

    Sun server allowed the default colormap to be destroyed, causing havoc.

*** old/lib/Xt/Create.c
--- lib/Xt/Create.c
***************
*** 1,5 ****
  #ifndef lint
! static char Xrcsid[] = "$XConsortium: Create.c,v 1.47 88/10/17 20:19:21 swick Exp $";
  /* $oHeader: Create.c,v 1.5 88/09/01 11:26:22 asente Exp $ */
  #endif lint
  
--- 1,5 ----
  #ifndef lint
! static char Xrcsid[] = "$XConsortium: Create.c,v 1.48 88/12/02 12:49:46 swick Exp $";
  /* $oHeader: Create.c,v 1.5 88/09/01 11:26:22 asente Exp $ */
  #endif lint
  
***************
*** 281,286 ****
--- 281,293 ----
  	Window win;
          if ((win = XtWindow(widget)) != NULL)
  	    XDestroyWindow( XtDisplay(widget), win );
+ 
+ 	return;
+ 	/* don't update parent's popup_list, as we won't then be able to find
+ 	 * this child for Phase2Destroy.  This also allows for the possibility
+ 	 * that a destroy callback higher up in the hierarchy may care to
+ 	 * know that this popup child once existed.
+ 	 */
      }
      parent->core.num_popups--;
      for (/*i=i*/; i<parent->core.num_popups; i++)


*** lib/Xt/NextEvent.c.old
--- lib/Xt/NextEvent.c
***************
*** 1,5 ****
  #ifndef lint
! static char Xrcsid[] = "$XConsortium: NextEvent.c,v 1.56 88/10/21 13:23:02 swick Exp $";
  /* $oHeader: NextEvent.c,v 1.4 88/09/01 11:43:27 asente Exp $ */
  #endif lint
  
--- 1,5 ----
  #ifndef lint
! static char Xrcsid[] = "$XConsortium: NextEvent.c,v 1.59 89/01/18 17:04:01 swick Exp $";
  /* $oHeader: NextEvent.c,v 1.4 88/09/01 11:43:27 asente Exp $ */
  #endif lint
  
***************
*** 77,89 ****
   *
   * This routine returns when there is something to be done
   *
   *
!  * _XtWaitForSomething( ignoreTimers, ignoreInputs, block, howlong, displaySet)
   * Boolean ignoreTimers;     (Don't return if a timer would fire
   *				Also implies forget timers exist)
   *
   * Boolean ignoreInputs;     (Ditto for input callbacks )
   *
   * Boolean block;	     (Okay to block)
   * TimeVal howlong;	     (howlong to wait for if blocking and not
   *				doing Timers... Null mean forever.
--- 77,96 ----
   *
   * This routine returns when there is something to be done
   *
+  * Before calling this with ignoreInputs==False, app->outstandingQueue should
+  * be checked; this routine will not verify that an alternate input source
+  * has not already been enqueued.
   *
!  *
!  * _XtWaitForSomething( ignoreTimers, ignoreInputs, ignoreEvents,
!  *			block, howlong, appContext)
   * Boolean ignoreTimers;     (Don't return if a timer would fire
   *				Also implies forget timers exist)
   *
   * Boolean ignoreInputs;     (Ditto for input callbacks )
   *
+  * Boolean ignoreEvents;     (Ditto for X events)
+  *
   * Boolean block;	     (Okay to block)
   * TimeVal howlong;	     (howlong to wait for if blocking and not
   *				doing Timers... Null mean forever.
***************
*** 90,99 ****
   *				Maybe should mean shortest of both)
   * XtAppContext app;	     (Displays to check wait on)
   * Returns display for which input is available, if any
   */
! int _XtwaitForSomething(ignoreTimers, ignoreInputs, block, howlong, app)
  	Boolean ignoreTimers;
  	Boolean ignoreInputs;
  	Boolean block;
  	unsigned long *howlong;
  	XtAppContext app;
--- 97,114 ----
   *				Maybe should mean shortest of both)
   * XtAppContext app;	     (Displays to check wait on)
   * Returns display for which input is available, if any
+  * and if ignoreEvents==False, else returns -1
+  *
+  * if ignoring everything && block=True && howlong=NULL, you'll have
+  * lots of time for coffee; better not try it!  In fact, it probably
+  * makes little sense to do this regardless of the value of howlong
+  * (bottom line is, we don't bother checking here).
   */
! int _XtwaitForSomething(ignoreTimers, ignoreInputs, ignoreEvents,
! 			block, howlong, app)
  	Boolean ignoreTimers;
  	Boolean ignoreInputs;
+ 	Boolean ignoreEvents;
  	Boolean block;
  	unsigned long *howlong;
  	XtAppContext app;
***************
*** 147,154 ****
  			wmaskfd = zero;
  			emaskfd = zero;
  		}
! 		for (d = 0; d < app->count; d++) {
! 		    FD_SET (ConnectionNumber(app->list[d]), &rmaskfd);
  		}
  		nfound = select (app->fds.nfds, (int *) &rmaskfd,
  			(int *) &wmaskfd, (int *) &emaskfd, wait_time_ptr);
--- 162,171 ----
  			wmaskfd = zero;
  			emaskfd = zero;
  		}
! 		if (!ignoreEvents) {
! 		    for (d = 0; d < app->count; d++) {
! 			FD_SET (ConnectionNumber(app->list[d]), &rmaskfd);
! 		    }
  		}
  		nfound = select (app->fds.nfds, (int *) &rmaskfd,
  			(int *) &wmaskfd, (int *) &emaskfd, wait_time_ptr);
***************
*** 198,203 ****
--- 215,221 ----
  	        }
  	}
  	if(ignoreInputs) {
+ 	    if (ignoreEvents) return -1; /* then only doing timers */
  	    for (d = 0; d < app->count; d++) {
  		if (FD_ISSET(ConnectionNumber(app->list[d]), &rmaskfd)) {
  		    return d;
***************
*** 207,222 ****
  	ret = -1;
  	for (i = 0; i < app->fds.nfds && nfound > 0; i++) {
  	    if (FD_ISSET (i, &rmaskfd)) {
! 		for (d = 0; d < app->count; d++) {
! 		    if (i == ConnectionNumber(app->list[d])) {
! 			if (ret == -1) ret = d;
! 			goto ENDILOOP;
  		    }
  		}
  
  		app->selectRqueue[i]->ie_oq = app->outstandingQueue;
  		app->outstandingQueue = app->selectRqueue[i];
- 		nfound--;
  	    }
  	    if (FD_ISSET (i, &wmaskfd)) {
  		app->selectWqueue[i]->ie_oq = app->outstandingQueue;
--- 225,242 ----
  	ret = -1;
  	for (i = 0; i < app->fds.nfds && nfound > 0; i++) {
  	    if (FD_ISSET (i, &rmaskfd)) {
! 		nfound--;
! 		if (!ignoreEvents) {
! 		    for (d = 0; d < app->count; d++) {
! 			if (i == ConnectionNumber(app->list[d])) {
! 			    if (ret == -1) ret = d;
! 			    goto ENDILOOP;
! 			}
  		    }
  		}
  
  		app->selectRqueue[i]->ie_oq = app->outstandingQueue;
  		app->outstandingQueue = app->selectRqueue[i];
  	    }
  	    if (FD_ISSET (i, &wmaskfd)) {
  		app->selectWqueue[i]->ie_oq = app->outstandingQueue;
***************
*** 362,368 ****
  	InputEvent *sptr;
  	XtInputMask condition = (XtInputMask) Condition;
  	
! 	sptr = (InputEvent *)XtMalloc((unsigned) sizeof (*sptr));
  	if(condition == XtInputReadMask){
  	    sptr->ie_next = app->selectRqueue[source];
  	    app->selectRqueue[source] = sptr;
--- 382,388 ----
  	InputEvent *sptr;
  	XtInputMask condition = (XtInputMask) Condition;
  	
! 	sptr = XtNew(InputEvent);
  	if(condition == XtInputReadMask){
  	    sptr->ie_next = app->selectRqueue[source];
  	    app->selectRqueue[source] = sptr;
***************
*** 474,491 ****
  	struct timeval  cur_time;
  	struct timezone cur_timezone;
  
  	if (app->fds.count > 0) {
  	    /* Call _XtwaitForSomething to get input queued up */
! 	    (void) _XtwaitForSomething(TRUE, FALSE, FALSE,
  		(unsigned long *)NULL, app);
  	}
- 
- 	for (ie_ptr = app->outstandingQueue; ie_ptr != NULL;) {
- 	    app->outstandingQueue = ie_ptr->ie_oq;
- 	    ie_ptr ->ie_oq = NULL;
- 	    IeCallProc(ie_ptr);
- 	    ie_ptr = app->outstandingQueue;
- 	}
  	if (app->timerQueue != NULL) {	/* check timeout queue */
  	    (void) gettimeofday (&cur_time, &cur_timezone);
  	    while(IS_AFTER (app->timerQueue->te_timer_value, cur_time)) {
--- 494,514 ----
  	struct timeval  cur_time;
  	struct timezone cur_timezone;
  
+ #define DrainQueue() \
+ 	for (ie_ptr = app->outstandingQueue; ie_ptr != NULL;) { \
+ 	    app->outstandingQueue = ie_ptr->ie_oq;		\
+ 	    ie_ptr ->ie_oq = NULL;				\
+ 	    IeCallProc(ie_ptr);					\
+ 	    ie_ptr = app->outstandingQueue;			\
+ 	}
+ /*enddef*/
+ 	DrainQueue();
  	if (app->fds.count > 0) {
  	    /* Call _XtwaitForSomething to get input queued up */
! 	    (void) _XtwaitForSomething(TRUE, FALSE, TRUE, FALSE,
  		(unsigned long *)NULL, app);
+ 	    DrainQueue();
  	}
  	if (app->timerQueue != NULL) {	/* check timeout queue */
  	    (void) gettimeofday (&cur_time, &cur_timezone);
  	    while(IS_AFTER (app->timerQueue->te_timer_value, cur_time)) {
***************
*** 498,503 ****
--- 521,527 ----
                if (app->timerQueue == NULL) break;
  	    }
  	}
+ #undef DrainQueue
  }
  
  /* If there are any work procs, call them.  Return whether we did so */
***************
*** 573,579 ****
  	/* We're ready to wait...if there is a work proc, call it */
  	if (CallWorkProc(app)) continue;
  
! 	d = _XtwaitForSomething(FALSE, FALSE, TRUE,
  				(unsigned long *) NULL, app);
  
  	if (d != -1) {
--- 597,603 ----
  	/* We're ready to wait...if there is a work proc, call it */
  	if (CallWorkProc(app)) continue;
  
! 	d = _XtwaitForSomething(FALSE, FALSE, FALSE, TRUE,
  				(unsigned long *) NULL, app);
  
  	if (d != -1) {
***************
*** 622,630 ****
  	    }
      
  	    if (mask & XtIMAlternateInput) {
! 		if (app->fds.count > 0) {
  		    /* Call _XtwaitForSomething to get input queued up */
! 		    (void) _XtwaitForSomething(TRUE, FALSE, FALSE,
  			    (unsigned long *)NULL, app);
  		}
  		if (app->outstandingQueue != NULL) {
--- 646,654 ----
  	    }
      
  	    if (mask & XtIMAlternateInput) {
! 		if (app->fds.count > 0 && app->outstandingQueue == NULL) {
  		    /* Call _XtwaitForSomething to get input queued up */
! 		    (void) _XtwaitForSomething(TRUE, FALSE, TRUE, FALSE,
  			    (unsigned long *)NULL, app);
  		}
  		if (app->outstandingQueue != NULL) {
***************
*** 654,663 ****
  
  	    if (CallWorkProc(app)) continue;
  
! 	    d = _XtwaitForSomething(FALSE, FALSE, TRUE,
  				    (unsigned long *) NULL, app);
  	    
! 	    if (d != -1) {
  		XNextEvent(app->list[d], &event);
  		app->last = d;
  		if (event.xany.type == MappingNotify) {
--- 678,691 ----
  
  	    if (CallWorkProc(app)) continue;
  
! 	    d = _XtwaitForSomething(
! 				    (mask & XtIMTimer ? FALSE : TRUE),
! 				    (mask & XtIMAlternateInput ? FALSE : TRUE),
! 				    (mask & XtIMXEvent ? FALSE : TRUE),
! 				    TRUE,
  				    (unsigned long *) NULL, app);
  	    
! 	    if (mask & XtIMXEvent && d != -1) {
  		XNextEvent(app->list[d], &event);
  		app->last = d;
  		if (event.xany.type == MappingNotify) {
***************
*** 708,714 ****
  	else {
  	    /* This won't cause a wait, but will enqueue any input */
  
! 	    if(_XtwaitForSomething(TRUE, FALSE, FALSE, (unsigned long *) NULL,
  		    app) != -1) ret |= XtIMXEvent;
  	    if (app->outstandingQueue != NULL) ret |= XtIMAlternateInput;
  	}
--- 736,742 ----
  	else {
  	    /* This won't cause a wait, but will enqueue any input */
  
! 	    if(_XtwaitForSomething(TRUE, FALSE, FALSE, FALSE, (unsigned long *) NULL,
  		    app) != -1) ret |= XtIMXEvent;
  	    if (app->outstandingQueue != NULL) ret |= XtIMAlternateInput;
  	}
***************
*** 723,735 ****
  	struct timeval  cur_time;
  	struct timezone cur_timezone;
  
  	if (app->fds.count > 0) {
  	    /* Call _XtwaitForSomething to get input queued up */
! 	    (void) _XtwaitForSomething(TRUE, FALSE, FALSE,
  		    (unsigned long *)NULL, app);
  	}
  
- 	if (app->outstandingQueue != NULL) return TRUE;
  	if (app->timerQueue != NULL) {	/* check timeout queue */
  	    (void) gettimeofday (&cur_time, &cur_timezone);
  	    if (IS_AFTER (app->timerQueue->te_timer_value, cur_time)) return TRUE;
--- 751,765 ----
  	struct timeval  cur_time;
  	struct timezone cur_timezone;
  
+ 	if (app->outstandingQueue != NULL) return TRUE;
+ 
  	if (app->fds.count > 0) {
  	    /* Call _XtwaitForSomething to get input queued up */
! 	    (void) _XtwaitForSomething(TRUE, FALSE, TRUE, FALSE,
  		    (unsigned long *)NULL, app);
+ 	    if (app->outstandingQueue != NULL) return TRUE;
  	}
  
  	if (app->timerQueue != NULL) {	/* check timeout queue */
  	    (void) gettimeofday (&cur_time, &cur_timezone);
  	    if (IS_AFTER (app->timerQueue->te_timer_value, cur_time)) return TRUE;
***************
*** 769,775 ****
  		return FALSE;
  	    }
  
! 	    d = _XtwaitForSomething(FALSE, FALSE, TRUE,
  		    (unsigned long *) NULL, app);
  
  	    if (d != -1) {
--- 799,805 ----
  		return FALSE;
  	    }
  
! 	    d = _XtwaitForSomething(FALSE, FALSE, FALSE, TRUE,
  		    (unsigned long *) NULL, app);
  
  	    if (d != -1) {


*** lib/Xt/InitialI.h.old
--- lib/Xt/InitialI.h
***************
*** 1,4 ****
! /* $XConsortium: InitialI.h,v 1.8 88/10/19 08:35:49 swick Exp $ */
  /* $oHeader: InitializeI.h,v 1.8 88/09/01 11:25:04 asente Exp $ */
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
--- 1,4 ----
! /* $XConsortium: InitialI.h,v 1.9 89/01/18 17:05:57 swick Exp $ */
  /* $oHeader: InitializeI.h,v 1.8 88/09/01 11:25:04 asente Exp $ */
  /***********************************************************
  Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
***************
*** 107,116 ****
  extern int _XtAppDestroyCount;
  extern int _XtDpyDestroyCount;
  
! extern int _XtwaitForSomething(); /* ignoreTimers, ignoreInputs, block, 
! 					howlong, dset */
      /* Boolean ignoreTimers; */
      /* Boolean ignoreInputs; */
      /* Boolean block; */
      /* unsigned long *howlong; */
      /* XtAppContext app */
--- 107,117 ----
  extern int _XtAppDestroyCount;
  extern int _XtDpyDestroyCount;
  
! extern int _XtwaitForSomething(); /* ignoreTimers, ignoreInputs, ignoreEvents,
! 				     block, howlong, appContext */
      /* Boolean ignoreTimers; */
      /* Boolean ignoreInputs; */
+     /* Boolean ignoreEvents; */
      /* Boolean block; */
      /* unsigned long *howlong; */
      /* XtAppContext app */


*** lib/Xt/Shell.c.old
--- lib/Xt/Shell.c
***************
*** 1,5 ****
  #ifndef lint
! static char Xrcsid[] = "$XConsortium: Shell.c,v 1.45 88/10/19 09:21:48 swick Exp $";
  /* $oHeader: Shell.c,v 1.7 88/09/01 11:57:00 asente Exp $ */
  #endif lint
  
--- 1,5 ----
  #ifndef lint
! static char Xrcsid[] = "$XConsortium: Shell.c,v 1.46 89/01/18 17:04:58 swick Exp $";
  /* $oHeader: Shell.c,v 1.7 88/09/01 11:57:00 asente Exp $ */
  #endif lint
  
***************
*** 1265,1271 ****
  		}
  		return TRUE;
  	    } else {
! 		if (_XtwaitForSomething(TRUE, TRUE, TRUE, &timeout,
  			app) != -1) continue;
  		if (timeout == 0)
  		  return FALSE;
--- 1265,1271 ----
  		}
  		return TRUE;
  	    } else {
! 		if (_XtwaitForSomething(TRUE, TRUE, FALSE, TRUE, &timeout,
  			app) != -1) continue;
  		if (timeout == 0)
  		  return FALSE;


*** /tmp/,RCSt1a05545	Fri Jan 20 08:06:10 1989
--- lib/Xt/TMstate.c	Fri Jan 20 08:05:58 1989
***************
*** 1,5 ****
  #ifndef lint
! static char Xrcsid[] = "$XConsortium: TMstate.c,v 1.61 88/09/26 09:30:45 swick Exp $";
  /* $oHeader: TMstate.c,v 1.5 88/09/01 17:17:29 asente Exp $ */
  #endif lint
  /*LINTLIBRARY*/
--- 1,5 ----
  #ifndef lint
! static char Xrcsid[] = "$XConsortium: TMstate.c,v 1.65 89/01/20 08:05:17 swick Exp $";
  /* $oHeader: TMstate.c,v 1.5 88/09/01 17:17:29 asente Exp $ */
  #endif lint
  /*LINTLIBRARY*/
***************
*** 41,46 ****
--- 41,63 ----
  
  #define StringToAction(string)	((XtAction) StringToQuark(string))
  
+ #define STR_THRESHOLD 25
+ #define STR_INCAMOUNT 100
+ #define CHECK_STR_OVERFLOW \
+     if (str - *buf > *len - STR_THRESHOLD) {		\
+ 	String old = *buf;				\
+ 	*buf = XtRealloc(old, *len += STR_INCAMOUNT);	\
+ 	str = str - old + *buf;				\
+     }
+ 
+ #define ExpandToFit(more) \
+     if (str - *buf > *len - STR_THRESHOLD - strlen(more)) { 		\
+ 	String old = *buf;						\
+ 	*buf = XtRealloc(old, *len += STR_INCAMOUNT + strlen(more));	\
+ 	str = str - old + *buf;						\
+     }
+ 
+ 
  static void FreeActions(action)
    register ActionPtr action;
  {
***************
*** 60,93 ****
      }
  }
  
! static String PrintModifiers(str, mask, mod)
      String str;
      unsigned long mask, mod;
  {
!     if (mask & ShiftMask)
! 	(void) sprintf(str, "%sShift", ((mod & ShiftMask) ? "" : "~"));
!     if (mask & ControlMask)
! 	(void) sprintf(str, "%sCtrl", ((mod & ControlMask) ? "" : "~"));
!     if (mask & LockMask)
! 	(void) sprintf(str, "%sLock", ((mod & LockMask) ? "" : "~"));
!     if (mask & Mod1Mask)
! 	(void) sprintf(str, "%sMeta", ((mod & Mod1Mask) ? "" : "~"));
!     if (mask & Mod2Mask)
! 	(void) sprintf(str, "%sMod2", ((mod & Mod2Mask) ? "" : "~"));
!     if (mask & Mod3Mask)
! 	(void) sprintf(str, "%sMod3", ((mod & Mod3Mask) ? "" : "~"));
!     if (mask & Mod4Mask)
! 	(void) sprintf(str, "%sMod4", ((mod & Mod4Mask) ? "" : "~"));
!     if (mask & Mod5Mask)
! 	(void) sprintf(str, "%sMod5", ((mod & Mod5Mask) ? "" : "~"));
!     str += strlen(str);
      return str;
  }
  
! static String PrintEventType(str, event)
      register String str;
      unsigned long event;
  {
      switch (event) {
  #define PRINTEVENT(event) case event: (void) sprintf(str, "<event>"); break;
  	PRINTEVENT(KeyPress)
--- 77,139 ----
      }
  }
  
! static String PrintModifiers(buf, len, str, mask, mod)
!     String *buf;
!     int *len;
      String str;
      unsigned long mask, mod;
  {
!     Boolean notfirst = False;
!     CHECK_STR_OVERFLOW;
! 
! #if defined(__STDC__) && !defined(UNIXCPP)
! #define MASKNAME(modname) modname##Mask
! #else
! #define MASKNAME(modname) modname/**/Mask
! #endif
! 
! #define PRINTMOD(modname) \
!     if (mask & MASKNAME(modname)) {	 \
! 	if (! (mod & MASKNAME(modname))) \
! 	    *str++ = '~';		 \
! 	else if (notfirst)		 \
! 	    *str++ = ' ';		 \
! 	*str = '\0';			 \
! 	strcat(str, "modname");		 \
! 	str += strlen(str);		 \
! 	notfirst = True;		 \
!     }
! 
! #define CtrlMask ControlMask
! 
!     PRINTMOD(Shift);
!     PRINTMOD(Ctrl);
!     PRINTMOD(Lock);
!     PRINTMOD(Mod1);
!     PRINTMOD(Mod2);
!     PRINTMOD(Mod3);
!     PRINTMOD(Mod4);
!     PRINTMOD(Mod5);
!     PRINTMOD(Button1);
!     PRINTMOD(Button2);
!     PRINTMOD(Button3);
!     PRINTMOD(Button4);
!     PRINTMOD(Button5);
! 
! #undef MASKNAME
! #undef PRINTMOD
! #undef CtrlMask
! 
      return str;
  }
  
! static String PrintEventType(buf, len, str, event)
!     String *buf;
!     int *len;
      register String str;
      unsigned long event;
  {
+     CHECK_STR_OVERFLOW;
      switch (event) {
  #define PRINTEVENT(event) case event: (void) sprintf(str, "<event>"); break;
  	PRINTEVENT(KeyPress)
***************
*** 131,140 ****
      return str;
  }
  
! static String PrintCode(str, mask, code)
      register String str;
      unsigned long mask, code;
  {
      if (mask != 0) {
  	if (mask != (unsigned long)~0L)
  	    (void) sprintf(str, "0x%lx:0x%lx", mask, code);
--- 177,189 ----
      return str;
  }
  
! static String PrintCode(buf, len, str, mask, code)
!     String *buf;
!     int *len;
      register String str;
      unsigned long mask, code;
  {
+     CHECK_STR_OVERFLOW;
      if (mask != 0) {
  	if (mask != (unsigned long)~0L)
  	    (void) sprintf(str, "0x%lx:0x%lx", mask, code);
***************
*** 144,165 ****
      return str;
  }
  
! static String PrintEvent(str, event)
      register String str;
      register Event *event;
  {
!     str = PrintModifiers(str, event->modifierMask, event->modifiers);
!     str = PrintEventType(str, event->eventType);
!     str = PrintCode(str, event->eventCodeMask, event->eventCode);
      return str;
  }
  
! static String PrintParams(str, params, num_params)
      register String str, *params;
      Cardinal num_params;
  {
      register Cardinal i;
      for (i = 0; i<num_params; i++) {
  	if (i != 0) (void) sprintf(str, ", ");
  	str += strlen(str);
  	(void) sprintf(str, "\"%s\"", params[i]);
--- 193,243 ----
      return str;
  }
  
! static String PrintLateModifiers(buf, len, str, lateModifiers)
!     String *buf;
!     int *len;
      register String str;
+     LateBindingsPtr lateModifiers;
+ {
+     for (; lateModifiers->keysym != NULL; lateModifiers++) {
+ 	CHECK_STR_OVERFLOW;
+ 	if (lateModifiers->knot) {
+ 	    *str++ = '~';
+ 	    *str = '\0';
+ 	}
+ 	strcat(str, XKeysymToString(lateModifiers->keysym));
+ 	str += strlen(str);
+ 	if (lateModifiers->pair) {
+ 	    *(str -= 2) = '\0';	/* strip "_L" */
+ 	    lateModifiers++;	/* skip _R keysym */
+ 	}
+     }
+     return str;
+ }
+ 
+ static String PrintEvent(buf, len, str, event)
+     String *buf;
+     int *len;
+     register String str;
      register Event *event;
  {
!     str = PrintModifiers(buf, len, str, event->modifierMask, event->modifiers);
!     if (event->lateModifiers != NULL)
! 	str = PrintLateModifiers(buf, len, str, event->lateModifiers);
!     str = PrintEventType(buf, len, str, event->eventType);
!     str = PrintCode(buf, len, str, event->eventCodeMask, event->eventCode);
      return str;
  }
  
! static String PrintParams(buf, len, str, params, num_params)
!     String *buf;
!     int *len;
      register String str, *params;
      Cardinal num_params;
  {
      register Cardinal i;
      for (i = 0; i<num_params; i++) {
+ 	ExpandToFit( params[i] );
  	if (i != 0) (void) sprintf(str, ", ");
  	str += strlen(str);
  	(void) sprintf(str, "\"%s\"", params[i]);
***************
*** 168,183 ****
      return str;
  }
  
! static String PrintActions(str, actions, quarkTable)
      register String str;
      register ActionPtr actions;
      XrmQuark* quarkTable;
  {
!     while (actions != NULL && actions->token != NULL) {
!         (void) sprintf(
!             str, " %s(", XrmQuarkToString(quarkTable[actions->index]));
  	str += strlen(str);
! 	str = PrintParams(str, actions->params, (Cardinal)actions->num_params);
  	str += strlen(str);
  	(void) sprintf(str, ")");
  	str += strlen(str);
--- 246,264 ----
      return str;
  }
  
! static String PrintActions(buf, len, str, actions, quarkTable)
!     String *buf;
!     int *len;
      register String str;
      register ActionPtr actions;
      XrmQuark* quarkTable;
  {
!     while (actions != NULL /* && actions->token != NULL */) {
! 	String proc = XrmQuarkToString(quarkTable[actions->index]);
! 	ExpandToFit( proc );
!         (void) sprintf(str, " %s(", proc);
  	str += strlen(str);
! 	str = PrintParams(buf, len, str, actions->params, (Cardinal)actions->num_params);
  	str += strlen(str);
  	(void) sprintf(str, ")");
  	str += strlen(str);
***************
*** 1002,1007 ****
--- 1083,1089 ----
      if (unbound != 0) ReportUnboundActions(tm, stateTable);
  }
  
+ static
  void _XtBindAccActions(widget,stateTable,index,accBindings)
      Widget	    widget;
      XtTranslations  stateTable;
***************
*** 1491,1527 ****
  void XtInstallAccelerators(destination,source)
      Widget destination,source;
  {
-     char str[100];
-     XtTranslations temp;
      XtBoundAccActions accBindings;
      if ((!XtIsWindowObject(source)) ||
          source->core.accelerators == NULL) return;
!     if (source->core.accelerators != NULL 
!         && source->core.accelerators->accProcTbl == NULL)
          _XtBindAccActions(source,source->core.accelerators,0,&accBindings);
!     _XtInitializeStateTable(&temp);
!     temp->clickTime = source->core.accelerators->clickTime;
!     if (source->core.accelerators->operation == XtTableOverride) {
!         MergeTables(temp,source->core.accelerators,FALSE,accBindings);
!         MergeTables(temp, destination->core.tm.translations,FALSE,
!                destination->core.tm.translations->accProcTbl);
      }
!     else { 
!         MergeTables(temp, destination->core.tm.translations,FALSE,
!                destination->core.tm.translations->accProcTbl);
!         MergeTables(temp,source->core.accelerators,FALSE,accBindings);
      }
-     destination->core.tm.translations = temp;
      if (XtIsRealized(destination))
          _XtInstallTranslations(destination,
               destination->core.tm.translations);
      XtAddCallback(source, XtNdestroyCallback,
!         RemoveAccelerators,(caddr_t)temp);
      if (XtClass(source)->core_class.display_accelerator != NULL){
           str[0] = '\0';
!          (void) PrintEvent(&str[0],
!                 &source->core.tm.translations->eventObjTbl[0].event);
!          (*(XtClass(source)->core_class.display_accelerator))(source,str);
      }
  }         
  void XtInstallAllAccelerators(destination,source)
--- 1573,1632 ----
  void XtInstallAccelerators(destination,source)
      Widget destination,source;
  {
      XtBoundAccActions accBindings;
      if ((!XtIsWindowObject(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,0,&accBindings);
!     if (destination->core.tm.translations == NULL) {
! 	destination->core.tm.translations = source->core.accelerators;
! 	destination->core.tm.translations->accProcTbl = accBindings;
      }
!     else {
! 	XtTranslations temp;
! 	_XtInitializeStateTable(&temp);
! 	temp->clickTime = source->core.accelerators->clickTime;
! 	if (source->core.accelerators->operation == XtTableOverride) {
! 	    MergeTables(temp,source->core.accelerators,FALSE,accBindings);
! 	    MergeTables(temp, destination->core.tm.translations,FALSE,
! 		   destination->core.tm.translations->accProcTbl);
! 	}
! 	else { 
! 	    MergeTables(temp, destination->core.tm.translations,FALSE,
! 		   destination->core.tm.translations->accProcTbl);
! 	    MergeTables(temp,source->core.accelerators,FALSE,accBindings);
! 	}
! 	destination->core.tm.translations = temp;
      }
      if (XtIsRealized(destination))
          _XtInstallTranslations(destination,
               destination->core.tm.translations);
      XtAddCallback(source, XtNdestroyCallback,
!         RemoveAccelerators,(caddr_t)destination->core.tm.translations);
      if (XtClass(source)->core_class.display_accelerator != NULL){
+ 	 char *buf = XtMalloc(100);
+ 	 int len = 100;
+ 	 String str = buf;
+ 	 int i;
           str[0] = '\0';
! 	 for (i = 0; i < source->core.accelerators->numEvents;) {
! 	     str = PrintEvent(&str, &len, str,
! 			    &source->core.accelerators->eventObjTbl[i].event);
! 	     if (++i == source->core.accelerators->numEvents) break;
! 	     else {
! 		 *str++ = '\n';
! 		 *str = '\0';
! 	     }
! 	 }
!          (*(XtClass(source)->core_class.display_accelerator))(source,buf);
! 	 XtFree(buf);
      }
  }         
  void XtInstallAllAccelerators(destination,source)
***************
*** 1574,1581 ****
  
  }
  
! static void PrintState(start, str, state, quarkTable, eot)
!     register String start, str;
      StatePtr state;
      XrmQuark* quarkTable;
      EventObjPtr eot;
--- 1679,1688 ----
  
  }
  
! static void PrintState(buf, len, str, state, quarkTable, eot)
!     String *buf;
!     int *len;
!     register String str;
      StatePtr state;
      XrmQuark* quarkTable;
      EventObjPtr eot;
***************
*** 1584,1608 ****
      /* print the current state */
      if (state == NULL) return;
  
!     str = PrintEvent(str, &eot[state->index].event);
!     str += strlen(str);
      if (state->actions != NULL) {
! 	String temp = str;
  	(void) sprintf(str, "%s: ", (state->cycle ? "(+)" : ""));
  	while (*str) str++;
! 	(void) PrintActions(str, state->actions, quarkTable);
! 	(void) printf("%s\n", start);
! 	str = temp; *str = '\0';
      }
  
      /* print succeeding states */
      if (!state->cycle)
! 	PrintState(start, str, state->nextLevel, quarkTable, eot);
  
      str = old; *str = '\0';
  
      /* print sibling states */
!     PrintState(start, str, state->next, quarkTable, eot);
      *str = '\0';
  
  }
--- 1691,1715 ----
      /* print the current state */
      if (state == NULL) return;
  
!     str = PrintEvent(buf, len, str, &eot[state->index].event);
      if (state->actions != NULL) {
! 	int offset = str - *buf;
! 	CHECK_STR_OVERFLOW;
  	(void) sprintf(str, "%s: ", (state->cycle ? "(+)" : ""));
  	while (*str) str++;
! 	(void) PrintActions(buf, len, str, state->actions, quarkTable);
! 	(void) printf("%s\n", *buf);
! 	str = *buf + offset; *str = '\0';
      }
  
      /* print succeeding states */
      if (!state->cycle)
! 	PrintState(buf, len, str, state->nextLevel, quarkTable, eot);
  
      str = old; *str = '\0';
  
      /* print sibling states */
!     PrintState(buf, len, str, state->next, quarkTable, eot);
      *str = '\0';
  
  }
***************
*** 1615,1631 ****
      XtTranslations translations;
  {
      register Cardinal i;
!     char buf[1000];
  
      for (i = 0; i < translations->numEvents; i++) {
  	buf[0] = '\0';
  	PrintState(
! 	   &buf[0],
! 	   &buf[0],
  	   translations->eventObjTbl[i].state,
             translations->quarkTable,
  	   translations->eventObjTbl);
      }
  }
  
  /***********************************************************************
--- 1722,1741 ----
      XtTranslations translations;
  {
      register Cardinal i;
!     int len = 1000;
!     char *buf = XtMalloc(1000);
  
      for (i = 0; i < translations->numEvents; i++) {
  	buf[0] = '\0';
  	PrintState(
! 	   &buf,
! 	   &len,
! 	   buf,
  	   translations->eventObjTbl[i].state,
             translations->quarkTable,
  	   translations->eventObjTbl);
      }
+     XtFree(buf);
  }
  
  /***********************************************************************


*** /tmp/,RCSt1a09958	Thu Dec 22 17:26:10 1988
--- server/dix/resource.c	Thu Dec 22 16:58:08 1988
***************
*** 22,28 ****
  
  ********************************************************/
  
! /* $XConsortium: resource.c,v 1.66 88/09/06 15:41:20 jim Exp $ */
  
  /*	Routines to manage various kinds of resources:
   *
--- 22,28 ----
  
  ********************************************************/
  
! /* $XConsortium: resource.c,v 1.67 88/12/22 16:58:58 rws Exp $ */
  
  /*	Routines to manage various kinds of resources:
   *
***************
*** 169,176 ****
      pointer value;
      int (* func)();
  {
!     int client, j;
!     ResourcePtr res, next, *head;
      	
      client = CLIENT_ID(id);
      if (!clientTable[client].buckets)
--- 169,177 ----
      pointer value;
      int (* func)();
  {
!     int client;
!     register int j;
!     register ResourcePtr res, next, *head;
      	
      client = CLIENT_ID(id);
      if (!clientTable[client].buckets)
***************
*** 195,206 ****
  	clientTable[client].hashsize++;
  	for (j = 0; j < clientTable[client].buckets; j++)
  	{
  	    for (res = clientTable[client].resources[j]; res; res = next)
  	    {
  		next = res->next;
  		head = &resources[Hash(client, res->id)];
! 		res->next = *head;
  		*head = res;
  	    }
  	}
  	clientTable[client].buckets *= 2;
--- 196,213 ----
  	clientTable[client].hashsize++;
  	for (j = 0; j < clientTable[client].buckets; j++)
  	{
+ 	    /*
+ 	     * Must preserve insertion order so that FreeResource doesn't free
+ 	     * "subclasses" before main resources are freed.  Sigh.
+ 	     */
  	    for (res = clientTable[client].resources[j]; res; res = next)
  	    {
  		next = res->next;
  		head = &resources[Hash(client, res->id)];
! 		while (*head)
! 		    head = &(*head)->next;
  		*head = res;
+ 		res->next = NullResource;
  	    }
  	}
  	clientTable[client].buckets *= 2;


*** /tmp/,RCSt1a03822	Thu Jan 12 17:43:12 1989
--- server/ddx/cfb/cfbscrinit.c	Thu Jan 12 17:41:35 1989
***************
*** 64,70 ****
      8,		1,		NULL,
  };
  
- static ColormapPtr cfbColorMaps[NUMVISUALS];	/* assume one per visual */
  #define NUMDEPTHS	((sizeof depths)/(sizeof depths[0]))
  
  /* dts * (inch/dot) * (25.4 mm / inch) = mm */
--- 64,69 ----
***************
*** 80,85 ****
--- 79,85 ----
      register PixmapPtr pPixmap;
      int	i;
      void cfbInitialize332Colormap();
+     ColormapPtr cmap;
  
      pScreen->myNum = index;
      pScreen->width = xsize;
***************
*** 171,195 ****
  	visuals[i].screen = index;
  	AddResource(visuals[i].vid, RT_VISUALID, (pointer)&visuals[i],
  		    NoopDDA, RC_CORE);
- 	switch (visuals[i].class) {
- 	case StaticGray:
- 	case StaticColor:
- 	    CreateColormap(FakeClientID(0), pScreen, &visuals[i], 
- 		&cfbColorMaps[i], AllocAll, 0);
- 	    break;
- 	case PseudoColor:
- 	case GrayScale:
- 	    CreateColormap(FakeClientID(0), pScreen, &visuals[i], 
- 		&cfbColorMaps[i], AllocNone, 0);
- 	    break;
- 	case TrueColor:
- 	case DirectColor:
- 	    FatalError("Bad visual in cfbScreenInit\n");
- 	}
- 	if (!cfbColorMaps[i])
- 	    FatalError("Can't create colormap in cfbScreenInit\n");
      }
-     pScreen->defColormap = cfbColorMaps[ROOTVISUAL]->mid;
      pScreen->rootVisual = visuals[ROOTVISUAL].vid;
  
      /*  Set up the remaining fields in the depths[] array */
--- 171,177 ----
***************
*** 201,206 ****
--- 183,207 ----
  	    pVids[0] = visuals[ROOTVISUAL].vid;
  	}
      }
+ 
+     pScreen->defColormap = FakeClientID(0);
+     switch (visuals[ROOTVISUAL].class) {
+     case StaticGray:
+     case StaticColor:
+ 	CreateColormap(pScreen->defColormap, pScreen, &visuals[ROOTVISUAL],
+ 		       &cmap, AllocAll, 0);
+ 	break;
+     case PseudoColor:
+     case GrayScale:
+ 	CreateColormap(pScreen->defColormap, pScreen, &visuals[ROOTVISUAL], 
+ 		       &cmap, AllocNone, 0);
+ 	break;
+     case TrueColor:
+     case DirectColor:
+ 	FatalError("Bad visual in cfbScreenInit\n");
+     }
+     if (!cmap)
+ 	FatalError("Can't create colormap in cfbScreenInit\n");
      return( TRUE );
  }
  

*** old/lib/Xt/TMstate.c
--- lib/Xt/TMstate.c
***************
*** 1,5 ****
  #ifndef lint
! static char Xrcsid[] = "$XConsortium: TMstate.c,v 1.65 89/01/20 08:05:17 swick Exp $";
  /* $oHeader: TMstate.c,v 1.5 88/09/01 17:17:29 asente Exp $ */
  #endif lint
  /*LINTLIBRARY*/
--- 1,5 ----
  #ifndef lint
! static char Xrcsid[] = "$XConsortium: TMstate.c,v 1.67 89/01/30 15:01:40 swick Exp $";
  /* $oHeader: TMstate.c,v 1.5 88/09/01 17:17:29 asente Exp $ */
  #endif lint
  /*LINTLIBRARY*/
***************
*** 86,128 ****
      Boolean notfirst = False;
      CHECK_STR_OVERFLOW;
  
! #if defined(__STDC__) && !defined(UNIXCPP)
! #define MASKNAME(modname) modname##Mask
! #else
! #define MASKNAME(modname) modname/**/Mask
! #endif
! 
! #define PRINTMOD(modname) \
!     if (mask & MASKNAME(modname)) {	 \
! 	if (! (mod & MASKNAME(modname))) \
  	    *str++ = '~';		 \
  	else if (notfirst)		 \
  	    *str++ = ' ';		 \
  	*str = '\0';			 \
! 	strcat(str, "modname");		 \
  	str += strlen(str);		 \
- 	notfirst = True;		 \
      }
  
! #define CtrlMask ControlMask
  
-     PRINTMOD(Shift);
-     PRINTMOD(Ctrl);
-     PRINTMOD(Lock);
-     PRINTMOD(Mod1);
-     PRINTMOD(Mod2);
-     PRINTMOD(Mod3);
-     PRINTMOD(Mod4);
-     PRINTMOD(Mod5);
-     PRINTMOD(Button1);
-     PRINTMOD(Button2);
-     PRINTMOD(Button3);
-     PRINTMOD(Button4);
-     PRINTMOD(Button5);
- 
- #undef MASKNAME
  #undef PRINTMOD
- #undef CtrlMask
  
      return str;
  }
--- 86,120 ----
      Boolean notfirst = False;
      CHECK_STR_OVERFLOW;
  
! #define PRINTMOD(modmask,modstring) \
!     if (mask & modmask) {		 \
! 	if (! (mod & modmask)) {	 \
  	    *str++ = '~';		 \
+ 	    notfirst = True;		 \
+ 	}				 \
  	else if (notfirst)		 \
  	    *str++ = ' ';		 \
+ 	else notfirst = True;		 \
  	*str = '\0';			 \
! 	strcat(str, modstring);		 \
  	str += strlen(str);		 \
      }
  
!     PRINTMOD(ShiftMask, "Shift");
!     PRINTMOD(ControlMask, "Ctrl");	/* name is not CtrlMask... */
!     PRINTMOD(LockMask, "Lock");
!     PRINTMOD(Mod1Mask, "Mod1");
!     PRINTMOD(Mod2Mask, "Mod2");
!     PRINTMOD(Mod3Mask, "Mod3");
!     PRINTMOD(Mod4Mask, "Mod4");
!     PRINTMOD(Mod5Mask, "Mod5");
!     PRINTMOD(Button1Mask, "Button1");
!     PRINTMOD(Button2Mask, "Button2");
!     PRINTMOD(Button3Mask, "Button3");
!     PRINTMOD(Button4Mask, "Button4");
!     PRINTMOD(Button5Mask, "Button5");
  
  #undef PRINTMOD
  
      return str;
  }
-- 
Mike Wexler(wyse!mikew)    Phone: (408)433-1000 x1330
Moderator of comp.sources.x