#BUGFIX by stefan
authorStefan Vogel <sv@exept.de>
Wed, 25 Apr 2018 14:34:13 +0200
changeset 8341 4ff8b5be757e
parent 8340 1a85908cff8b
child 8342 61d70299d474
#BUGFIX by stefan class: XWorkstation changed: #getProperty:from:delete: fix get only half the number of properties on 64-bit systems
XWorkstation.st
--- a/XWorkstation.st	Wed Apr 25 12:28:18 2018 +0200
+++ b/XWorkstation.st	Wed Apr 25 14:34:13 2018 +0200
@@ -10634,144 +10634,156 @@
 
     <context: #return>
 
-    |val typeID propertyID windowID|
-
+    |val typeID propertyID windowID isUtf8 utf8StringAtom|
+
+    isUtf8 := false.
     propertySymbolOrAtomID isString ifTrue:[
-	propertyID := self atomIDOf:propertySymbolOrAtomID create:false.
-	propertyID isNil ifTrue:[^ nil].
+        propertyID := self atomIDOf:propertySymbolOrAtomID create:false.
+        propertyID isNil ifTrue:[^ nil].
     ] ifFalse:[
-	propertyID := propertySymbolOrAtomID.
+        propertyID := propertySymbolOrAtomID.
     ].
     aWindowOrWindowIDOrNil isView ifTrue:[
-	windowID := aWindowOrWindowIDOrNil id.
+        windowID := aWindowOrWindowIDOrNil id.
     ] ifFalse:[
-	windowID := aWindowOrWindowIDOrNil.
-    ].
-
-%{
+        windowID := aWindowOrWindowIDOrNil.
+    ].
+    utf8StringAtom := self atomIDOf:#'UTF8_STRING' create:true.
+
+%{  /* UNLIMITEDSTACK */
+#define PROPERTY_DEBUG
     Window window;
     Atom property;
-    char *cp, *cp2;
     Atom actual_type;
     int actual_format;
-    unsigned long nitems, bytes_after, nread;
-    unsigned char *data;
+    unsigned long nread = 0, bytes_after;
+    char *cp = 0, *cp2;
     int ok = 1;
 #   define PROP_SIZE    2048
 
     if (ISCONNECTED) {
-	Display *dpy = myDpy;
-
-	if (__isAtomID(propertyID)) {
-	    property = __AtomVal(propertyID);
-
-	    if (__isExternalAddress(windowID)) {
-		window = __WindowVal(windowID);
-	    } else if (windowID == nil) {
-		window = DefaultRootWindow(dpy);
-	    } else
-		goto fail;
-
-	    nread = 0;
-	    cp = 0;
+        Display *dpy = myDpy;
+
+        if (__isAtomID(propertyID)) {
+            property = __AtomVal(propertyID);
+
+            if (__isExternalAddress(windowID)) {
+                window = __WindowVal(windowID);
+            } else if (windowID == nil) {
+                window = DefaultRootWindow(dpy);
+            } else
+                goto fail;
+
 #ifdef PROPERTY_DEBUG
-	    console_fprintf(stderr, "getProperty %x\n", property);
-#endif
-
-	    do {
-		int retVal;
-
-		ENTER_XLIB();
-		retVal = XGetWindowProperty(dpy, window, property, nread/4, PROP_SIZE,
-					    doDelete == true,
-					    AnyPropertyType, &actual_type, &actual_format,
-					    &nitems, &bytes_after, (unsigned char **)&data);
-		LEAVE_XLIB();
-		if (retVal != Success) {
+            console_fprintf(stderr, "getProperty %x\n", property);
+#endif
+
+            do {
+                int retVal;
+                unsigned char *data;
+                unsigned long nitems, nReturnedBytes;
+
+                ENTER_XLIB();
+                retVal = XGetWindowProperty(dpy, window, property, nread/4, PROP_SIZE,
+                                            doDelete == true,
+                                            AnyPropertyType, &actual_type, &actual_format,
+                                            &nitems, &bytes_after, (unsigned char **)&data);
+                LEAVE_XLIB();
+                if (retVal != Success) {
 #ifdef PROPERTY_DEBUG
-		    console_fprintf(stderr, "- no success\n");
-#endif
-		    ok = 0;
-		    break;
-		}
+                    console_fprintf(stderr, "- no success\n");
+#endif
+                    ok = 0;
+                    break;
+                }
 #ifdef PROPERTY_DEBUG
-		console_fprintf(stderr, "- type:%x\n", actual_type);
-#endif
-		nitems *= (actual_format / 8);
-		typeID = __MKATOMOBJ(actual_type);
-		if (! cp) {
-		    cp = cp2 = (char *)malloc(nitems+bytes_after);
-		} else {
-		    cp2 = cp + nread;
-		}
-		if (! cp) {
-		    XFree(data);
-		    goto fail;
-		}
-
-		nread += nitems;
-		bcopy(data, cp2, nitems);
-		XFree(data);
-#ifdef PROPERTY_DEBUG
-		console_fprintf(stderr, "- <nitems:%d bytes_after:%d>\n", nitems, bytes_after);
-#endif
-	    } while (bytes_after > 0);
-
-	    if (ok) {
-		switch (actual_format) {
-		case 32:
-		    // bad design: even though it says "32",
-		    // what is really returned are longs.
-		    // this does make a difference on 64bit machines!
-		    val = __stArrayFromCULongArray((unsigned long*)cp, nread/sizeof(long));
-		    break;
-		case 16:
-		    val = __stArrayFromCUShortArray((unsigned short*)cp, nread/2);
-		    break;
-		case 8:
-		default:
-		    if (actual_type == XA_STRING) {
-			val = __MKSTRING_L(cp, nread);
-		    } else {
-			val = __MKBYTEARRAY(cp, nread);
-		    }
-		    break;
-		}
-	    }
-	    if (cp)
-		free(cp);
-	}
+                console_fprintf(stderr, "- type:%x format:%d nitems:%d bytes_after:%d\n", actual_type, actual_format, nitems, bytes_after);
+#endif
+                typeID = __MKATOMOBJ(actual_type);
+                nReturnedBytes = nitems * (actual_format == 32 ? sizeof(long) : actual_format / 8);
+                if (! cp) {
+                    cp = cp2 = (char *)malloc(nReturnedBytes+bytes_after);
+                    if (! cp) {
+                        XFree(data);
+                        goto fail;
+                    }
+                } else {
+                    cp2 = cp + nread;
+                }
+
+                nread += nReturnedBytes;
+                memcpy(cp2, data, nReturnedBytes);
+                XFree(data);
+            } while (bytes_after > 0);
+
+            if (ok) {
+                switch (actual_format) {
+                case 32:
+                    // bad design: even though it says "32",
+                    // what is really returned are longs.
+                    // this does make a difference on 64bit machines!
+                    val = __stArrayFromCULongArray((unsigned long*)cp, nread/sizeof(long));
+                    break;
+                case 16:
+                    val = __stArrayFromCUShortArray((unsigned short*)cp, nread/2);
+                    break;
+                case 8:
+                default:
+                    if (actual_type == XA_STRING) {
+                        val = __MKSTRING_L(cp, nread);
+                    } else {
+                        if (actual_type == __intVal(utf8StringAtom)) 
+                            isUtf8 = true;
+                        val = __MKBYTEARRAY(cp, nread);
+                    }
+                    break;
+                }
+            }
+            if (cp)
+                free(cp);
+        }
     }
 fail: ;
 %}.
     (typeID isNil or:[typeID == 0]) ifTrue:[
-	"typeID == 0 (None): The property does not exist in the specified window"
-	^ nil
-    ].
+        "typeID == 0 (None): The property does not exist in the specified window"
+        ^ nil
+    ].
+    isUtf8 ifTrue:[
+        val := val utf8Decoded.
+    ].
+    (val isString and:[val includes:(Character codePoint:0)]) ifTrue:[
+        val := val asCollectionOfSubCollectionsSeparatedBy:(Character codePoint:0).
+    ].   
     ^ typeID->val
 
     "
      Display
-	getProperty:#'_NET_WM_ICON_GEOMETRY'
-	from:nil
-	delete:false
+        getProperty:#'_NET_DESKTOP_NAMES'
+        from:nil
+        delete:false
+
+     Display
+        getProperty:#'_NET_CURRENT_DESKTOP'
+        from:nil
+        delete:false
 
      Display
-	getProperty:#'_NET_SUPPORTED'
-	from:nil
-	delete:false
+        getProperty:#'_NET_SUPPORTED'
+        from:nil
+        delete:false
 
      Transcript showCR:(
-	 (Display
-	    getProperty:#'_NET_SUPPORTED'
-	    from:nil
-	    delete:false)
-		value
-		    collect:[:eachID | Display atomName:eachID])
+         (Display
+            getProperty:#'_NET_SUPPORTED'
+            from:nil
+            delete:false) value
+                    collect:[:eachID | Display atomName:eachID])
 
     "
 
     "Modified: / 31-08-2017 / 22:01:44 / cg"
+    "Modified (comment): / 25-04-2018 / 14:33:26 / stefan"
 !
 
 propertiesOf:aWindowOrWindowIDOrNil