Adding inline helper functions for detection of whether a given Screen
is a master or slave screen.
With PanoramiX enabled, the first one (->myNum == 0) is considered the
master, while the others are slaves. When disabled, all screens are
considered master.
That's allowing us to move some more implementation detail logic out of
DDX/DIX into the extension code and get rid of some ifdef's.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.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>
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>
XFixes 6.1 adds a new feature where individual client can demand immediate
server shutdown when it disconnects: the client can set a special flag via
X_XFixesGetClientDisconnectMode request - when it's set and that client
terminates, the server stops event delivery and shuts down immediately.
It's is mainly a security feature for screen lockers: without it, crashing
screen locker leading to the whole session becoming unlocked. This is now
prevented by immediately killing the xserver, so no unauthorized access
to the session is possible anymore.
Another practical use case is when some critical applications must be present
(eg. in certain control centers), and a crash of those should trigger to
immediate fault state or session restart.
For now, the feature can only be enabled explicitly in the xfree86 DDX,
via the AllowForceTerminate boolean config file option. Not enabled at all
on other DDX'es yet.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
inline CreateConnectionBlock() into PanoramiXCreateConnectionBlock(),
in order to make future refactoring a bit easier. Further steps will
refactor the function to just return the buffer instead of setting
global variables.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
We have to patch up the connection info block with per-client specific
data. Instead of patching up a global buffer, do this in a safe copy.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Factor out the actual rendering to a separate function, which now just
returns x_rpcbuf_t, not directly updating global ConnectionInfo field
(that's left to the caller).
In later iterations, we then could easily generate a new connection info
block per client, eg. masking the available screens based on separate
policies (NEXUS screen remapping, Xnamespace permissions, etc).
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Simplify the code by using x_rpcbuf_t, so we don't need prio block size
calculation and care for allocation / reallocation. rpcbuf is don't it
all for us and giving us the final block size.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Drop the global connSetupPrefix variable and instead create that
tiny struct on the fly (we need to copy it for byteswapping anyways)
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Store it it's own variable as authorative source, so we don't
need to keep it in connSetupPrefix anymore - and get rid of that
in future steps.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Make the code path a bit cleaner and tightly more efficient
(by doing the byteswap directly)
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Panoramix needs a special handling so that we're only sending one
screen (and numRoots becomes = 1). Instead of tweaking global
variables back and forth, just pass in the desired value.
When 0 is passed, using screenInfo.numScreens instead.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Usually, we would use screenInfo.numScreens, but Xinerama has a special
handling that's taking the number from the already compiled ConnectionInfo's
numRoots field.
Actually, we don't need any special handling here, just take the numroots
field, because in non-xinerama case, it's equal to screenInfo.numScreens.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
AddScreen() allocates a new ScreenRec structure, adds it to the global screen
list and then calls the passed ScreenInitProcPtr function for the DDX init.
Right now, this machinery has no way for passing DDX private data into DDX
init, so all DDX'es have to do ugly tricks (eg. using the latest screen number
and global) to access it's private data. That tends to imply various assumptions,
eg. DDX knowing exactly which screen numbers going to be allocated for the yet
to be created screens. It's managable as long as screens are static and DDX is
the only one reserving screen slots, but totally falling once screens get added
or removed at runtime or something something like NEXUS comes around, creating
virtual before the DDX screens.
Therefore, allow DDX passing private data to it's own init functions through
the AddScreen machinery. Upcoming steps will updating the individual DDX'es
to actually use that data, instead of going through global arrays, and also
assigning devPrivate's to their screens, so global table looksups via screen
aren't necessary at all anymore.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
These helpers are always defined, even when compiling w/o PanoramiX
at all (symbol XINERAMA not defined), so we need fewer ifdef's.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
sizes can't have negative numbers, so use the size_t here.
Also having to fix up lots of callers.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Switch all in-tree DIX callers (the modern X_SEND_REPLY_* reply helpers
in request_priv.h, xmitClientEvent() in dix_priv.h, and the direct
callers in dispatch.c, events.c, swaprep.c, dixfonts.c) over to the
internal dixWriteToClient() worker. The exported WriteToClient() stays
as the legacy frontend for out-of-tree modules only.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PR: https://github.com/X11Libre/xserver/pull/3162
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Simplify saveSet handling by just using trivial `struct xorg_list` instead
of complicated dynamically resized array. Common operations like insert or
remove are much simpler using lists instead of arrays.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
* the `GrabInProgress` field isn't used by any known drivers, thus
no need to export it
* the only in-tree consumer outside of it's source file is Xext/saver.c,
which actually just wants to know whether any *other* client already
grabbed the server - asking the OS layer isn't the right source
(should ask dix/dispatch.c instead)
Therefore adding a simple function for that check into dispatch.c (where
grab/ungrab is actually controlled), so we can easily make this internal
field static again.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Replace public min/max macros by private MIN/MAX and deprecate them.
The few drivers still using them can trivially define them on their own.
Adding a new private header for all kind of math-ish definitions - future
commits will move more stuff there.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
For safety, add extra parantheses on each used macro argument.
In most cases not strictly necessary, but better have some strict
and automatically enforcable policy here than wasting time on
judging individual cases.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Let's directly write into the target buffer, instead of first writing
to temporary struct and then memcpy() it into the target buffer.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
QueryColors() fills the red/green/blue fields of each xrgb entry but never
writes the trailing 2-byte pad field. Because the reply buffer was allocated
with the non-zeroing x_rpcbuf_reserve(), those pad bytes leaked uninitialized
server heap to the client (and were even byte-swapped on the swapped path).
Use x_rpcbuf_reserve0() for the xrgb array.
Fixes: 15340ce053 ("dix: ProcQueryColors(): use x_rpcbuf_t")
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
AllocARGBCursor took ownership of the psrcbits/pmaskbits/argb arguments.
But if the initial calloc failed none of them were freed, without the
caller knowing about it. Depending on the code path, those arguments
would thus either leak or be double-freed.
Fix it by always freeing those on error and updating the callers
accordingly.
Assisted-by: Claude:claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2214>
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Mixing result variables for separate things is making the code hard
to understand, so add a new local variable for temporarily storing
the result of ReadRequestFromClient().
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Now that we have untwisted Xinerama side, it's trivial to inline
the few lines for byte-swapping into the actual handlers.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Adding new source and header that's going to host all DIX
settings (set via cmdline or xf86 config file) in the future.
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>