tych0 / xcffib

A drop-in replacement for xpyb based on cffi
Apache License 2.0
92 stars 26 forks source link

XIChangeProperty missing a data parameter #49

Closed pascal-de-ladurantaye closed 7 years ago

pascal-de-ladurantaye commented 9 years ago

Hi, thanks for this python binding. As far as I've seen, it's a pretty good alternative to xpyb.

However, I think there's a problem with the binding generator for the XIChangeProperty function.

Here is the generated function:

def XIChangeProperty(self, deviceid, mode, format, property, type, num_items, is_checked=False):
        buf = six.BytesIO()
        buf.write(struct.pack("=xx2xHBBIII", deviceid, mode, format, property, type, num_items))
        return self.send_request(57, buf, is_checked=is_checked)

The problem is that there is no way for us to specify the new data for the property since there is no argument for it.

Here is the command line to disable the mouse (id=8) through a terminal: xinput set-prop 8 --type=int --format=8 136 0

(the 0 at the end is the new data)

This works perfectly, however we would like to have an all python solution through xcffib.

Do you think there's a way to do this through xcffib or do we need to use an os.system call instead?

pascal-de-ladurantaye commented 9 years ago

To clarify, here is the function call we are trying to make (equivalent to the command line call):

conn.xinput.XIChangeProperty(deviceid=8, mode=xcffib.xproto.PropMode.Replace, format=8, property=136, type=xcffib.xproto.Atom.INTEGER, num_items=1, data=0)
tych0 commented 9 years ago

There isn't a way right now, mostly because I didn't know what switch meant when I wrote it:

https://github.com/tych0/xcffib/blob/master/generator/Data/XCB/Python/Parse.hs#L293

However, looking at the xml definition for XIChangeProperty, it's pretty clear what it means, so it should be easy enough to implement. Unfortunately, I'm not sure I'll have time for the next few weeks, but I'd be happy to help if you're interested in taking a crack at it.

pascal-de-ladurantaye commented 9 years ago

Would you be kind enough to tell me where I could find the xml definition for XIChangeProperty?

Thank you

tych0 commented 9 years ago

On Wed, Jun 17, 2015 at 10:23:51AM -0700, Pascal de Ladurantaye wrote:

Would you be kind enough to tell me where I could find the xml definition for XIChangeProperty?

Sure, it is installed on most systems at /usr/share/xcb/xinput.xml, but the upstream repo is:

http://cgit.freedesktop.org/xcb/proto/

Tycho

Thank you


Reply to this email directly or view it on GitHub: https://github.com/tych0/xcffib/issues/49#issuecomment-112883558

pascal-de-ladurantaye commented 9 years ago

For reference purpose:

<request name="XIChangeProperty" opcode="57">
    <field type="DeviceId" name="deviceid" altenum="Device" />
    <field type="CARD8" name="mode" enum="PropMode" />
    <field type="CARD8" name="format" enum="PropertyFormat" />
    <field type="ATOM" name="property" />
    <field type="ATOM" name="type" />
    <field type="CARD32" name="num_items" />
    <switch name="items">
        <fieldref>format</fieldref>
        <!-- <bitcase> is not correct, this would need <cases>s.
                 It works in that case, because PropertyFormat items can be
                 distinguished exactly as their values don't have equal bits.
            -->
        <bitcase>
            <enumref ref="PropertyFormat">8Bits</enumref>
            <list type="CARD8" name="data8">
                <fieldref>num_items</fieldref>
            </list>
        </bitcase>
        <bitcase>
            <enumref ref="PropertyFormat">16Bits</enumref>
            <list type="CARD16" name="data16">
                <fieldref>num_items</fieldref>
            </list>
        </bitcase>
        <bitcase>
            <enumref ref="PropertyFormat">32Bits</enumref>
            <list type="CARD32" name="data32">
                <fieldref>num_items</fieldref>
            </list>
        </bitcase>
    </switch>
</request>
pascal-de-ladurantaye commented 9 years ago

After a look in the code, it seems I don't have the necessary skills to fix this (I've never written anything in Haskell). We have decided to go along with the command line option until this is fixed.

Hopefully, someone will eventually have time to fix this. All the necessary information is documented in this issue.

flacjacket commented 9 years ago

Haskell beginner incoming! So I took a crack at this:

@pascal-de-ladurantaye can you see if #50 does what you need?

@tych0 if you could take a look at it to see if I'm doing anything particularly bad with Haskell?

padele commented 9 years ago

@flacjacket I've built your branch but i was still unable to deactivate my mouse using either:

conn.xinput.XIChangeProperty(deviceid=deviceID, mode=xcffib.xproto.PropMode.Replace, format=8, property=136, type=xcffib.xproto.Atom.INTEGER, num_items=1, items=[0])

or

conn.xinput.XIChangeProperty(deviceid=deviceID, mode=xcffib.xproto.PropMode.Replace, format=8, property=136, type=xcffib.xproto.Atom.INTEGER, num_items=1, items=[False])

where deviceID is 8 as per this information: 8 Name is : PixArt HP USB Optical Mouse Type is : SlaveKeyboard Use is : ExtensionPointer Device is: ENABLED

were you able to deactivate or change any property of a device? Thanks for trying to help and fix this.

pascal-de-ladurantaye commented 9 years ago

Just realised i was logged in with the wrong account

flacjacket commented 9 years ago

I'm not sure exactly how to check if it works, or what I'd expect to happen.

You should try with format=xcffib.xinput.PropertyFormat._8Bits. The if-else block should look like:

if self.format == PropertyFormat._8Bits:
    unpacker.pad("B")
    self.items = xcffib.List(unpacker, "B", self.num_items)
elif self.format == PropertyFormat._16Bits:
    unpacker.pad("H")
    self.items = xcffib.List(unpacker, "H", self.num_items)
elif self.format == PropertyFormat._32Bits:
    unpacker.pad("I")
    self.items = xcffib.List(unpacker, "I", self.num_items)

it should probably have an else that raises an exception...

pascal-de-ladurantaye commented 9 years ago

PropertyFormat._8Bits == 8

this is the generated function:

def XIChangeProperty(self, deviceid, mode, format, property, type, num_items, items, is_checked=False):
        buf = six.BytesIO()
        buf.write(struct.pack("=xx2xHBBIII", deviceid, mode, format, property, type, num_items))
        if format == PropertyFormat._8Bits:
            buf.write(xcffib.pack_list(items, "B"))
        elif format == PropertyFormat._16Bits:
            buf.write(xcffib.pack_list(items, "H"))
        elif format == PropertyFormat._32Bits:
            buf.write(xcffib.pack_list(items, "I"))
        return self.send_request(57, buf, is_checked=is_checked)
flacjacket commented 9 years ago

Oh, yeah, that looks right (at least it was what I was thinking would work). I can see if I can get it working. What is the expected behavior when running that?

pascal-de-ladurantaye commented 9 years ago

you could try it yourself with the command line version:

xinput set-prop --type=int --format=8 136 0

property 136 is ENABLED 0 is for False

The expected behavior is, in my case, a total removal of the mouse pointer in the window manager. That's what i get with the command line interface.

flacjacket commented 9 years ago

So looking at the xcb generated C code, I noticed we aren't always packing things correctly, including this, see #51. I can try to address that and try again.

tych0 commented 7 years ago

I believe this is also fixed with the merging of #50. Please re-open if it is not.