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