
patch.tix -   11/6/97

This patch file fixes Tix 4.1 for use with the Img package. It should
be applied by running the "patch" program in the top-level directory
of a clean Tix 4.1 release, using the command "patch -p0 <patch.tix"

*** imgpatch.orig	Sat Nov  8 03:42:20 1997
--- imgpatch	Sat Nov  8 03:41:59 1997
***************
*** 0 ****
--- 1,49 ----
+ #!/bin/sh
+ # The next line restarts using tclsh8.0 \
+ exec tclsh8.0 $0 ${1+"$@"}
+ 
+ set dirs ". ./generic"
+ set date "11/6/97"
+ 
+ #
+ # This is a tcl-script that will search a list of directories
+ # for ".orig"-files. For all of these it will make a "diff",
+ # and create a patch-file.
+ #
+ #	Written by:	Jan Nijtmans
+ #			CMG (Computer Management Group) Arnhem B.V.
+ #			email: Jan.Nijtmans@wxs.nl (private)
+ #			       Jan.Nijtmans@cmg.nl (work)
+ #			url:   http://home.wxs.nl/~nijtmans/
+ 
+ set dfiles ""
+ 
+ set file [open imgpatch.orig w]
+ close $file
+ 
+ foreach dir $dirs {
+     set files [eval exec ls $dir]
+     foreach file $files {
+ 	if {[regexp ".*\.orig" $file]} {
+ 	    set file [file join $dir [string range $file 0 [expr [string length $file]-6]]]
+ 	    lappend dfiles $file.diff
+ 	    set file [string range $file 2 [string length $file]]
+ 	    puts stdout "creating $file.diff"
+ 	    catch "exec diff -c $file.orig $file >$file.diff"
+ 	}
+     }
+ }
+ 
+ puts stdout "creating patch.tix"
+ set file [open patch.tix w]
+ puts $file ""
+ puts $file "patch.tix -   $date"
+ puts $file ""
+ puts $file "This patch file fixes Tix 4.1 for use with the Img package. It should"
+ puts $file "be applied by running the \"patch\" program in the top-level directory"
+ puts $file "of a clean Tix 4.1 release, using the command \"patch -p0 <patch.tix\""
+ puts $file ""
+ eval exec cat $dfiles >@$file
+ close $file
+ 
+ file delete imgpatch.diff imgpatch.orig
*** generic/tix.h.orig	Wed Sep 24 01:41:51 1997
--- generic/tix.h	Wed Nov  5 00:08:34 1997
***************
*** 376,381 ****
--- 376,383 ----
  			    int argc, char **argv));
  EXTERN void		Tix_SetRcFileName _ANSI_ARGS_((
  			    Tcl_Interp * interp,  char * rcFileName));
+ EXTERN char *		TixGetStringFromObj _ANSI_ARGS_((
+ 			    char *objPtr,int *lengthPtr));
  
  
  /*
*** generic/tixImgCmp.c.orig	Fri Jun 27 19:23:45 1997
--- generic/tixImgCmp.c	Wed Nov  5 00:08:34 1997
***************
*** 369,380 ****
  
  	/* ARGSUSED */
  static int
! ImgCmpCreate(interp, name, argc, argv, typePtr, master, clientDataPtr)
      Tcl_Interp *interp;		/* Interpreter for application containing
  				 * image. */
      char *name;			/* Name to use for image. */
      int argc;			/* Number of arguments. */
!     char **argv;		/* Argument strings for options (doesn't
  				 * include image name or type). */
      Tk_ImageType *typePtr;	/* Pointer to our type record (not used). */
      Tk_ImageMaster master;	/* Token for image, to be used by us in
--- 369,380 ----
  
  	/* ARGSUSED */
  static int
! ImgCmpCreate(interp, name, argc, objv, typePtr, master, clientDataPtr)
      Tcl_Interp *interp;		/* Interpreter for application containing
  				 * image. */
      char *name;			/* Name to use for image. */
      int argc;			/* Number of arguments. */
