Commit Graph

2527 Commits

Author SHA1 Message Date
Enrico Weigelt, metux IT consult cb56f8fac8 (!1899) dix: make RESOURCE_CLIENT_MASK macro private
Not used in any external modules, so no need to keep it public.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:53 +02:00
Enrico Weigelt, metux IT consult 2e51d88c27 (!1899) dix: make CLIENT_BITS() macro private
Not used by any external drivers, so no need to keep it exported.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:53 +02:00
Enrico Weigelt, metux IT consult 8f83c5397f (!1899) dix: make SERVER_BIT define private
Not used by any external drivers, so no need to keep it exported.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:53 +02:00
Enrico Weigelt, metux IT consult 5d143cf0d5 (!1899) dix: make SameClient() macro private
Not used in any external modules, so need to keep it public.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:53 +02:00
Enrico Weigelt, metux IT consult f04bb746fc (!1899) dix: add dixResouceIsServerOwned()
Little helper function for checking whether a resource XID
belongs to the server itself.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:53 +02:00
Enrico Weigelt, metux IT consult 39a1274411 (!1899) dix: let CreateGrab operate on ClientPtr instead of array index
Almost all callers have ClientPtr anyways, so we're just doing duplicate
array lookups. Just using ClientPtr directly is easier anyways.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:53 +02:00
Enrico Weigelt, metux IT consult 77ebc0baf5 (!1899) dix: add dixClientForXID()
Retrieves the ClientPtr for the owner of given resource.
This way reducing the sites directly accessing clients[] array.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:53 +02:00
Enrico Weigelt, metux IT consult e20bf7d26a (!1899) dix: replace CLIENT_ID() macro by dixClientIdForXID() inline function
Make it type-safe and a bit more obvious what it really does,
also adding some inline documentation. Since it's just some
bit shifting magic, it's qualified for inlining.

The CLIENT_ID() macro isn't used by any external modules, so the
new function doesn't need to be in a public header.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:53 +02:00
Enrico Weigelt, metux IT consult cd454c6b2d (!1899) dix: add dixClientForOtherClients()
Helper function for retrieving the owning client of an OtherClients.

It's an actual function, so callers don't need access to internal
knowledge (definition of struct _OtherClients, clients[] array, ...)

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:53 +02:00
Enrico Weigelt, metux IT consult 3c0482df81 (!1899) dix: add dixClientForInputClients()
Helper function for retrieving the owning client of an InputClients.

It's an actual function, so callers don't need access to internal
knowledge (definition of struct _InputClients, clients[] array, ...)

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:53 +02:00
Enrico Weigelt, metux IT consult c6a21803f6 (!1899) dix: add dixClientForGrab()
Helper function for retrieving the owning client of a grab.

It's an actual function, so callers don't need access to internal
knowledge (definition of GrabRec, clients[] array, ...)

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:52 +02:00
Enrico Weigelt, metux IT consult 14cfff2c5e (!1899) dix: replace wClient() macro by dixClientForWindow() inline function
Hide internals (drop the need to include windowstr.h), make it typesafe
as well as the naming easier to understand.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:52 +02:00
Enrico Weigelt, metux IT consult 4fa4436c79 (!1900) dix: events: clean up XaceHookSendAccess() client arg
Use NullClient macro instead of NULL or 0.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:52 +02:00
Enrico Weigelt, metux IT consult dbeebb5ffb (!1901) dix: resource: protect FakeClientID() from returning 0
Some callers treating XID = 0 as a sign for non-existing resource.
Practically should not happen, but nevertheless adding extra
protection, just in case.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:52 +02:00
Enrico Weigelt, metux IT consult cffc7a83ac (!1393) fix name clash on 'GC' between Xlib and Xserver
Both xlib as well as the Xserver use the same identifier "GC" for
different types. While on xlib it's just the numerical ID of a GC,
the xserver defines a struct for it by the same name. This is this
ugly and needs ridiculous hacks for Xserver code that needs xlib.

