Age | Commit message (Collapse) | Author |
|
|
|
Now that we no longer propagate callback return values, we can safely call
into user-callbacks during sysview_context_stop(). This way, users can
rely on all objects to be removed via callbacks (except if they failed
during object creation). This avoids duplicating any object hashtables on
the users' side and reduces memory consumption.
|
|
We cannot sanely propagate error codes if we call into user-callbacks
multiple times for multiple objects. There is no way to merge those errors
or somehow propagate them.
However, we can just act similar to sd-event and print a log-message while
discarding the values. This way, we allow error-returns, but can properly
continue working on our objects.
|
|
Add "userdata" storage to a bunch of external objects, namely displays and
sessions. Furthermore, add some property retrieval helpers.
This is required if we want external API users to not duplicate our own
object hashtables, but retrieve context from the objects themselves.
|
|
Instead of adding matches per device, we now add logind matches per
session. This reduces the number of matches considerably and saves
resources.
|
|
Instead of raising DEVICE_CHANGE only per device, we now raise it per
device-session attachment. This is what we want for all sysview users,
anyway, as sessions are meant to be independent of each other. Lets avoid
any external session iterators and just do that in sysview itself.
|
|
Whenever we resync an evdev device (or disable it), we should send RESYNC
events to the linked upper layers. This allows to disable key-repeat and
assume some events got dropped.
|
|
The current pause/resume logic kinda intertwines the resume/pause and
enable/disable functions. Lets avoid that non-obvious behavior and always
make resume call into enable, and pause call into disable, if appropriate.
|
|
Whenever a key-event is part of a RESYNC, we should print that verbosely
as those events are out-of-order.
|
|
The GETXY ioctls of DRM are usually called twice by libdrm: Once to
retrieve the number of objects, a second time with suitably sized buffers
to actually retrieve all objects. In grdrm, we avoid these excessive calls
and instead just call ioctls with cached buffers and resize them if they
were too small.
However, connectors need to read the mode list via EDID, which is horribly
slow. As the kernel still cannot do that asynchronously (seriously, we
need to fix this!), it has a hack to only do it if count_modes==0. This is
fine with libdrm, as it calls every ioctl twice, anyway. However, we fail
horribly with this as we usually never pass 0.
Fix this by calling into GETCONNECTOR ioctls twice in case we received an
hotplug event. Only in those cases, we need to re-read modes, so this
should be totally fine.
|
|
Multiple issues here:
1) Don't print excessive card dumps on each resync. Disable it and make
developers add it themselves.
2) Ignore EINVAL on page-flips. Some cards don't support page-flips, so
we'd print it on each frame. Maybe, at some point, the kernel will add
support to retrieve capabilities for that. Until then, simply ignore
it.
3) Replace the now dropped card-dump with a short message about resyncing
the card.
|
|
Whenever we cannot use hardware frame events, we now schedule a virtual
frame event to make sure applications don't have to do this. Usually,
applications render only on data changes, but we can further reduce
render-time by also limiting rendering to vsyncs.
|
|
Whenever a display is added or changed, we suppressed any frame events.
Make sure to raise them manually so we can avoid rendering when handling
anything but FRAME events.
|
|
This helper is quite huge, split it apart to make it easier to follow.
|
|
Whenever we get udev hotplug events, re-read the device state so we
properly detect any changed in the display setups.
|
|
If we get udev-device events via sysview, but they lack devnum
annotations, we know it cannot be a DRM card. Look through it's parents
and treat it as hotplug event in case we find such a card.
This will treat any new/removed connectors as sub-devices of the real
card, instead of as devices on its own.
|
|
Properly forward DEVICE_CHANGE events into grdev so we can react to
changing display setups.
|
|
The high frequency of the color-morphing is kinda irritating. Reduce it
to a much lower frequency so you can actually look at it longer than few
seconds.
|
|
So far, we only forward DRM cards via sysview APIs. However, with MST,
connectors can be hotplugged, too. Forward the connectors as first-level
devices via sysview so API users can react to changing DRM connectors.
|
|
Whe need to react to "change" events on devices, but we want to avoid
duplicating udev-monitors everywhere. Therefore, make sysview forward
change events to the sysview controllers, which can then properly react
to it.
|
|
When deciding what seat a device is on, we have to traverse all parents
to find one with an ID_SEAT tag, otherwise, input devices plugged on a
seated USB-hub are not automatically attached to the right seat. But any
tags on the main device still overwrite the tags of the childs, so fix our
logic to check the device itself first, before traversing the parents.
|
|
The systemd-modeset tool is meant to debug grdev issues. It simply
displays morphing colors on any found display. This is pretty handy to
look for tearing in the backends and debug hotplug issues.
Note that this tool requires systemd-logind to be compiled from git
(there're important fixes that haven't been released, yet).
|
|
The grdev-drm backend manages DRM cards for grdev. Any DRM card with
DUMB_BUFFER support can be used. So far, our policy is to configure all
available connectors, but keep pipes inactive as long as users don't
enable the displays on top.
We hard-code double-buffering so far, but can easily support
single-buffering or n-buffering. We also require XRGB8888 as format as
this is required to be supported by all DRM drivers and it is what VTs
use. This allows us to switch from VTs to grdev via page-flips instead of
deep modesets.
There is still a lot room for improvements in this backend, but it works
smoothly so far so more enhanced features can be added later.
|
|
The grdev layer provides graphics-device access via the
libsystemd-terminal library. It will be used by all terminal helpers to
actually access display hardware.
Like idev, the grdev layer is built around session objects. On each
session object you add/remove graphics devices as they appear and vanish.
Any device type can be supported via specific card-backends. The exported
grdev API hides any device details.
Graphics devices are represented by "cards". Those are hidden in the
session and any pipe-configuration is automatically applied. Out of those,
we configure displays which are then exported to the API user. Displays
are meant as lowest hardware entity available outside of grdev. The
underlying pipe configuration is fully hidden and not accessible from the
outside. The grdev tiling layer allows almost arbitrary setups out of
multiple pipes, but so far we only use a small subset of this. More will
follow.
A grdev-display is meant to represent real connected displays/monitors.
The upper level screen arrangements are user policy and not controlled by
grdev. Applications are free to apply any policy they want.
Real card-backends will follow in later patches.
|
|
We only reject evdev FDs that are O_WRONLY as they're currently pretty
useless. The following check for O_WRONLY is thus never excercised so drop
it.
Thanks to Thomas Andersen (via coverity)!
|
|
The 3 calls to sd_bus_error_get_errno appear to expect a negative
return value.
This patch negates the returned value so it matches the other error
cases in the 3 functions where sd_bus_error_get_errno is used.
|
|
hashmap_new() now takes *_ops instead of individual functions. Fix up any
missing invokations of it that haven't been converted already.
|
|
We currently print weird error-messages if xkbcommon fails (which cannot
fail so far, but might in the future). Fix the uninitialized variable
warnings by setting 'r' correctly.
Thanks to Philippe De Swert for catching this (via coverity).
|
|
This assertion is already there two lines down. Drop the redundant
assertion.
|
|
This might cause >=0 to be returned, even though the method failed. Fix
this and return -errno.
|
|
If we enable a session, any probed device might get immediately enabled.
This might cause TakeDevice() messages to be sent before we call
TakeControl(). Therefore, enable sessions *after* sending TakeControl() so
we always succeed if TakeControl() succeeds.
|
|
We don't use set.h so no need to include it. We used to include it for
temporary refs on all idev devices of a session, but that never was pushed
upstream.
|
|
We define typedefs for all internal types so drop the redundant "struct"
prefix.
|
|
If read() fails on evdev devices, we deal with this in idev_evdev_hup().
It is very likely this is an async revoke, therefore, we must not abort.
Fix our io helper to discard such errors after passing them to
idev_evdev_hup(), so we don't bail out of the event loop.
|
|
|
|
Skipping interfaces randomly without the caller specifying it is nasty.
Avoid this and let the caller do that themselves.
|
|
Don't leak the device-names during device destruction in sysview. Somehow,
the device-name is "const char*", so make it "char*" first to avoid
warnings when calling free() on it.
|
|
Fix leaking the xkb-state during keyboard destruction, leaking lots of xkb
references into the wild.
|
|
In case 'scan_evdev' and 'scan_drm' are both false, we never set 'r' to
anyhting, thus return an uninitialized error code. Fix this by always
returning 0 as we catch negative codes earlier, anyway. Thanks to Thomas
H.P. Anderson for the report.
|
|
|
|
Like systemd-subterm, this new systemd-evcat tool should only be used to
debug libsystemd-terminal. systemd-evcat attaches to the running session
and pushes all evdev devices attached to the current session into an
idev-session. All events of the created idev-devices are then printed to
stdout for input-event debugging.
|
|
The idev-keyboard object provides keyboard devices to the idev interface.
It uses libxkbcommon to provide proper keymap support.
So far, the keyboard implementation is pretty straightforward with one
keyboard device per matching evdev element. We feed everything into the
system keymap and provide proper high-level keyboard events to the
application. Compose-features and IM need to be added later.
|
|
The evdev-element provides linux evdev interfaces as idev-elements. This
way, all real input hardware devices on linux can be used with the idev
interface.
We use libevdev to interface with the kernel. It's a simple wrapper
library around the kernel evdev API that takes care to resync devices
after kernel-queue overflows, which is a rather non-trivial task.
Furthermore, it's a well tested interface used by all other major input
users (Xorg, weston, libinput, ...).
Last but not least, it provides nice keycode to keyname lookup tables (and
vice versa), which is really nice for debugging input problems.
|
|
The idev-interface provides input drivers for all libsystemd-terminal
based applications. It is split into 4 main objects:
idev_context: The context object tracks global state of the input
interface. This will include data like system-keymaps,
xkb contexts and more.
idev_session: A session serves as controller for a set of devices.
Each session on an idev-context is independent of each
other. The session is also the main notification object.
All events raised via idev are reported through the
session interface. Apart of that, the session is a
pretty dumb object that just contains devices.
idev_element: Elements provide real hardware in the idev stack. For
each hardware device, one element is added. Elements
have no knowledge of higher-level device types, they
only provide raw input data to the upper levels. For
example, each evdev device is represented by a different
element in an idev session.
idev_device: Devices are objects that the application deals with. An
application is usually not interested in elements (and
those are hidden to applications), instead, they want
high-level input devices like keyboard, touchpads, mice
and more. Device are the high-level interface provided
by idev. Each device might be fed by a set of elements.
Elements drive the device. If elements are removed,
devices are destroyed. If elements are added, suitable
devices are created.
Applications should monitor the system for sessions and hardware devices.
For each session they want to operate on, they create an idev_session
object and add hardware to that object. The idev interface requires the
application to monitor the system (preferably via sysview_*, but not
required) for hardware devices. Whenever hardware is added to the idev
session, new devices *might* be created. The relationship between hardware
and high-level idev-devices is hidden in the idev-session and not exposed.
Internally, the idev elements and devices are virtual objects. Each real
hardware and device type inherits those virtual objects and provides real
elements and devices. Those types will be added in follow-up commits.
Data flow from hardware to the application is done via idev_*_feed()
functions. Data flow from applications to hardware is done via
idev_*_feedback() functions. Feedback is usually used for LEDs, FF and
similar operations.
|
|
We're going to need multiple binaries that provide session-services via
logind device management. To avoid re-writing the seat/session/device
scan/monitor interface for each of them, this commit adds a generic helper
to libsystemd-terminal:
The sysview interface scans and tracks seats, sessions and devices on a
system. It basically mirrors the state of logind on the application side.
Now, each session-service can listen for matching sessions and
attach to them. On each session, managed device access is provided. This
way, it is pretty simple to write session-services that attach to multiple
sessions (even split across seats).
|
|
|
|
Avoid hard-coding "unsigned long" and use the usec_t type defined in
src/shared.
|
|
Empty format-strings are just fine if format-functions do more than
printing. This is the case here, so suppress the "empty format-string"
warning by using "%s" with an empty argument.
|
|
The unifont layer of libsystemd-terminal provides a fallback font for
situations where no system-fonts are available, or if you don't want to
deal with traditional font-formats for some reasons.
The unifont API mmaps a pre-compiled bitmap font that was generated out of
GNU-Unifont font-data. This guarantees, that all users of the font will
share the pages in memory. Furthermore, the layout of the binary file
allows accessing glyph data in O(1) without pre-rendering glyphs etc. That
is, the OS can skip loading pages for glyphs that we never access.
Note that this is currently a test-run and we want to include the binary
file in the GNU-Unifont package. However, until it was considered stable
and accepted by the maintainers, we will ship it as part of systemd. So
far it's only enabled with the experimental --enable-terminal, anyway.
|
|
|