On Tue, 13 Aug 2019 10:26:40 +1000 Daniel Kasak <d.j.kasak...@gmail.com> said:

> Thanks! Also ... yikes! So the short version is that this is significantly
> more work than I'd imagined :/
> 
> On Sun, Aug 11, 2019 at 9:54 PM Carsten Haitzler <ras...@rasterman.com>
> wrote:
> 
> > On Sun, 11 Aug 2019 13:36:39 +1000 Daniel Kasak <d.j.kasak...@gmail.com>
> > said:
> > aaah please note: libinput (via elput) is for wayland mode (or specifically
> > wayland mode when targetting drm/kms (framebuffer/tty) as the target). it
> > is
> > not for x11.
> 
> 
> OK. I hadn't given this much thought, other than a blind assumption that
> libinput *would* work for x11. That complicates things.
> 
> so there needs to be a consideration of making the wayland
> > support on par with x11 vs adding new features where both paths then need
> > the
> > support (if it is possible, and if it is not finding an appropriate way of
> > dealing with that situation).
> 
> 
> Well making everything work the same way - with libinput - might be an easy
> way to achieve this? I assume there are reasons why we can't do this?

x11 may have limits via x protocol and may not support all the knobs and
swizzles libinput does... and vice-versa - libinput may hide things or not do
some things so ye olde xinput path can (though this is unlikely as xorg xserver
uses libinput these days... :) - it's an implementation detail though and
everything is abstracted by old long-standing protocols like xinput)

> actually no - e_config is a full data struct. it can contain linked lists,
> > sub
> > structs, arrays - look at anything with E_CONFIG_LIST macros declaring
> > them.
> >
> 
> OK great :)
> 
> > This is where I'm not sure how I would proceed ... ie how would I go about
> > > defining a per-device configuration for things like button mappings? Can
> > I
> > > store a config structure against a key ( maybe not I guess ), or a list?
> >
> > in any way you like - but generally since devices are N - probably a
> > linked list
> > of structs. each struct has some way to identify the device again at
> > runtime
> > (map it to the device info e.g. by name? so string(s) (perhaps multiple).
> > you
> > want to choose a way to map it that will work across systems that have the
> > same
> > device plugged in or across boots/sessions so perhaps device id's is bad...
> > classes of device will be constant as will probably be manufacturer
> > identifier
> > strings, serial numbers provided by the hardware itself etc. -> look at the
> > randr config data. there is a list of configured screens and the code thee
> > uses
> > a combination of gfx card output name (DP0, HDMI-1, etc.) and the edid
> > data. to
> > the randr code this is considered a unique combination (THAT monitor
> > plugged
> > into THAT port). so if that combo is seen again the existing config saved
> > in a
> > list is applied next time - so plug a screen in once, configure it, unplug
> > it,
> > plug it in the next day and it will do exactly what it did last time.
> >
> 
> Got it.
> 
> > I also have no idea of how I'd determine what device was the source of an
> > > event.
> >
> > now you begin to hit the problems. :) you need to do this for both x11 AND
> > wayland i think. you probably need to expand on what you are trying to
> > achieve
> > here. i am guessing you want things like "if i have 2 keyboards plugged in
> > and
> > i press escape on the logitech one over there but not escape on the clanky
> > ibm
> > ps/2 kbd here... i want THAT escape key press to do something different",
> > or
> > same with 2 mice, or a mouse + trackball or 21 active pen devices on a
> > touchscreen?
> >
> 
> Well for me personally, it's just to remap some buttons on my trackball.
> The 1st button is dying from being clicked many times. I map one near it to
> be button 1. I wouldn't want this mapping to be global, as it would screw
> up my laptop touchpad's 1st button. I also set up the ScrollButton feature,
> using this xorg.conf fragment:
> 
> Section "InputClass"
>     Identifier  "Logitech USB Receiver"
>     MatchProduct        "Logitech"
>     Option              "SendCoreEvents" "True"
>     Option              "ButtonMapping" "8 2 3 4 5 6 7 1 9 10 11 12"
>     Option              "ScrollMethod" "button"
>     Option              "ScrollButton" "10"
>     Option              "Tapping" "on"
> EndSection