Easy to solve by just renaming the GC typedef to GCRec (consistent
with how we're naming other structs) and replacing GC* by GCPtr.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:52 +02:00
Enrico Weigelt, metux IT consult 722d0c0d7f (!1903) dix: CreateColormap() pass in ClientPtr instead of client index
The function actually operates on ClientRec, so we can pass it in
directly, so it doesn't need to fetch it from clients[] array itself.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:52 +02:00
Enrico Weigelt, metux IT consult 9fcd6fb5c5 (!1904) dix: colormap: let AllocColorCells() operate on ClientPtr instead of index
It's only caller already has a pointer to client struct, so no need to
let this function look it up again in the global clients array.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:52 +02:00
Enrico Weigelt, metux IT consult 43fd7595ca (!1918) dix: rename dixLookupClient() to dixLookupResourceOwner()
Choose a bit more precise / descriptive name for that function.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:52 +02:00
Enrico Weigelt, metux IT consult 74f2d68d35 (!1918) dix: dixLookupClient() align parameter naming with prototype
Align the function's parameter names with those defined in the prototype.
Especially it makes code easier to understand if the result parameter
is also named "result" here, as in the prototype.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:52 +02:00
Enrico Weigelt, metux IT consult a35783855c (!1909) dix: use calloc() instead of malloc()
Using calloc() instead of malloc() as preventive measure, so there
never can be any hidden bugs or leaks due uninitialized memory.

The extra cost of using this compiler intrinsic should be practically
impossible to measure - in many cases a good compiler can even deduce
if certain areas really don't need to be zero'd (because they're written
to right after allocation) and create more efficient machine code.

The code pathes in question are pretty cold anyways, so it's probably
not worth even thinking about potential extra runtime costs.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:49 +02:00
Enrico Weigelt, metux IT consult ad1802015d (!1944) treewide: drop COMPOSITE symbol
It's always enabled for very long time now (at least since meson transition),
there doesn't seem to be any need to ever disable it again. So we can reduce
code complexity by removing all the ifdef's.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:47 +02:00
Enrico Weigelt, metux IT consult 608cabe2dc (!1714) dix: add CreateScreenResources callback mechanism
Right now, extensions that need to be called after the CreateScreenResources
proc had been run, must wrap the screen proc vector directly (all of them
forming kind of daisy chain), and so - when called - temporarily restore the
previous one, call it, wrap again, and if the call was successful finally
doing it's own stuff. (same is done for many other procs)

While that approach is looking nice and elegant on the drawing board, it's
complicated, dangerous like a chainsaw and makes debugging hard, leading to
pretty blurred API borders.

Instead introducing a simple approach for letting extension hook into a
post-CreateScreenResources callback list safely, w/o having to care much
about side effects with the call chain. Extensions now can simply register
their business logic and get called back - w/o ever having to mess with the
ScreenRec's internal structures.

Note that these hooks are executed *AFTER* the original CreateScreenResources()
proc had been called SUCCESSFULLY (returned TRUE), so callees can rely on
the DDX/driver had already done it's job.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:47 +02:00
Enrico Weigelt, metux IT consult 4c7eeea81d (!1714) dix: add per-screen pixmap destructor mechanism
Right now, extension specific pixmap destruction procedures are implemented
by wrapping the ScreenRec's DestroyPixmap() proc pointer: the extensions are
storing the original pointer in their private data and putting in their own one.
On each call, their proc restores the original one, calls it, and switches back
again. When multiple extensions doing so, they're forming a kind of daisy chain.
(the same is done for lots of other procs)

While that approach is looking nice and elegant on the drawing board, it's
complicated, dangerous like a chainsaw and makes debugging hard, leading to
pretty blurred API borders.

It's even getting worse: the proc also has to do ref counting, and only destroy
the pixmap if refconter reaching zero - that's all done in the individual screen
drivers. Therefore, all extensions must check for refcnt == 1, in order to know
when to really act.

This commit introduces a simple approach for letting extension hook into the
pixmap destruction safely, w/o having to care much about side effects with
the call chain. Extensions now can simply register their destructor proc
(and an opaque pointer) and get called back - w/o ever having to mess with
the ScreenRec's internal structures.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:47 +02:00
Enrico Weigelt, metux IT consult e6b506d46f (!1714) dix: add per-screen close notify hook
Right now, extension specific actions on screen closing implemented by wrapping
the ScreenRec's PositionWindow() proc pointer: the extensions are storing the
original pointer in their private data and putting in their own one. On each
call, their proc restores the original one, calls it, and switches back again.
When multiple extensions doing so, they're forming a kind of daisy chain.
(the same is done for lots of other procs)

While that approach is looking nice and elegant on the drawing board, it's
complicated, dangerous like a chainsaw and makes debugging hard, leading to
pretty blurred API borders.

This commit introduces a simple approach for letting extension hook into the
screen closing path safely, w/o having to care much about side effects with
the call chain. Extensions now can simply register their hook proc (and an
opaque pointer) and get called back - w/o ever having to mess with the
ScreenRec's internal structures. These hooks are called before the original
vector (usually handled by DDX/screen driver directly) is called.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:46 +02:00
Enrico Weigelt, metux IT consult fc3582a94d (!1714) dbe: use window position notify hook
Wrapping ScreenRec's function pointers is problematic for many reasons,
so use the new window position notify hook instead.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:46 +02:00
Enrico Weigelt, metux IT consult 1ca8724a02 (!1714) dix: add per-screen window position notify hook
Right now, extension specific actions on window positioning are implemented
by wrapping the ScreenRec's PositionWindow() proc pointer: the extensions are
storing the original pointer in their private data and putting in their own one.
On each call, their proc restores the original one, calls it, and switches back
again. When multiple extensions doing so, they're forming a kind of daisy chain.
(the same is done for lots of other procs)

While that approach is looking nice and elegant on the drawing board, it's
complicated, dangerous like a chainsaw and makes debugging hard, leading to
pretty blurred API borders.

This commit introduces a simple approach for letting extension hook into the
window positioning path safely, w/o having to care much about side effects
with the call chain. Extensions now can simply register their hook proc
(and an opaque pointer) and get called back - w/o ever having to mess with
the ScreenRec's internal structures. These hooks are called before the original
vector (usually handled by DDX/screen driver directly) is called.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:46 +02:00
Enrico Weigelt, metux IT consult 3be21f9f8d (!1714) dix: add per-screen window destructor hook
Right now, extension specific window destruction procedures are implemented
by wrapping the ScreenRec's DestroyWindow() proc pointer: the extensions are
storing the original pointer in their private data and putting in their own one.
On each call, their proc restores the original one, calls it, and switches back
again. When multiple extensions doing so, they're forming a kind of daisy chain.
(the same is done for lots of other procs)

While that approach is looking nice and elegant on the drawing board, it's
complicated, dangerous like a chainsaw and makes debugging hard, leading to
pretty blurred API borders.

This commit introduces a simple approach for letting extension hook into the
window destruction safely, w/o having to care much about side effects with
the call chain. Extensions now can simply register their destructor proc
(and an opaque pointer) and get called back - w/o ever having to mess with
the ScreenRec's internal structures.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:45 +02:00
Enrico Weigelt, metux IT consult e7274038c0 (!1714) dix: make DeleteCallbackList() non-static and document it
Allow using it by other places outside this file, so we can also support
callback lists in dynamically allocated structures:

Those cases need to explicitly call DeleteCallbackList() before free()ing
the structures - otherwise we're getting heap corruptions, because the
actual deletion can happen asynchronously.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:45 +02:00
Enrico Weigelt, metux IT consult d18fb54375 (!1905) dix: consolidate screen destruction in dixFreeScreen()
Consolidate duplicated screen destruction logic into new function
dixFreeScreen().

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:45 +02:00
Enrico Weigelt, metux IT consult 59d1e97c3f (!1905) dix: replace FreeDefaultStipple()
It's just a one-liner only called once, so no actual need for it.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:45 +02:00
Enrico Weigelt, metux IT consult 80f02a2c61 (!1905) dix: let FreeGCperDepth() operate on ScreenPtr and NULL protect it
Instead of retrieving the screen index from ScreenRec and passing this,
so the ScreenRec is looked up again, just pass in the ScreenPtr that
already have anyways.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:45 +02:00
Enrico Weigelt, metux IT consult 9b73035d47 (!1905) dix: NULL-protect FreeGC()
Make it possible to call FreeGC() w/o prior NULL checks.
In case of NULL, BadMatch is returned.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:45 +02:00
Enrico Weigelt, metux IT consult 1edbfc803c (!1966) dix: a little bit more startup logging
Adding a little bit more logging to the startup process, eg. telling
when outputs or inputs have been initialized. Serving as a little aid for
debugging driver problems.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:41 +02:00
Enrico Weigelt, metux IT consult 95d76576c9 (!1967) dix: protect input_option_set_value() from NULL pointer
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:41 +02:00
Enrico Weigelt, metux IT consult 4a8eed7247 (!1967) dix: extra NULL safety check in SetClipRects()
Even though it might never be actually hit, it's better to have an
(really cheap) extra check, just in case.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:41 +02:00
Enrico Weigelt, metux IT consult 1d292edd0f (!1967) dix: extra NULL protection in UnmapSubwindows()
Even though it probably won't be hit ever, it's still better to be
really sure instead of some remote chance for hard segfault.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:41 +02:00
Enrico Weigelt, metux IT consult 3dd8d42569 (!1967) dix: clear free()ed pointers on CloseDownExtensions()
As safety precaution, clear the pointers to extion records that just
have been free()ed.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:41 +02:00
Enrico Weigelt, metux IT consult 1f2d207e8c (!1967) dix: NULL-protect AllocGlyphCursor()
Return error to the client if sourcefont turns out to be NULL for
whatever reason.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:41 +02:00
Enrico Weigelt, metux IT consult 4aaf4a6be2 (!1967) dix: devices: refine NULL checks in GetMaster()
The checking / branchin isn't entirely trivial to understand, and the
analyzer also gets confused. So rewrite it in an simpler way that's
easier to understand both the human reader as well as the analyzer.
(and so get rid of yet another false alarm)

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:41 +02:00
Enrico Weigelt, metux IT consult 28fb627126 (!1967) dix: region: turn xfreeData() into inline func and add checks
For type-safety turn xfreeData() macro into an inline function.
Also adding some checks against accidentially free()'ing global data.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:41 +02:00
Enrico Weigelt, metux IT consult 04d7fe797f (!1967) dix: make DeviceEnterLeaveEvent() anaylzer-friendly
The analyzer giving a false alarm on potential NULL-pointer deref here.
Even though that case can't happen, it's also not immediately clear
to the human reader.

To make both the analyzer as well human reader happier, reformulating
this function to by using fast-return pattern.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:41 +02:00
Enrico Weigelt, metux IT consult 7e19399f1a (!1967) dix: protect ChangeWindowDeviceCursor() from allocation failure
On memory allocation failure, return BadAlloc instead of crashing.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:41 +02:00
Enrico Weigelt, metux IT consult ea07763d95 (!1967) dix: dixfonts: explain analyzer false alarm on alleged free() of stack chunk
The analyzer is wrong here, because the free'd closure pointer really points
to some calloc()'d chunk, instead of the PolyText()'s stack frame.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:41 +02:00
Enrico Weigelt, metux IT consult 66ac707d64 (!1967) dix: NULL-protection in GestureAddRegularListener()
protect against the (unlikely) case that inputMasks == NULL.

| ../dix/gestures.c: In function ‘GestureAddRegularListener’:
| ../include/list.h:376:21: warning: dereference of NULL ‘0’ [CWE-476] [-Wanalyzer-null-dereference]
|   376 |         for (_entry = _list; _entry; _entry = (_entry)->_member)
| ../dix/gestures.c:241:9: note: in expansion of macro ‘nt_list_for_each_entry’
|   241 |         nt_list_for_each_entry(iclients, inputMasks->inputClients, next) {
|       |         ^~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:41 +02:00
Enrico Weigelt, metux IT consult 0e9b15f024 (!1967) dix: protect from pScreen->SetCursorPosition == NULL
It's safer not relying on all ScreenProc's actually filled.

../dix/events.c: In function ‘CheckPhysLimits’:
../dix/events.c:780:14: warning: dereference of NULL ‘pScreen’ [CWE-476] [-Wanalyzer-null-dereference]
  780 |             (*pScreen->SetCursorPosition)
      |             ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:41 +02:00
Enrico Weigelt, metux IT consult f5da036e5e (!1967) dix: touch: NULL-protection in TouchAddRegularListener()
protect against the (unlikely) case that inputMasks == NULL.

| ../dix/touch.c: In function ‘TouchAddRegularListener’:
| ../include/list.h:376:21: warning: dereference of NULL ‘0’ [CWE-476] [-Wanalyzer-null-dereference]
|   376 |         for (_entry = _list; _entry; _entry = (_entry)->_member)
| ../dix/touch.c:766:9: note: in expansion of macro ‘nt_list_for_each_entry’
|   766 |         nt_list_for_each_entry(iclients, inputMasks->inputClients, next) {
|       |         ^~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:41 +02:00
Enrico Weigelt, metux IT consult 39172bcab6 (!1967) dix: region: add comments on xfreeData()
Commenting a few aspects need to be considered when using this macro.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:41 +02:00
Enrico Weigelt, metux IT consult 300920ffec (!1967) dix: protect against alloc failure in ‘DeviceFocusEvent()
Fixes analyzer warning:

| ../dix/enterleave.c: In function ‘DeviceFocusEvent’:
| ../dix/enterleave.c:788:20: warning: dereference of possibly-NULL ‘xi2event’ [CWE-690] [-Wanalyzer-possible-null-dereference]
|   788 |     xi2event->type = GenericEvent;
|   ‘DoFocusEvents’: events 1-4

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:41 +02:00
Enrico Weigelt, metux IT consult 65c0c35197 (!1967) dix: move props into WindowRec and fix potential NULL deref
The pointer to the window properties is currently inside the WindowOptional
structure, which may or may not exist at any given time. Thus, before accessing
those fields, at least need to check whether it exists, potentially need to
create it first.

Since a pointer is small (in relation to WindowRec) and windows having properties
is a pretty common, we can make our life much simpler here by moving the pointer
directly into WindowRec, so we don't need extra WindowOptionalRec allocation.

This also fixes an analyzer warning on potential NULL dereference issue:

| ../dix/property.c: In function ‘dixChangeWindowProperty’:
|../dix/property.c:343:37: warning: dereference of NULL ‘*pWin.optional’ [CWE-476] [-Wanalyzer-null-dereference]
|  343 |         pProp->next = pWin->optional->userProps;
|      |                       ~~~~~~~~~~~~~~^~~~~~~~~~~

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:41 +02:00
Enrico Weigelt, metux IT consult 3f31cce8af (!1967) dix: protect doPolyText() from potential NULL dereference
There's a (theoretical) chance that origGC might be NULL, so better
be cautious and check for this - doesn't cost us much, probably just
another JZ instruction.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-05-22 17:34:41 +02:00