!     char **objv;		/* Argument strings for options (doesn't
  				 * include image name or type). */
      Tk_ImageType *typePtr;	/* Pointer to our type record (not used). */
      Tk_ImageMaster master;	/* Token for image, to be used by us in
***************
*** 383,388 ****
--- 383,401 ----
  				 * it will be returned in later callbacks. */
  {
      CmpMaster *masterPtr;
+     int i;
+     char *argvbuf[10];
+     char **argv = argvbuf;
+ 
+     /*
+      * Convert the objc/objv arguments into string equivalent.
+      */
+     if (argc > 10) {
+ 	argv = (char **) ckalloc(argc * sizeof(char *));
+     }
+     for (i = 0; i < argc; i++) {
+ 	argv[i] = TixGetStringFromObj(objv[i], NULL);
+     }
  
      masterPtr = (CmpMaster *) ckalloc(sizeof(CmpMaster));
      masterPtr->tkMaster = master;
***************
*** 409,417 ****
--- 422,436 ----
  	
      if (ImgCmpConfigureMaster(masterPtr, argc, argv, 0) != TCL_OK) {
  	ImgCmpDelete((ClientData) masterPtr);
+ 	if (argv != argvbuf) {
+ 	    ckfree((char *) argv);
+ 	}
  	return TCL_ERROR;
      }
      *clientDataPtr = (ClientData) masterPtr;
+     if (argv != argvbuf) {
+ 	ckfree((char *) argv);
+     }
      return TCL_OK;
  }
  
*** generic/tixImgXpm.c.orig	Fri Jun 27 00:44:31 1997
--- generic/tixImgXpm.c	Wed Nov  5 00:08:34 1997
***************
*** 107,118 ****
   *----------------------------------------------------------------------
   */
  static int
! ImgXpmCreate(interp, name, argc, argv, typePtr, master, clientDataPtr)
      Tcl_Interp *interp;		/* Interpreter for application containing
  				 * image. */
      char *name;			/* Name to use for image. */
      int argc;			/* Number of arguments. */
!     char **argv;		/* Argument strings for options (doesn't
  				 * include image name or type). */
      Tk_ImageType *typePtr;	/* Pointer to our type record (not used). */
      Tk_ImageMaster master;	/* Token for image, to be used by us in
--- 107,118 ----
   *----------------------------------------------------------------------
   */
  static int
! ImgXpmCreate(interp, name, argc, objv, typePtr, master, clientDataPtr)
      Tcl_Interp *interp;		/* Interpreter for application containing
  				 * image. */
      char *name;			/* Name to use for image. */
      int argc;			/* Number of arguments. */
