Re: 64-bit support for display device

Stefan Kemper <[email protected]>
Newsgroups gmane.comp.printing.ghostscript.patches
Message-ID <1076514233.7342.1133.camel@sklap>
Thanks, Russell.  

I'm glad you found a way to do this in a backward compatible manner. 
Kudos.   I'll merge this over so it gets into our next pcl release.  

./Stefan

On Wed, 2004-02-11 at 01:38, Russell Lang wrote:
> Ray,
> 
> Please review the following patch.  I have not tested it on a 64-
> bit platform (I don't have one).  I would like this added to 
> 8.14.  If all goes well it should be harmless.  Worst case is 
> probably some compiler warnings when compiled on a 64-bit 
> platform.    For HEAD, GS_8_1X and GS_8_0X.
> 
> Log message:
> 
> Change display device parameter DisplayHandle from an integer
> to a string, to add support for 64-bit platforms.
> 
> DETAILS:
> 
> The display device passes a (void *) handle to callback 
> functions.  The handle is set before the device is opened, and 
> attempting to change it afterwards is an error.  The handle may 
> be used by the caller to identify an instance of the display 
> device, for example it may point to the display instance object 
> in the caller. This handle was set using a PostScript integer 
> which is 32-bits long, typically with -dDisplayHandle.  The 
> existing code will not work correctly on 64-bit architectures.   
> 
> 
> The display device is changed to return a string as the
> DisplayHandle parameter.
> Previously the handle would be set using -dDisplayHandle=1234.
> The changed code allows it to be passed as
>  -dDisplayHandle=1234
>  -dDisplayHandle=(1234)
>  -sDisplayHandle=1234
>  -sDisplayHandle=10#1234
>  -sDisplayHandle=16#04d2
> This should be backward compatible, since users of the
> display device will most likely only set the DisplayHandle,
> not read its value.
> 
> The ghostscript example code in dw*.c, dx*.c and dp*.c
> does not use DisplayHandle, so is unaffected by this change.
> GSview does use DisplayHandle and will require this
> change for operation on 64-bit platforms.
> 
> It is assumed that size_t is an integer with the same size
> as a pointer.
> 
> 
> Russell Lang                   [email protected]
> Ghostgum Software Pty Ltd      http://www.ghostgum.com.au/
> 
> 
> 
> 
> ______________________________________________________________________
> diff -u l:src/gdevdsp.c src/gdevdsp.c
> --- l:src/gdevdsp.c	Wed Apr 30 09:34:53 2003
> +++ src/gdevdsp.c	Wed Feb 11 08:08:53 2004
> @@ -704,9 +704,33 @@
>  {
>      gx_device_display *ddev = (gx_device_display *) dev;
>      int code = gx_default_get_params(dev, plist);
> +    gs_param_string dhandle;
> +    int idx;
> +    int val;
> +    int i = 0;
> +    size_t dptr;
> +    char buf[64];
> +   
> +    idx = ((int)sizeof(size_t)) * 8 - 4;
> +    buf[i++] = '1';
> +    buf[i++] = '6';
> +    buf[i++] = '#';
> +    dptr = (size_t)(ddev->pHandle);
> +    while (idx >= 0) {
> +	val = (int)(dptr >> idx) & 0xf;
> +        if (val <= 9)
> +	    buf[i++] = '0' + val;
> +	else
> +	    buf[i++] = 'a' - 10 + val;
> +	idx -= 4;
> +    }
> +    buf[i] = '\0';
> +     
> +    param_string_from_transient_string(dhandle, buf);
> +    
>      (void)(code < 0 ||
> -	(code = param_write_long(plist, 
> -	    "DisplayHandle", (long *)(&ddev->pHandle))) < 0 ||
> +	(code = param_write_string(plist, 
> +	    "DisplayHandle", &dhandle)) < 0 ||
>  	(code = param_write_int(plist, 
>  	    "DisplayFormat", &ddev->nFormat)) < 0 );
>      return code;
> @@ -731,6 +755,8 @@
>  
>      int format;
>      void *handle;
> +    int found_string_handle = 0;
> +    gs_param_string dh = { 0 };
>  
>      /* Handle extra parameters */
>  
> @@ -757,24 +783,98 @@
>  	    break;
>      }
>  
> -    switch (code = param_read_long(plist, "DisplayHandle", (long *)(&handle))) {
> +    /* 64-bit systems need to use DisplayHandle as a string */
> +    switch (code = param_read_string(plist, "DisplayHandle", &dh)) {
>  	case 0:
> -	    if (dev->is_open) {
> -		if (ddev->pHandle != handle)
> -		    ecode = gs_error_rangecheck;
> -		else
> -		    break;
> -	    }
> -	    else
> -		ddev->pHandle = handle;
> -		break;
> -	    goto hdle;
> +    	    found_string_handle = 1;
> +	    break;
>  	default:
> +	    if ((code == gs_error_typecheck) && (sizeof(size_t) <= 4)) {
> +		/* 32-bit systems can use the older long type */
> +		switch (code = param_read_long(plist, "DisplayHandle", 
> +		    (long *)(&handle))) {
> +		    case 0:
> +			if (dev->is_open) {
> +			    if (ddev->pHandle != handle)
> +				ecode = gs_error_rangecheck;
> +			    else
> +				break;
> +			}
> +			else {
> +			    ddev->pHandle = handle;
> +			    break;
> +			}
> +			goto hdle;
> +		    default:
> +			ecode = code;
> +		      hdle:param_signal_error(plist, "DisplayHandle", ecode);
> +		    case 1:
> +			break;
> +		}
> +		break;
> +	    }
>  	    ecode = code;
> -	  hdle:param_signal_error(plist, "DisplayHandle", ecode);
> +	    param_signal_error(plist, "DisplayHandle", ecode);
> +	    /* fall through */
>  	case 1:
> +	    dh.data = 0;
>  	    break;
>      }
> +    if (found_string_handle) {
> +	/* 
> +	 * Convert from a string to a pointer.  
> +	 * It is assumed that size_t has the same size as a pointer.
> +	 * Allow formats (1234), (10#1234) or (16#04d2).
> +	 */
> +	size_t ptr = 0;
> + 	int i;
> +	int base = 10;
> + 	int val;
> +	code = 0;
> +	for (i=0; i<dh.size; i++) {
> +	    val = dh.data[i];
> +	    if ((val >= '0') && (val <= '9'))
> +		val = val - '0';
> +	    else if ((val >= 'A') && (val <= 'F'))
> +		val = val - 'A' + 10;
> +	    else if ((val >= 'a') && (val <= 'f'))
> +		val = val - 'a' + 10;
> +	    else if (val == '#') {
> +		base = (int)ptr;
> +		ptr = 0;
> +		if ((base != 10) && (base != 16)) {
> +		    code = gs_error_rangecheck;
> +		    break;
> +		}
> +		continue;
> +	    }
> +	    else {
> +		code = gs_error_rangecheck;
> +		break;
> +	    }
> +
> +	    if (base == 10)
> +		ptr = ptr * 10 + val;
> +	    else if (base == 16)
> +		ptr = ptr * 16 + val;
> +	    else {
> +		code = gs_error_rangecheck;
> +		break;
> +	    }
> +	}
> +	if (code == 0) {
> +	    if (dev->is_open) {
> +		if (ddev->pHandle != (void *)ptr)
> +		    code = gs_error_rangecheck;
> +	    }
> +	    else
> +		ddev->pHandle = (void *)ptr;
> +	}
> +	if (code < 0) {
> +	    ecode = code;
> +	    param_signal_error(plist, "DisplayHandle", ecode);
> +	}
> +    }
>  
>      if (ecode >= 0) {
>  	/* Prevent gx_default_put_params from closing the device. */
> Only in src: gdevdsp.c.orig
> diff -u l:src/gdevdsp.h src/gdevdsp.h
> --- l:src/gdevdsp.h	Thu Nov 21 08:36:43 2002
> +++ src/gdevdsp.h	Wed Feb 11 08:11:53 2004
> @@ -28,8 +28,10 @@
>   *  gsapi_init_with_args(minst, argc, argv);
>   *
>   * Supported parameters and default values are:
> - * -dDisplayHandle=0                      long
> - *    Caller supplied handle.
> + * -sDisplayHandle=16#04d2 or 1234        string
> + *    Caller supplied handle as a decimal or hexadecimal number
> + *    in a string.  On 32-bit platforms, it may be set
> + *    using -dDisplayHandle=1234 for backward compatibility.
>   *    Included as first parameter of all callback functions.
>   *
>   * -dDisplayFormat=0                      long
> 
> ______________________________________________________________________
> _______________________________________________
> gs-code-review mailing list
> [email protected]
> http://www.ghostscript.com/mailman/listinfo/gs-code-review
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.