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