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

Simon Gomizelj simongmzlj at gmail.com
Fri Apr 3 10:33:21 PDT 2009


On Thu, 02 Apr 2009 09:59:55 -0400, Jarrett Billingsley  
<jarrett.billingsley at gmail.com> wrote:

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

Yeah, thats it exactly, which is annoying because since I downloaded this  
binding I just assumed it was done right 8-).

extern (C):
extern int XGetWindowProperty(
     Display*    /* display */,
     Window      /* w */,
     Atom        /* property */,
     long        /* long_offset */,  <-- should be int
     long        /* long_length */,  <-- should be int
     Bool        /* delete */,
     Atom        /* req_type */,
     Atom*       /* actual_type_return */,
     int*        /* actual_format_return */,
     uint*       /* nitems_return */,
     uint*       /* bytes_after_return */,
     ubyte**     /* prop_return */
);

Since their are no occurences of long longs I just did a search and  
replace across the whole file for longs to ints

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/



More information about the Digitalmars-d mailing list