!     char **objv;		/* Argument strings for options (doesn't
  				 * include image name or type). */
      Tk_ImageType *typePtr;	/* Pointer to our type record (not used). */
      Tk_ImageMaster master;	/* Token for image, to be used by us in
***************
*** 121,126 ****
--- 121,139 ----
  				 * it will be returned in later callbacks. */
  {
      PixmapMaster *masterPtr;
+     int i;
+     char *argvbuf[10];
+     char **argv = argvbuf;
+ 
+     /*
+      * Convert the objc/objv arguments into string equivalent.
+      */
+     if (argc > 10) {
+ 	argv = (char **) ckalloc(argc * sizeof(char *));
+     }
+     for (i = 0; i < argc; i++) {
+ 	argv[i] = TixGetStringFromObj(objv[i], NULL);
+     }
  
      masterPtr = (PixmapMaster *) ckalloc(sizeof(PixmapMaster));
      masterPtr->tkMaster = master;
***************
*** 137,143 ****
--- 150,162 ----
  
      if (ImgXpmConfigureMaster(masterPtr, argc, argv, 0) != TCL_OK) {
  	ImgXpmDelete((ClientData) masterPtr);
+ 	if (argv != argvbuf) {
+ 	    ckfree((char *) argv);
+ 	}
  	return TCL_ERROR;
+     }
+     if (argv != argvbuf) {
+ 	ckfree((char *) argv);
      }
      *clientDataPtr = (ClientData) masterPtr;
      return TCL_OK;
*** generic/tixUtils.c.orig	Tue Jun 17 20:28:32 1997
--- generic/tixUtils.c	Wed Nov  5 00:46:24 1997
***************
*** 350,355 ****
--- 350,357 ----
   *----------------------------------------------------------------------
   */
  
+ static int initialized = 0;
+ 
  void Tix_CreateCommands(interp, commands, clientData, deleteProc)
      Tcl_Interp *interp;
      Tix_TclCmd *commands;
***************
*** 358,363 ****
--- 360,383 ----
  {
      Tix_TclCmd * cmdPtr;
  
+     if (!initialized) {
+ 	char *version = Tcl_PkgRequire(interp, "Tcl", NULL, 0);
+ 	initialized = 1;
+ 	if (version[0] == '8') {
+ 	    struct CmdInfo {
+ 		int isNativeObjectProc;
+ 		Tcl_ObjCmdProc *objProc;
+ 		ClientData objClientData;
+ 		VOID *dummy[10]; /* worst case space that could be written
+ 				  * by Tcl_GetCommandInfo() */
+ 	    } cmdInfo;
+ 	    if (!Tcl_GetCommandInfo(interp,"image", (Tcl_CmdInfo *) &cmdInfo)) {
+ 		panic("cannot find the \"image\" command");
+ 	    } else if (cmdInfo.isNativeObjectProc == 1) {
+ 		initialized = 2; /* we use objects */
+ 	    }
+ 	}
+     }
      for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) {
  	Tcl_CreateCommand(interp, cmdPtr->name,
  	     cmdPtr->cmdProc, clientData, deleteProc);
***************
*** 860,862 ****
--- 880,1035 ----
      Tk_FreeTextLayout(textLayout);
  }
  #endif
+ 
+ #if TK_MAJOR_VERSION < 8
+ 
+ /*
+  * Procedure types defined by Tcl:
+  */
+ 
+ typedef void (Tcl_FreeInternalRepProc) _ANSI_ARGS_((struct Tcl_Obj *objPtr));
+ typedef void (Tcl_DupInternalRepProc) _ANSI_ARGS_((struct Tcl_Obj *srcPtr, 
+         struct Tcl_Obj *dupPtr));
+ typedef void (Tcl_UpdateStringProc) _ANSI_ARGS_((struct Tcl_Obj *objPtr));
+ typedef int (Tcl_SetFromAnyProc) _ANSI_ARGS_((Tcl_Interp *interp,
+ 	struct Tcl_Obj *objPtr));
+ typedef int (Tcl_ObjCmdProc) _ANSI_ARGS_((ClientData clientData,
+ 	Tcl_Interp *interp, int objc, struct Tcl_Obj *CONST objv[]));
+ 
+ /*
+  * The following structure represents a type of object, which is a
+  * particular internal representation for an object plus a set of
+  * procedures that provide standard operations on objects of that type.
+  */
+ 
+ typedef struct Tcl_ObjType {
+     char *name;			/* Name of the type, e.g. "int". */
+     Tcl_FreeInternalRepProc *freeIntRepProc;
+ 				/* Called to free any storage for the type's
+ 				 * internal rep. NULL if the internal rep
+ 				 * does not need freeing. */
+     Tcl_DupInternalRepProc *dupIntRepProc;
+     				/* Called to create a new object as a copy
+ 				 * of an existing object. */
+     Tcl_UpdateStringProc *updateStringProc;
+     				/* Called to update the string rep from the
+ 				 * type's internal representation. */
+     Tcl_SetFromAnyProc *setFromAnyProc;
+     				/* Called to convert the object's internal
+ 				 * rep to this type. Frees the internal rep
+ 				 * of the old type. Returns TCL_ERROR on
+ 				 * failure. */
+ } Tcl_ObjType;
+ 
+ /*
+  * One of the following structures exists for each object in the Tcl
+  * system.  An object stores a value as either a string, some internal
+  * representation, or both.
+  */
+ 
+ typedef struct Tcl_Obj {
+     int refCount;		/* When 0 the object will be freed. */
+     char *bytes;		/* This points to the first byte of the
+ 				 * object's string representation. The
+ 				 * array must be followed by a null byte
+ 				 * (i.e., at offset length) but may also
+ 				 * contain embedded null characters. The
+ 				 * array's storage is allocated by
+ 				 * ckalloc. NULL indicates the string
+ 				 * rep is empty or invalid and must be
+ 				 * regenerated from the internal rep.
+ 				 * Clients should use Tcl_GetStringFromObj
+ 				 * to get a pointer to the byte array
+ 				 * as a readonly value.  */
+     int length;			/* The number of bytes at *bytes, not
+ 				 * including the terminating null. */
+     Tcl_ObjType *typePtr;	/* Denotes the object's type. Always
+ 				 * corresponds to the type of the object's
+ 				 * internal rep. NULL indicates the object
+ 				 * has no internal rep (has no type). */
+     union {			/* The internal representation: */
+ 	long longValue;		/*   - an long integer value */
+ 	double doubleValue;	/*   - a double-precision floating value */
+ 	VOID *otherValuePtr;	/*   - another, type-specific value */
+ 	struct {		/*   - internal rep as two pointers */
+ 	    VOID *ptr1;
+ 	    VOID *ptr2;
+ 	} twoPtrValue;
+     } internalRep;
+ } Tcl_Obj;
+ 
+ #endif
+ 
+ /*
+  *----------------------------------------------------------------------
+  *
+  * TixGetStringFromObj --
+  *
+  *	Returns the string representation's byte array pointer and length
+  *	for an object.
+  *
+  * Results:
+  *	Returns a pointer to the string representation of objPtr.  If
+  *	lengthPtr isn't NULL, the length of the string representation is
+  *	stored at *lengthPtr. The byte array referenced by the returned
+  *	pointer must not be modified by the caller. Furthermore, the
+  *	caller must copy the bytes if they need to retain them since the
+  *	object's string rep can change as a result of other operations.
+  *      REMARK: This function reacts a little bit different than
+  *	Tcl_GetStringFromObj():
+  *	- objPtr is allowed to be NULL. In that case the NULL pointer
+  *	  will be returned, and the length will be reported to be 0;
+  *	In the Img code there is never a distinction between en empty
+  *	string and a NULL pointer, while the latter is easier to check
+  *	for. That's the reason for this difference.
+  *
+  * Side effects:
+  *	May call the object's updateStringProc to update the string
+  *	representation from the internal representation.
+  *
+  *----------------------------------------------------------------------
+  */
+ 
+ char *
+ TixGetStringFromObj(objPtr, lengthPtr)
+     char *objPtr;		/* Object whose string rep byte pointer
+ 				 * should be returned, or NULL */
+     register int *lengthPtr;	/* If non-NULL, the location where the
+ 				 * string rep's byte array length should be
+ 				 * stored. If NULL, no length is stored. */
+ {
+     Tcl_Obj *obj = (Tcl_Obj *) objPtr;
+ 
+     if (!obj) {
+ 	if (lengthPtr != NULL) {
+ 	    *lengthPtr = 0;
+ 	}
+ 	return (char *) NULL;
+     }
+     if (initialized & 2) {
+ 	if (obj->bytes != NULL) {
+ 	    if (lengthPtr != NULL) {
+ 		*lengthPtr = obj->length;
+ 	    }
+ 	    return (obj->length) ? obj->bytes : (char *) NULL;
+ 	}
+ 
+ 	if (obj->typePtr == NULL) {
+ 	    if (lengthPtr != NULL) {
+ 		*lengthPtr = 0;
+ 	    }
+ 	    return "";
+ 	}
+ 
+ 	obj->typePtr->updateStringProc(obj);
+ 	if (lengthPtr != NULL) {
+ 	    *lengthPtr = obj->length;
+ 	}
+ 	return (obj->length) ? obj->bytes : (char *) NULL;
+     } else {
+ 	if (lengthPtr != NULL) {
+ 	    *lengthPtr = objPtr ? strlen(objPtr) : 0;
+ 	}
+ 	return objPtr;
+     }
+ }
