Re: 64-bit DisplayHandle

"Russell Lang" <[email protected]> Wed, 02 Mar 2005 07:40:36 +1100
Newsgroups gmane.comp.printing.ghostscript.patches
Message-ID <42256DF4.7693.21FAE26D@localhost>
[updated patch - the previous one didn't apply cleanly because
gdevdsp.c had been changed since the patch was created]

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
 -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.

For HEAD, GS_8_1X

Russell Lang                   [email protected]
Ghostgum Software Pty Ltd      http://www.ghostgum.com.au/

_______________________________________________
gs-code-review mailing list
[email protected]
http://www.ghostscript.com/mailman/listinfo/gs-code-review
disp64c.txt (application/octet-stream, 4.8 KB)
diff -u ..\gs8.51a\src/gdevdsp.c src/gdevdsp.c
--- ..\gs8.51a\src/gdevdsp.c	Fri Feb 11 21:17:28 2005
+++ src/gdevdsp.c	Tue Mar 01 20:34:26 2005
@@ -33,7 +33,7 @@
  * caller when the device is opened, closed, resized, showpage etc.
  * The structure is defined in gdevdsp.h.
  *
- * Not all combinatinos of display formats have been tested.
+ * Not all combinations of display formats have been tested.
  * At the end of this file is some example code showing which
  * formats have been tested.
  */
@@ -765,11 +765,34 @@
 {
     gx_device_display *ddev = (gx_device_display *) dev;
     int code;
+    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);
 
     code = gx_default_get_params(dev, plist);
     (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 ||
 	(code = param_write_float(plist, 
@@ -806,6 +829,8 @@
 
     int format;
     void *handle;
+    int found_string_handle = 0;
+    gs_param_string dh = { 0 };
 
     /* Handle extra parameters */
 
@@ -832,24 +857,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);
+	}
+    }
 
     /* 
      * Set the initial display resolution.
diff -u ..\gs8.51a\src/gdevdsp.h src/gdevdsp.h
--- ..\gs8.51a\src/gdevdsp.h	Fri Feb 11 21:17:28 2005
+++ src/gdevdsp.h	Wed Feb 16 03:54:40 2005
@@ -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