aaaah all that work for something so simple... :) yeah... unfortunately all
that work is needed ... for something that simple :( but... in your case...
mappings would be done *IN* elput itself. libinput doesn't do this. it'd require
elput itself to have these mappings since elput generates the events for both
e and clients. in x it's a free-for-all where any client can fight over this
stuff and tell the xserver what to do globally at any time. not so in wayland.
compositor is in charge and clients get what they get and don't have much say
in it, and in our case the compositor gets abstratced by elput (efl library).

we support some very simple global button mappings in e like left hand/right
hand button mapping swaps for "the global mouse", global acceleration but never
supported a mapping per device. a bit too niche, but you could do it via
another client in a script if u wanted and run that on startup or xorg conf
files like you did, so it's never been necessary as there is a "backdoor" for
those rare cases.

in wayland there is no free-for-all "backdoor" anymore. compositor does
everything, so... actually in this case... you don't need to touch libinput.
you need to touch elput though.

but to make the logic portable to both you'd need to add appropriate support to
ecore_x's xinput code (ecore_x_xi2.c) and new api's to get/set device
properties and in this case button maps per device. there is a cmdline tool
(xinput) that can do this - try it. it uses the xinput extension (libXi.so)
library to talk xinput protocol to the xserver. ecore_x_xi2.c also uses that
same library and api for doing some magic to listen to touch events explicitly
on windows to get multi-touch to work. thus why that needs extending there
(relying on a cmdline tool is rather hacky and requires the tools be installed
which they are not always, but the library will be). it will mean wrapping up
the device plug/unplug (hierarchy changed / device changed events). etc.

so... for you the work would be in extending ecore_x_xi2.c to do these (need to
then also list devices and get their names etc. so you can identify which is
which), then... the difference between wl and x is e needs to set up the
mapping with elput or with ecore_x api's (and apply it whenever that device is
detected and plugged in at runtime). there needs to be some place to store such
mapping config (as you have already identified) ... and then some way to
configure it (a gui dialog :)). lots of moving parts i know... welcome to
development! :) a hacky script is just not "good enough" when making something
like e :) it has to be clicky-pointy and "automagic" :)

> > for x11 there are core events where you basically have no idea where it
> > comes
> > from. a mouse button 1 press is a mouse button 1 press. you don't know what
> > device produced it. same with keys. all our bindings setup is built around
> > this
> > generic "i got an event but its generic" set of events.
> >
> 
>  So libinput under x11 doesn't allow the kind of per-device config as per
> above? That's harsh.

in your case it'll be done in elput itself. libinput is going to report raw
what the device sends... its the next layer up that has to remap it to
something else here.

> there is an x extension called xinput. ecore_x_xi2.c in efl deals with
> > xinput
> > 2.x ... it mostly abstracts touch events so we can get multitouch data.
> > xinput
> > events have far more extensive info like device id ... which you can then
> > track
> > back to some device data like a name (just run the xinput commandline tool
> > to
> > see what devices you have plugged in and some names - this just uses the
> > xinput
> > extension to query this from x).
> >
> > now elput is the interface to this (on top of libinput) and it wraps up
> > libinput and hides a bunch of details and glues it into the mainloop etc.
> > cutting down the code needed in e to deal with it (and thus sharing that
> > wrapper with efl too so efl apps work directly in the tty too via the same
> > elput wrapper). elput exposes Elput_Device's - you get events when they
> > plug
> > and unplug and you can query device capabilities, name etc. so in many
> > ways it
> > looks like the xinput part of xlib/ecore_x. if you want something more
> > extended
> > you need to look into this as well as xinput and ecore_x and come up with
> > a way
> > of both being equivalent. elput still will need some filling in here to tag
> > events it posts to the event queue (ecore_event_add()) with the correct
> > device
> > identifiers (evas devices) etc. etc. ... yes - it slooks complex. it's a
> > result
> > of years of evolution of the api where it went from wanting to just work
> > on x11
> > to being able to work in the fb (fbcon) to then working on windows and osx
> > too
> > and wayland and e becoming a wayland compositor etc. as well as efl having
> > been
> > split into all these libraries and layers. it'd have been a lot simpler if
> > it
> > were designed from day 0 with this all in mind and as a single library and
> > not
> > a whole bunch of them. :)
> >
> 
> I see. I'm not overly confident that I'm up to that part :)

the way we learn and improve and come out the other side better is by doing
things we haven't done before... :) for me it's a lot about learning about all
the moving parts surrounding a desktop/wm and then gluing it in. i'm 100%
comfortable with the C bits and of course efl/e. what i then focus on is the
bits i do not know. for example bluez5 support... i knuckled down one day
because i wanted my bt mouse to work again. i was going on a trip and i was
tired of plugging in the usb dongles. i wanted my mouse to just work without
any dongles. i sat down and studied the bluez5 dbus protocol docs - studied the
code in bluetoothctl and then wrote test code to "poke it to see how it
wobbles". it did this as a stand-alone tool which just took some arguments and
did printfs on what it saw and then i narrowed down the real behavior and what
the docs actually meant once you made thing wobble and then once i was
confident i had that right ... i ported it into e as a module and gadget. at
least i had the lower end of things "right" by then and could focus on the gui
bits.

for you... i'd do something similar. write just enough code in ecore_x to start
listing devices and getting their properties/names/types etc. ...  and a small
cmdline tool that uses ecore_x and a main loop and listens to those device
change etc. events and prints stuff out. use the xinput tool to do the same
(xinput test-xi2 :)) and see that you get the same stuff... then add the
mapping set/get and code that is even hardcoded to set the mapping. plug/unplug
your device to test. now u have an x path u know works and some ecore_x
additions u know work. now... graft that into e somewhere with a new file that
is meant to set up a listener for such device events on startup/init, query
devices on init and have something that can identify devices e.g. by name and
an apply func. that apply fucn is now where your magic happens. this is where
you now you need config - so design some data structs that allow e to identify
that device and map it to a struct with config data in it for that device. for
now that struct doesn't need much - just some identifiers to match it up. you
now need to begin a config gui too. that means probably extending the current
mouse settings config dialog with a new tab that lists pointer style devices by
name and then allows you do somehow set up a mapping. this will be the
fun/tricky bit... how do u present this to the user in a vaguely useful way
(not just some entry box where they type in 0 1 2 3 etc.). like a proper
structured way which won't involve syntax errors :)

