[PATCH libevdev 0/2] libevdev copy constructor

David Herrmann dh.herrmann at gmail.com
Mon Nov 4 23:41:10 PST 2013


Hi Peter

On Tue, Nov 5, 2013 at 8:31 AM, Peter Hutterer <peter.hutterer at who-t.net> wrote:
> On Mon, Nov 04, 2013 at 03:51:17PM +0100, David Herrmann wrote:
>> I am currently hacking on some input stuff and was wondering what to use to
>> represent "evdev-capabilities". So imagine I have a libevdev object with an
>> attached fd. On top of that I have a re-mapper which fixes some broken
>> device-mappings. Now the remapping should be transparent to the application, so
>> I want to tell the applications the _real_ type/code values of the device, not
>> the raw ones from the kernel.
>>
>> This series introduces libevdev_new_from_libevdev(). I can thus create a copy of
>> an existing libevdev object, then modify the enabled type/codes and pass it to
>> the application as "capability set". The application can query it and see which
>> codes are enabled.
>>
>> Another idea I had is to create an object like:
>>   struct libevdev_caps {
>>     unsigned long bits[NLONGS(EV_CNT)];
>>     unsigned long props[NLONGS(INPUT_PROP_CNT)];
>>     unsigned long key_bits[NLONGS(KEY_CNT)];
>>     unsigned long rel_bits[NLONGS(REL_CNT)];
>>     unsigned long abs_bits[NLONGS(ABS_CNT)];
>>     unsigned long led_bits[NLONGS(LED_CNT)];
>>     unsigned long msc_bits[NLONGS(MSC_CNT)];
>>     unsigned long sw_bits[NLONGS(SW_CNT)];
>>     unsigned long rep_bits[NLONGS(REP_CNT)]; /* convenience, always 1 */
>>     unsigned long ff_bits[NLONGS(FF_CNT)];
>>     unsigned long snd_bits[NLONGS(SND_CNT)];
>>     struct input_absinfo abs_info[ABS_CNT];
>>   };
>> That is, exporting the real bits from libevdev to avoid having a copy of the
>> other data. I doubt that we win anything by this, so I went with my first idea.
>
> main question here is whether this capability would be better off inside
> libevdev? it would be adding complexity, but the question is how much is
> needed, what's the scope etc. and whether the complexity is going to be
> worse than having another layer that takes libevdev and presents it as
> libevdev to the next layer, because then you need to emulate
> libevdev_next_event() behaviour etc.
>
> as soon as you're handing over a libevdev object, the caller will likely
> assume that it can treat it as such, so you'd have to emulate most/all the
> API.
>
> I take it that's for libinputmapper?

Kind of. Still just hacking on stuff to figure our what works and what
doesn't. Note that the copy-constructor would also be highly useful
for uinput devices. Imagine you have an evdev device and want to
create multiple uinput devices similar to it. You could just modify
the source libevdev device, create the uinput device, and then restore
the real libevdev device. But with the copy-constructor, you could
just copy the libevdev device, adjust any bits, create the uinput
device and throw it away afterwards (or keep it as representation of
your uinput device for later queries).

So I think this copy-constructor is useful regardless of the
capability-thing I was talking about.

But ok, lets talk about the other idea:
I wasn't intending to set the "fd" field on the separate libevdev
object. So anyone who gets access to the separate libevdev object
would notice that immediately (get_fd() fails, or any other function
that requires initialized libevdev objects). All they could do is
query the state. No need to emulate libevdev_next_event() or something
else. This object is "dead" and intended to be so.
As I said, the "cleaner" way is probably a libevdev_cap object which
just contains the capabilities. We would embed it in "struct libevdev"
but allow separate access. However, "struct libevdev" itself doesn't
have that much more information than the capabilities, so I thought
this might be overengineering and we should just (mis-)use "struct
libevdev" for it.

Suggestions?

Cheers
David


More information about the Input-tools mailing list