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:55:12 PDT 2009
On Fri, 03 Apr 2009 13:33:21 -0400, Simon Gomizelj <simongmzlj at gmail.com>
wrote:
> 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
>
For curiousities sake, is there any interest to adding my bindings to any
standard library? I know bindings for X.h and Xlib.h exist, but I created
a more complete set: X.d, Xlib.d, Xatom.d, Xproto.d, Xregion.d Xutil.d and
Xinerama.d and xf86vmode.h
--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
More information about the Digitalmars-d
mailing list