Convert the PseudoramiX (XQuartz) request handlers to the
X_REQUEST_HEAD_STRUCT()/X_REQUEST_FIELD_*()/X_REPLY_FIELD_*() macros
from dix/request_priv.h, mirroring the PanoramiX/RRXinerama handlers.
Behaviour-preserving: same size check and conditional byte-swaps.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Convert the RandR-Xinerama request handlers in rrxinerama.c to the
X_REQUEST_HEAD_STRUCT()/X_REQUEST_FIELD_*()/X_REPLY_FIELD_*() macros
from dix/request_priv.h, mirroring the already-converted PanoramiX
handlers in Xext/panoramiX/panoramiX.c. Behaviour-preserving: the
macros expand to the same size check and conditional byte-swaps.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
XvMC is only helpful for old MPEG2 decoding (and here only some specific
part, the motion compensation). It's only supported by few cards, and needs
special client-side drivers, which need to have direct and pretty low-level
(non-DRI) GPU access (usually involving root access).
Since it's local-only anyways, modern clients can use generic GPU shaders
for various video formats (via standard DRI/mesa) and send whole frames.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
AnimCursorCreate allocates an OsTimer even if the cursor is never
displayed. AnimCurUnrealizeCursor releases the retained frame cursors
but does not release that timer, leaking 40 bytes per animated cursor
on the tested x86_64 build.
Free the timer with the frame references on screen zero, and clear the
pointer. This cleanup runs when the final cursor reference is released.
The leak was reproduced with LeakSanitizer on an XLibre 25.1.9-based
test server. With the fix, all 90 focused native ASan/UBSan checks
pass with leak detection enabled and GLX disabled, including unused
animated cursors and repeated displayed cursor replacement.
Signed-off-by: David <david@code.contractors>
Tab indentation, missing spaces before braces and after commas, a
function brace on the declaration line, stray blank lines and a
misaligned comment end.
Also end the "failed to open" error with a newline, so the next log
message doesn't start on the same line.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: galternat <galternat.twins223@simplelogin.com>
ms_try_open() falls back to seatd_libseat_open_graphics() when the
driver can't open the node itself, but every FD from open_hw() is
closed with a plain close(). seatd keeps its own reference to the
device, and the FD stays in seatd-libseat.c's list, where a later open
that reuses the FD number can be mistaken for it.
Export seatd_libseat_close_graphics() and call it before closing an FD
that may have come from open_hw(). It does nothing for an FD that
wasn't opened through seatd, so the driver doesn't have to remember
where each FD came from. drmOpen() FDs of PCI entities and server FDs
aren't closed on these paths.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: galternat <galternat.twins223@simplelogin.com>
xf86_remove_platform_device() frees the attributes with
config_odev_free_attributes(), which gives a server FD back through
systemd_logind_release_fd(): a plain close() without a logind session.
seatd keeps the device open, and the tracked entry is left pointing at
an FD number that can be reused.
Close the device through libseat there, next to the logind release.
config.c is also linked into the kdrive servers, which never open a
device through seatd, so they get an empty stub like the logind ones.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: galternat <galternat.twins223@simplelogin.com>
seatd_libseat_open_graphics() hands the probed GPU's FD to the platform
bus as a server FD. For a driver without SUPPORTS_SERVER_FDS,
doPlatformProbe() gives it back with systemd_logind_release_fd(), which
without a logind session is a plain close(). seatd keeps its own
reference to the same open file and with it DRM master, so the driver's
own open of the node is not master which will cause it to fail.
The libseat device ID was also kept in a single slot that every
seatd_libseat_open_graphics() call overwrote, so with more than one GPU
there was no way to close the right device.
Track the libseat ID per FD and close the device through libseat before
the server FD is dropped.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: galternat <galternat.twins223@simplelogin.com>
When AddResource() fails it calls the type's delete function, which for
pixmaps is dixDestroyPixmap() and drops one reference.
SingleCompositeNameWindowPixmap() increments pPixmap->refcnt before
AddResource(), so a failure only drops that extra reference. The Xinerama
path in ProcCompositeNameWindowPixmap() incremented it afterwards, so a
failure dropped the window's own reference to its backing pixmap and
could free it while still in use. Take the reference first, as the
single-screen path does.
Signed-off-by: Mason Green <mason@greenm01.net>
ProcDestroySubwindows() ignored the result of DestroySubwindows() and
always replied Success. When an XACE hook denies destroying a child,
DestroySubwindows() stops there and returns the error, but the client
was told the request succeeded while some children were left in place.
Return the result instead. This also lets PanoramiXDestroySubwindows()
stop at the first failing screen, which it already checks for.
Signed-off-by: Mason Green <mason@greenm01.net>
ms_gbm.c uses GBM_BO_USE_FRONT_RENDERING, which older libgbm versions
accepted by meson don't provide, so Xmodesetting fails to build against
them. Include drm_defines.h, which defines it to 0 in that case, as the
Xorg modesetting driver does.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: galternat <galternat.twins223@simplelogin.com>
GBM_BO_USE_FRONT_RENDERING is a gbm_bo_flags enum value, so this
#ifndef always redefines it to 0. Nothing in drmmode_display.c has used
it since the front buffer allocation moved to drmmode_bo.c, which gets
the correct fallback from drm_defines.h, as does this file.
Remove it, so a later use here doesn't silently get 0.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: galternat <galternat.twins223@simplelogin.com>
GBM_HAVE_BO_USE_LINEAR and GBM_HAVE_BO_USE_FRONT_RENDERING only say
whether gbm.h provides these flags, but they are left unset whenever
glamor is disabled. When GBM is used without glamor, drm_defines.h
defines both flags as 0, hiding the real ones.
Set them whenever GBM is used.
Fixes: 3b81b8a9b9 ("modesetting: fix defined(GBM_BO_*) enum compile checks")
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: galternat <galternat.twins223@simplelogin.com>
GBM_BO_USE_LINEAR is a gbm_bo_flags enum value, not a macro, so the
#ifdef around it in glamor_make_pixmap_exportable() is always false, and
pixmaps created with CREATE_PIXMAP_USAGE_SHARED don't get a linear BO.
A PRIME sink imports them with only an FD and a stride, so it shows
a scrambled image whenever the primary GPU's driver tiles the buffer.
Drop the guards since drm_defines.h defines GBM_BO_USE_LINEAR to 0 when
libgbm doesn't provide it.
Fixes: b7bf58922f ("modesetting: Check for `GLAMOR` instead of `GLAMOR_HAS_GBM`")
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: galternat <galternat.twins223@simplelogin.com>
NextAvailableClient() stores the new client in clients[i] before
InitClientResources() and InsertFakeRequest(). If either fails, the
client is freed but clients[i] still points at it.
When i is a free slot below currentMaxClients, the next incoming
connection reaches EstablishNewConnections(), which walks
clients[1..currentMaxClients) and dereferences the freed client.
Clear clients[i] on both failure paths before freeing.
Signed-off-by: Mason Green <mason@greenm01.net>
We make two glyphsets, GS1 and GS2, both with the same format depth.
GS1 contains any glyph different from the others, let's call it U
(unique). GS2 contains two glyphs with the same content, or at least
sha1 hash. Let's call them A and B.
We first register GS1 and GS2. GS1 has no problems, but before the
fix, registering GS2 breaks accounting in `globalGlyphs`. Since there
is no check for duplicate glyphs within a single set, we make two
`GlyphNew` entries for A and B. Now in the loop at the end, we go over
each entry and call `AddGlyph` and `FreeGlyph`:
1. AddGlyph(GS2, A, idA) inserts A into `globalGlyphs`
2. FreeGlyph(A) drops A's refcnt by one, but as it's being held in
`globalGlyphs` it's kept alive.
3. AddGlyph(GS2, B, idB) finds A in `globalGlyphs` and reuses it
instead of inserting B
4. FreeGlyph(B) drops B's refcnt by one (to zero), and B is freed.
Before the fix, the lookup in `globalGlyphs` finds A's entry, and
since it isn't a DeletedGlyph, it erroneously removes the
`gr->glyph` pointing to `A` and decrements `tableEntries`. This
results in `tableEntries` being off-by-one as `A` is still alive.
Now, we free the glyphsets in a particular order. Freeing GS1 results
in calling FreeGlyph(U), which will decrement U's refcnt to zero, and
free U. This clears out the entry in `globalGlyphs` for U and
decrements `tableEntries`, which due to the earlier error is now zero.
When `FreeGlyphSet` sees this, it clears the `globalGlyphs` for that
format depth. Now freeing A or GS2 (which transitively frees A) will
try to check the `globalGlyphs` at that format depth, but because it
was cleared out this crashes.
The fix here is to change FreeGlyph to only free a glyph from
`globalGlyphs` that is exactly the glyph being freed, so that
FreeGlyph(B) doesn't touch `globalGlyphs` at all. This keeps a proper
count in `tableEntries` and prevents `globalGlyphs[fdepth]` from being
freed before A is freed.
Closes: #1881
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2264>
(cherry picked from commit 81edc9caf557f7a44c5b308742814457de0eb6c0)
(cherry picked from commit 716d876142280cd66bdcf000f81428dadd5d3937)
Signed-off-by: Octavia Togami <octy@octyl.net>
Commit ee9cb28c3 switched the trampoline's error reporting to
os_log_error(), which only exists on macOS 10.12 and later, breaking the
build for older deployment targets.
Add HAS_OS_LOG to osxcompat.h, keyed on MAC_OS_X_VERSION_MIN_REQUIRED
like the other compat checks, and route logging through
a trampoline_log_error() macro that uses asl_log() when os_log is not
available. The os_log-only %{public}s specifier is wrapped in a PUBLIC_S
macro that expands to plain %s for ASL.
Signed-off-by: Sergey Fedorov <barracuda@macos-powerpc.org>
An OutputClass with neither Driver nor Module ends up in the branch that
extends the default module search path, which dereferences
cl->modulepath without checking it. A class that only sets options, such
as PrimaryGPU, crashes the server during the bus probe.
Leave the search path alone when the class has no ModulePath, as before
per-driver search paths were introduced.
Fixes: 9f25f5d3f1 ("xfree86: make search paths configurable for certain modules")
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: galternat <galternat.twins223@simplelogin.com>
Callers of LoaderSetPath(), eg. xf86PlatformProbe, might pass empty strings
instead of NULL, but those also meaning "not present" (IOW: use default path).
That's leading to spurious "Failed to store module search path" error log
messages for modules that don't have a search path yet.
Instead of adding extra complexity there for transforming empty strings
to NULL pointers, just deal with those here and so make the interface
a bit more robust.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
The Unix-domain socket transport optionally bound a Linux "abstract"
socket (the @/tmp/.X11-unix/Xn variant with a leading NUL in sun_path)
in addition to the classic filesystem socket. Remove that abstract
variant; on Linux the local transport now behaves exactly like on every
other platform: a single Unix-domain socket under /tmp/.X11-unix.
Reasons:
- It is Linux-only. Abstract sockets are a Linux extension that does
not exist on the BSDs, Solaris, macOS, Cygwin, etc., so the feature
was already carried behind #ifdef __linux__ and only ever benefited
one platform while the code had to be maintained for all.
- It carries a fair amount of extra, special-case code for that single
platform: an abstract flag threaded through set_sun_path(),
CreateListener and ResetListener, the leading-NUL / trailing-'@'
sun_path fixups and their bespoke namelen computation, a dedicated
TRANS_ABSTRACT transport flag, and a second ("unix" vs "local")
transport-table entry whose semantics flipped depending on whether
abstract sockets were available. All of that is now gone.
- The classic filesystem socket has to exist anyway. libX11/libxcb
only *prefer* the abstract socket and fall back to the path socket,
and non-abstract clients (and every non-Linux client) need the path
socket regardless. So the abstract socket was never load-bearing:
it was a second, parallel endpoint duplicating one we must keep.
- It is problematic for containers. Abstract sockets live in the
network namespace rather than the mount namespace, so they cannot be
bind-mounted into a container/sandbox and leak across the netns
boundary, unlike the filesystem socket which can be shared (or
withheld) via a bind mount and constrained by filesystem
permissions. Sandboxes (flatpak, firejail, ...) already suppress the
abstract socket for exactly this reason.
- It does not fit the Unix philosophy. "Everything is a file" is the
whole point of a Unix-domain socket; an abstract socket is a name in
an opaque kernel namespace with no filesystem presence, no path, no
ownership and no permission bits. It exists to paper over userspace
lifecycle issues (stale socket files, cleanup on crash) by pushing
them into the kernel instead of solving them in userspace -- the same
kind of "work around a userspace problem inside the kernel" design
that got kdbus rejected [1]. Those userspace problems are already
handled for the path socket (stat/unlink on reset, mkdir of the
socket dir).
No client-visible behaviour changes on a normal desktop: clients that
tried the abstract socket first simply fall back to the filesystem
socket that the server has always also created.
[1] https://lkml.iu.edu/hypermail/linux/kernel/1504.3/02040.html
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
If a dumb gbm buffer cannot be created for a given depth,
but a tiled buffer works, use the tiled buffer and hope it works
Signed-off-by: stefan11111 <stefan11111github@gmail.com>
When the front buffer is tiled, this untextures the root pixmap,
and replaces the tiled bo with a cpu-mapped bo (+ ShadowFB if needed)
In the future, we should probably create a tiled shadow buffer,
and use gl for rotations
Signed-off-by: stefan11111 <stefan11111github@gmail.com>
We change the shadow update on the happy path.
If we later need to bail, we need to restore the old shadow update proc.
This can happen for example when we can't texture the front bo,
and we need to bail back to the cpu-mapped front bo,
and the cpu-mapped front bo was using ShadowFB
Signed-off-by: stefan11111 <stefan11111github@gmail.com>
For most uses, a 64x64 cursor is large enough.
If we are asked for a larger cursor, we allocate and use it then.
A 64x64 should be a good compromise between power usage and complexity.
See: 1f41320e1c
See: https://gitlab.freedesktop.org/xorg/xserver/-/work_items/1922
Signed-off-by: stefan11111 <stefan11111github@gmail.com>
We don't tell RandR about the initial rotation, so it thinks that it needs to
constrains the cursor position to the intersection of the rotated screen and unrotated screen
Wrap `pScreen->ConstrainCursorHarder` and return early when we are initially rotated.
We could instead just tell RandR about out initial rotation and assign new rotations directly
in RRSetConfig.
For now do it like this, revisit later if needed/desired.
Signed-off-by: stefan11111 <stefan11111github@gmail.com>
Discovered a bug where, when Xmodesetting is started with an initially-rotated
screen, the cursor position is incorectly clamped to the unrotated screen width and height.
This doesn't happen when Xmodesetting is started without any rotations and then rotated with xrandr.
Needs investigating
Signed-off-by: stefan11111 <stefan11111github@gmail.com>
Cursor hotspot is intended for virtual setups,
and relies on `DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT`,
which we don't try to set.
Save the glyph's hotspot when loading the cursor sprite
into video card memory, and offset its' hotspot's position
when moving the cursor.
Since we're no longer passing the cursor hotspot to the kernel,
prefer using `drmModeSetCursor` over `drmModeSetCursor2`
See: https://lists.freedesktop.org/archives/wayland-devel/2022-June/042208.html
Signed-off-by: stefan11111 <stefan11111github@gmail.com>
The DRI section isn't used at all for aeons now - just been relevant
for DRI1, which is already gone for over a decade now. Thus no practical
need to carry non-functional remains of it for any longer.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
These builds just taking too long and slowing down all other builds.
Let's only run them on a few branches (eg. baselines) and not on
each single PR or arbitrary pushes.
It's only running on:
- master
- release/*
- qemu/*
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Found out that vkgears doesn't respect the reported DRI3 modifiers on depth 30.
We could check that the requested modifier is supported in the DRI3 request handler,
but I'm not sure it's worth it.
The glamor issue stands regardless, since gl operations can fail for various reasons.
Signed-off-by: stefan11111 <stefan11111github@gmail.com>
When a transient namespace is deleted, XnsDestroyNamespace() frees the
namespace struct, its name, and its authentication tokens. However, it
leaves the virtual root window active in the server's resource database.
Because the virtual root window is never freed, the server leaks a Window
structure, window attributes, and properties every time a temporary
namespace is destroyed.
Fix this leak by calling FreeResource() on the virtual root window
before destroying the namespace.
Also update the formal TLA+ model in doc/Xnamespace.tla to track
resource cleanup and verify the fix.
Signed-off-by: Mason Green <mason@greenm01.net>