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