X11 binding, XGetWindowProperty, and different behaviour for similar code between D and C++ (D fails)

Jarrett Billingsley jarrett.billingsley at gmail.com
Thu Apr 2 06:59:55 PDT 2009


On Fri, Apr 3, 2009 at 4:40 AM, Simon Gomizelj <simongmzlj at gmail.com> wrote:
> On Fri, 03 Apr 2009 04:09:25 -0400, Simon Gomizelj <simongmzlj at gmail.com>
> wrote:
>
>> As a personal learning D/learn X11 project, I thought it would be
>> interesting to try to port dwm over to D. Building it up nice and slowly,
>> right now I'm trying to collect a list of windows and their states a-la
>> dwm.c code.
>>
>> The D code, which is translated from C code, does not work, it returns:
>> X Error of failed request:  BadValue (integer parameter out of range for
>> operation)
>>   Major opcode of failed request:  20 (X_GetProperty)
>>   Value in failed request:  0x2
>>   Serial number of failed request:  29
>>   Current serial number in output stream:  29
>>
>> The C++ code, which is the D code translated back, does work. The code
>> fails on a call to XGetWindowProperty. Debugging each shows that both the
>> C++ and D code pass the same atom, display, and window. Setting
>> WM_STATE_ELEMENTS < 2 causes the D code to start to segfault while the C++
>> code still seems to work.
>>
>> The std.c.linux.X11.X and std.c.linux.X11.Xlib modules I grabbed off of
>> http://www.dsource.org/projects/bindings/browser/trunk/X11?order=date. The
>> rest are hand translated (but unconsequential, XGetWindowProperty is
>> contained in Xlib). X.d and Xlib.d look correct enough.
>>
>> I've spent a full day looking at this code, and I can't seem to determine
>> why the D code fails. Anyone have any ideas? Thanks in advance.
>>
>
> C++ code:
> long getstate(Window window)
> {
>    static const long WM_STATE_ELEMENTS = 2L;
>
>    unsigned long nitems;
>    unsigned long leftover;
>    Atom xa_WM_STATE, actual_type;
>    int actual_format;
>    int status;
>    unsigned char* p = NULL;
>
>    xa_WM_STATE = XInternAtom(display, "WM_STATE", false);
>    cout << "debug: atom " << xa_WM_STATE << endl;
>
>    cout << "debug: XGetWindowProperty on window " << window << endl;
>    status = XGetWindowProperty(display, window,
>                  xa_WM_STATE, 0L, WM_STATE_ELEMENTS,
>                  false, xa_WM_STATE, &actual_type, &actual_format,
>                  &nitems, &leftover, &p);
>
>    if(status == 0)
>    {
>        cout << "RETURN:" << ((p != NULL) ? (long)*p : -1) << " leftover:" <<
> leftover << " nitems:" << nitems << endl;
>        XFree(p);
>        return (p != NULL) ? (long)*p : -1;
>    }
>    return -1;
> }
>
> D code:
> long getstate(Window window)
> {
>    static const long WM_STATE_ELEMENTS = 2L;
>
>    uint nitems;
>    uint leftover;
>    Atom xa_WM_STATE, actual_type;
>    int actual_format;
>    int status;
>
>    ubyte* p = null;
>    scope(exit) XFree(p);
>
>    byte[] name = cast(byte[])"WM_STATE\0";
>    xa_WM_STATE = XInternAtom(display, name.ptr, Bool.False);
>    debug output(color.green, "debug: atom {}", xa_WM_STATE);
>
>    debug output(color.cyan, "debug: XGetWindowProperty on window {}",
> window);
>    status = XGetWindowProperty(display, window,
>                  xa_WM_STATE, 0L, WM_STATE_ELEMENTS,
>                  Bool.False, xa_WM_STATE, &actual_type, &actual_format,
>                  &nitems, &leftover, &p);
>    debug output(color.cyan, "debug: XGetWindowProperty, result:{}", status);
>
>    if(status == 0)
>        return (p != null) ? cast(long)*p : -1;
>    return -1;
> }

My best guess is that you've translated those X11 function headers
incorrectly.  Perhaps you've used a D long where you shouldn't have.
A D long is 64 bits, while a C long is 32, at least on 32-bit
platforms.  If you were to pass a 64-bit value where it was expecting
a 32-bit one, the params would be in all the wrong places.  But this
is just speculation, since I don't know what your bindings look like.



More information about the Digitalmars-d mailing list