> > > If someone can give me some pointers / examples ... I *might* be able to
> > > add support for per-device mouse configuration, which I think would make
> > > the experience on wayland much nicer :)
> >
> > so you just want to CONFIGURE the mice in wayland mode right?
> 
> 
> Yes :)
> 
> then elput has
> > the api you need to deal with and elput is probably going to need extended
> > api's to configure elput devices - specifically the way you want. reality
> > is...
> > ecore_x+xinput needs this too so you will have to consider both paths. :)
> > both
> > will need extending and any data structs in e need to then probably be
> > generic
> > enough to span both use cases. :)
> >
> 
> I'll look more at this then. As noted above, it seems like the task is
> significantly more complicated than I had 1st imagined, and maybe biting
> off too much for a 1st serious attempt at doing anything in C. Maybe it
> would make sense to tackle some other low-hanging fruit and return to this
> when I'm a but more familiar with things. I'll see ...

it may - or try the stepped approach above.

step 1: write a stand-alone tool that uses ecore+ecore_x and listens to events.
creates a window for the events so u can click on it and get mouse presses...
printf the info out.

step 2: try add some code to ecore_x and Ecore_X.h for the prototypes and enums
and ... then use the code from the tool in step 1. build this up a bit to be
confident of your workflow. it's really not that hard. it's just getting
comfortable with something you haven't done much of before.

step 3: expand step 2 to actually do the work you need (get/set mapping info
per device, list devices and their names and whatever other info, listen to
device changes etc.) and make sure all of this works. gain much more confidence
here.

step 4: now get code from step 2/3 into e so e can see the same thing your tool
does. this is more just choosing a clean name, subsystem and way of doing this
with the right ifdefs and runtime if's to handle this only in x11 compositor
mode. again - printf things out and tail -f ~/.xsession-errors or wherever your
stdout for e goes... u will do a lot of ctrl+alt+end stuff here  restarting e
and seeing the output :) gain confidence here with dealing with e. you know the
code in steps 1-3 works... now just putting it in e nicely

step 5: now begins data structs creating in config that can store data to
map/identify a device on startup or when plugged/unplugged and match it to this
struct. just hardcode putting in a struct in the config by default at this stage
with the data you need to test. printf's for when the device is found on init
or on plug-in (and pritnfs when its disconnected).

step 6: now to add some gui to list devices, their names and to also handle
device plug/unplug in the gui (modify the list). as above - we have a dialog
already for mouse settings... so add a tab there and put it there.

step 7: now expand config struct to store mapping info ... somehow. this is a
design choice as to how to do this... and then also add to the gui to be able
to display and modify this data - depending how you design it. also.. you now
throw in "apply my mappings" in the hypothetical apply func when e sees a new
device plugged in or on start/init when it's already there. the mapping it
applies is from the config.

you're almost done here for the core of the infra, the x11 support code. you
can remove your own xorg conf hack here and have e do it runtime... most of the
hard yards are done... now it's time to do this for wayland:

step 8: now look at elput and you need to get it to have api's to do what you
did in ecore_x AND apply them to the input events from a specific device. doing
this is harder as u need to create an elput client tool and run it in a text
tty to test it - u have to switch to that tty to do this (this is why i am
pointing at wl to be done last). if you feel confident now u can leap right to
doing this in e - but e will need lots of restarts in wl mode and u may lose wl
clients in the process so development here is harder. anyway - this is kind of
steps 1-3 again but a bit less work, just more painful due to the tty/restart
and losing clients situation.

step 9: glue in the wayland support into e where you have the x11 support in
the appropriate ifdefs and runtime if's too - the rest of the gui code and the
abstraction is all done so its more about just filling in the wl path for code
you already tested in x mode and know works there. you should  be confident
here about your code and its just glue and plumbing work.

so that's how i'd recommend doing it. it's how i'd actually do it (though i
may skip steps and jump straight into some of the harder things as i am a bit
more confident of getting things right first go on the bigger components and
can thus take shortcuts - you will eventually be too. it just takes time). :)

this is how i do things myself. i do things in "baby steps" with each step
along the way tested and checked to work. you often don't see those steps from
me as they happen locally in my trees and things get committed hen they are
pretty much at the last steps. sometimes i do the x path and "wayland path to
be done in future" or stuff like that. but you tend to see them towards the
end of their cycle. the above are the invisible things i do that you won't see
in commits. i hope it helps :)


> Thanks for your in-depth response :)
> 
> Dan


-- 
------------- Codito, ergo sum - "I code, therefore I am" --------------
Carsten Haitzler - ras...@rasterman.com



_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to