Compare commits

...

146 Commits

Author SHA1 Message Date
Enrico Weigelt, metux IT consult 934a299066 ci: fix w64 cross build pkg-config path
pkg-config path is wrong: it's using /usr/share/pkgconfig from the *host*
instead of sysroot, which is leading to wrong pathes.

Fixes: d3933a24d1 - CI: Add an x86 MinGW-w64 cross build
Backport-Of: https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1655
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2024-08-23 15:57:22 +02:00
Olivier Fourdan 68129d7369 build: Drop libxcvt requirement from SDK_REQUIRED_MODULES
The SDK doed not need libxcvt, only Xorg and Xwayland do.

Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1721
Fixes: a4ab57cb7 - build: Add dependency on libxcvt
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1618>
2024-07-23 17:16:15 +02:00
José Expósito 8407181c7d ephyr: Fix incompatible pointer type build error
Fix a compilation error on 32 bits architectures with gcc 14:

  ephyr_glamor_xv.c: In function ‘ephyr_glamor_xv_init’:
  ephyr_glamor_xv.c:154:31: error: assignment to ‘SetPortAttributeFuncPtr’ {aka ‘int (*)(struct _KdScreenInfo *, long unsigned int,  int,  void *)’} from incompatible pointer type ‘int (*)(KdScreenInfo *, Atom,  INT32,  void *)’ {aka ‘int (*)(struct _KdScreenInfo *, long unsigned int,  long int,  void *)’} [-Wincompatible-pointer-types]
    154 |     adaptor->SetPortAttribute = ephyr_glamor_xv_set_port_attribute;
        |                               ^
  ephyr_glamor_xv.c:155:31: error: assignment to ‘GetPortAttributeFuncPtr’ {aka ‘int (*)(struct _KdScreenInfo *, long unsigned int,  int *, void *)’} from incompatible pointer type ‘int (*)(KdScreenInfo *, Atom,  INT32 *, void *)’ {aka ‘int (*)(struct _KdScreenInfo *, long unsigned int,  long int *, void *)’} [-Wincompatible-pointer-types]
    155 |     adaptor->GetPortAttribute = ephyr_glamor_xv_get_port_attribute;
        |                               ^

Build error logs:
https://koji.fedoraproject.org/koji/taskinfo?taskID=111964273

Signed-off-by: José Expósito <jexposit@redhat.com>
(cherry picked from commit e89edec497)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1532>
2024-05-12 08:00:00 +00:00
Matt Turner be2767845d xserver 21.1.13
Signed-off-by: Matt Turner <mattst88@gmail.com>
2024-04-12 13:09:23 -04:00
Olivier Fourdan b4ea6f9eb6 render: Avoid possible double-free in ProcRenderAddGlyphs()
ProcRenderAddGlyphs() adds the glyph to the glyphset using AddGlyph() and
then frees it using FreeGlyph() to decrease the reference count, after
AddGlyph() has increased it.

AddGlyph() however may chose to reuse an existing glyph if it's already
in the glyphSet, and free the glyph that was given, in which case the
caller function, ProcRenderAddGlyphs() will call FreeGlyph() on an
already freed glyph, as reported by ASan:

  READ of size 4 thread T0
    #0 in FreeGlyph xserver/render/glyph.c:252
    #1 in ProcRenderAddGlyphs xserver/render/render.c:1174
    #2 in Dispatch xserver/dix/dispatch.c:546
    #3 in dix_main xserver/dix/main.c:271
    #4 in main xserver/dix/stubmain.c:34
    #5 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #6 in __libc_start_main_impl ../csu/libc-start.c:360
    #7  (/usr/bin/Xwayland+0x44fe4)
  Address is located 0 bytes inside of 64-byte region
  freed by thread T0 here:
    #0 in __interceptor_free libsanitizer/asan/asan_malloc_linux.cpp:52
    #1 in _dixFreeObjectWithPrivates xserver/dix/privates.c:538
    #2 in AddGlyph xserver/render/glyph.c:295
    #3 in ProcRenderAddGlyphs xserver/render/render.c:1173
    #4 in Dispatch xserver/dix/dispatch.c:546
    #5 in dix_main xserver/dix/main.c:271
    #6 in main xserver/dix/stubmain.c:34
    #7 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
  previously allocated by thread T0 here:
    #0 in __interceptor_malloc libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 in AllocateGlyph xserver/render/glyph.c:355
    #2 in ProcRenderAddGlyphs xserver/render/render.c:1085
    #3 in Dispatch xserver/dix/dispatch.c:546
    #4 in dix_main xserver/dix/main.c:271
    #5 in main xserver/dix/stubmain.c:34
    #6 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
  SUMMARY: AddressSanitizer: heap-use-after-free xserver/render/glyph.c:252 in FreeGlyph

To avoid that, make sure not to free the given glyph in AddGlyph().

v2: Simplify the test using the boolean returned from AddGlyph() (Michel)
v3: Simplify even more by not freeing the glyph in AddGlyph() (Peter)

Fixes: bdca6c3d1 - render: fix refcounting of glyphs during ProcRenderAddGlyphs
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1659
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1476>
(cherry picked from commit 337d8d48b6)
2024-04-09 09:26:21 +02:00
Willem Jan Palenstijn f54647dfa6 mi: fix rounding issues around zero in miPointerSetPosition
Fixes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/577

This patch replaces the instances of trunc in miPointerSetPosition by
floor, thereby removing the incorrect behaviour with subpixel pointer
locations between -1 and 0.

This is the relevant code fragment:

    /* In the event we actually change screen or we get confined, we just
     * drop the float component on the floor
     * FIXME: only drop remainder for ConstrainCursorHarder, not for screen
     * crossings */
    if (x != trunc(*screenx))
        *screenx = x;
    if (y != trunc(*screeny))
        *screeny = y;

The behaviour of this code does not match its comment for subpixel
coordinates between -1 and 0. For example, if *screenx is -0.5, the
preceding code would (correctly) clamp x to 0, but this would not be
detected by this condition, since 0 == trunc(-0.5), leaving *screenx
at -0.5, out of bounds.

This causes undesirable behaviour in GTK3 code using xi2, where negative
subpixel coordinates like this would (to all appearances randomly)
remove the focus from windows aligned with the zero boundary when the
mouse hits the left or top screen boundaries.

The other occurences of trunc in miPointerSetPosition have a more subtle
effect which would prevent proper clamping if there is a pointer limit
at a negative integer rather than at 0. This patch changes these to
floor for consistency.

Signed-off-by: Willem Jan Palenstijn <wjp@usecode.org>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1451>
(cherry picked from commit 0ee4ed286e)
2024-04-05 13:46:40 +10:00
Povilas Kanapickas 101caa1b03 xserver 21.1.12
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2024-04-03 23:43:57 +03:00
Peter Hutterer 1173156404 render: fix refcounting of glyphs during ProcRenderAddGlyphs
Previously, AllocateGlyph would return a new glyph with refcount=0 and a
re-used glyph would end up not changing the refcount at all. The
resulting glyph_new array would thus have multiple entries pointing to
the same non-refcounted glyphs.

AddGlyph may free a glyph, resulting in a UAF when the same glyph
pointer is then later used.

Fix this by returning a refcount of 1 for a new glyph and always
incrementing the refcount for a re-used glyph, followed by dropping that
refcount back down again when we're done with it.

CVE-2024-31083, ZDI-CAN-22880

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1463>
(cherry picked from commit bdca6c3d1f)
2024-04-03 19:37:08 +03:00
Alan Coopersmith 0e34d8ebc9 Xquartz: ProcAppleDRICreatePixmap needs to use unswapped length to send reply
CVE-2024-31082

Fixes: 14205ade0 ("XQuartz: appledri: Fix byte swapping in replies")
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1463>
(cherry picked from commit 6c684d035c)
2024-04-03 19:35:46 +03:00
Alan Coopersmith cea92ca78f Xi: ProcXIPassiveGrabDevice needs to use unswapped length to send reply
CVE-2024-31081

Fixes: d220d6907 ("Xi: add GrabButton and GrabKeysym code.")
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1463>
(cherry picked from commit 3e77295f88)
2024-04-03 19:35:39 +03:00
Alan Coopersmith 8a7cd0e3ef Xi: ProcXIGetSelectedEvents needs to use unswapped length to send reply
CVE-2024-31080

Reported-by: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=69762
Fixes: 53e821ab4 ("Xi: add request processing for XIGetSelectedEvents.")
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1463>
(cherry picked from commit 96798fc196)
2024-04-03 19:35:30 +03:00
Alan Coopersmith 5ca3a95135 Xext: SProcSyncCreateFence needs to swap drawable id too
Otherwise it causes the server to return BadDrawable giving a
byte-swapped resource id instead of the real id the client sent.

Reported-by: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=69762
Fixes: 397dfd9f8 ("Create/Destroy/Trigger/Reset/Query Fence Sync objs")
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
---
(cherry picked from commit e6573baa7d)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1438>
2024-03-27 19:39:19 +00:00
Peter Hutterer 5d7272f05d Allow disabling byte-swapped clients
The X server swapping code is a huge attack surface, much of this code
is untested and prone to security issues. The use-case of byte-swapped
clients is very niche, so allow users to disable this if they don't
need it, using either a config option or commandline flag.

For Xorg, this adds the ServerFlag "AllowByteSwappedClients" "off".
For all DDX, this adds the commandline options +byteswappedclients and
-byteswappedclients to enable or disable, respectively.

Fixes #1201
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
---
(cherry picked from commit 412777664a)
(cherry picked from commit af5cd5acc9012e527ee869f8e98bf6c2e9a02ca4)
Backport to server-21.1-branch modified to keep byte-swapping enabled
by default but easy to disable by users or admins (or even by distros
shipping an xorg.conf.d fragment in their packages).

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1440>
2024-03-23 14:42:15 -07:00
Matthieu Herrb 8a46a463f6 Initialize Mode->name in xf86CVTMode()
This was overlooked when converting the function to use libxcvt.
Bring back name initialization from old code.

This was causing a segfault in xf86LookupMode() if modes where
name is NULL are present the modePool list.

Signed-off-by: Matthieu Herrb <matthieu@herrb.eu>
---
(cherry picked from ed11c4d443)

Reported-by: "Sergiy" <Black_N@ukr.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1319>
2024-02-23 00:01:10 +00:00
Yusuf Khan f653d9a0af hw/xfree86: fix NULL pointer refrence to mode name
Potentially, the pointer to the mode name could be unset, this can
occur with the xf86-video-nv DDX, in that case there isnt much we can do
except check if the next mode is any better.

Signed-off-by: Yusuf Khan <yusisamerican@gmail.com>
---
(cherry picked from db3aa4e03b)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1309>
2024-02-19 10:12:03 +00:00
Povilas Kanapickas 8b75ec34df dix: Fix use after free in input device shutdown
This fixes access to freed heap memory via dev->master. E.g. when
running BarrierNotify.ReceivesNotifyEvents/7 test from
xorg-integration-tests:

==24736==ERROR: AddressSanitizer: heap-use-after-free on address
0x619000065020 at pc 0x55c450e2b9cf bp 0x7fffc532fd20 sp 0x7fffc532fd10
READ of size 4 at 0x619000065020 thread T0
    #0 0x55c450e2b9ce in GetMaster ../../../dix/devices.c:2722
    #1 0x55c450e9d035 in IsFloating ../../../dix/events.c:346
    #2 0x55c4513209c6 in GetDeviceUse ../../../Xi/xiquerydevice.c:525
../../../Xi/xichangehierarchy.c:95
    #4 0x55c450e3455c in RemoveDevice ../../../dix/devices.c:1204
../../../hw/xfree86/common/xf86Xinput.c:1142
    #6 0x55c450e17b04 in CloseDeviceList ../../../dix/devices.c:1038
    #7 0x55c450e1de85 in CloseDownDevices ../../../dix/devices.c:1068
    #8 0x55c450e837ef in dix_main ../../../dix/main.c:302
    #9 0x55c4517a8d93 in main ../../../dix/stubmain.c:34
(/lib/x86_64-linux-gnu/libc.so.6+0x28564)
    #11 0x55c450d0113d in _start (/usr/lib/xorg/Xorg+0x117713d)

0x619000065020 is located 160 bytes inside of 912-byte region
[0x619000064f80,0x619000065310)
freed by thread T0 here:
(/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10d7cf)
    #1 0x55c450e19f1c in CloseDevice ../../../dix/devices.c:1014
    #2 0x55c450e343a4 in RemoveDevice ../../../dix/devices.c:1186
../../../hw/xfree86/common/xf86Xinput.c:1142
    #4 0x55c450e17b04 in CloseDeviceList ../../../dix/devices.c:1038
    #5 0x55c450e1de85 in CloseDownDevices ../../../dix/devices.c:1068
    #6 0x55c450e837ef in dix_main ../../../dix/main.c:302
    #7 0x55c4517a8d93 in main ../../../dix/stubmain.c:34
(/lib/x86_64-linux-gnu/libc.so.6+0x28564)

previously allocated by thread T0 here:
(/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10ddc6)
    #1 0x55c450e1c57b in AddInputDevice ../../../dix/devices.c:259
    #2 0x55c450e34840 in AllocDevicePair ../../../dix/devices.c:2755
    #3 0x55c45130318f in add_master ../../../Xi/xichangehierarchy.c:152
../../../Xi/xichangehierarchy.c:465
    #5 0x55c4512cb9f5 in ProcIDispatch ../../../Xi/extinit.c:390
    #6 0x55c450e6a92b in Dispatch ../../../dix/dispatch.c:551
    #7 0x55c450e834b7 in dix_main ../../../dix/main.c:272
    #8 0x55c4517a8d93 in main ../../../dix/stubmain.c:34
(/lib/x86_64-linux-gnu/libc.so.6+0x28564)

The problem is caused by dev->master being not reset when disabling the
device, which then causes dangling pointer when the master device itself
is being deleted when exiting whole server.

Note that RecalculateMasterButtons() requires dev->master to be still
valid, so we can reset it only at the end of function.

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
(cherry picked from commit 1801fe0ac3)
2024-01-22 15:14:21 +10:00
José Expósito 31407c0199 xserver 21.1.11
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
2024-01-16 10:15:15 +01:00
Olivier Fourdan a4f0e9466f ephyr,xwayland: Use the proper private key for cursor
The cursor in DIX is actually split in two parts, the cursor itself and
the cursor bits, each with their own devPrivates.

The cursor itself includes the cursor bits, meaning that the cursor bits
devPrivates in within structure of the cursor.

Both Xephyr and Xwayland were using the private key for the cursor bits
to store the data for the cursor, and when using XSELINUX which comes
with its own special devPrivates, the data stored in that cursor bits'
devPrivates would interfere with the XSELINUX devPrivates data and the
SELINUX security ID would point to some other unrelated data, causing a
crash in the XSELINUX code when trying to (re)use the security ID.

CVE-2024-0409

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 2ef0f1116c)
2024-01-16 10:00:37 +01:00
Olivier Fourdan 8d825f72da glx: Call XACE hooks on the GLX buffer
The XSELINUX code will label resources at creation by checking the
access mode. When the access mode is DixCreateAccess, it will call the
function to label the new resource SELinuxLabelResource().

However, GLX buffers do not go through the XACE hooks when created,
hence leaving the resource actually unlabeled.

When, later, the client tries to create another resource using that
drawable (like a GC for example), the XSELINUX code would try to use
the security ID of that object which has never been labeled, get a NULL
pointer and crash when checking whether the requested permissions are
granted for subject security ID.

To avoid the issue, make sure to call the XACE hooks when creating the
GLX buffers.

Credit goes to Donn Seeley <donn@xmission.com> for providing the patch.

CVE-2024-0408

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit e5e8586a12)
2024-01-16 09:58:09 +01:00
Peter Hutterer 5c4816afa7 dix: when disabling a master, float disabled slaved devices too
Disabling a master device floats all slave devices but we didn't do this
to already-disabled slave devices. As a result those devices kept their
reference to the master device resulting in access to already freed
memory if the master device was removed before the corresponding slave
device.

And to match this behavior, also forcibly reset that pointer during
CloseDownDevices().

Related to CVE-2024-21886, ZDI-CAN-22840

(cherry picked from commit 26769aa71f)
2024-01-16 09:58:06 +01:00
José Expósito 7b5694368b Xi: do not keep linked list pointer during recursion
The `DisableDevice()` function is called whenever an enabled device
is disabled and it moves the device from the `inputInfo.devices` linked
list to the `inputInfo.off_devices` linked list.

However, its link/unlink operation has an issue during the recursive
call to `DisableDevice()` due to the `prev` pointer pointing to a
removed device.

This issue leads to a length mismatch between the total number of
devices and the number of device in the list, leading to a heap
overflow and, possibly, to local privilege escalation.

Simplify the code that checked whether the device passed to
`DisableDevice()` was in `inputInfo.devices` or not and find the
previous device after the recursion.

CVE-2024-21886, ZDI-CAN-22840

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

(cherry picked from commit bc1fdbe465)
2024-01-16 09:58:02 +01:00
Peter Hutterer 6236342157 Xi: flush hierarchy events after adding/removing master devices
The `XISendDeviceHierarchyEvent()` function allocates space to store up
to `MAXDEVICES` (256) `xXIHierarchyInfo` structures in `info`.

If a device with a given ID was removed and a new device with the same
ID added both in the same operation, the single device ID will lead to
two info structures being written to `info`.

Since this case can occur for every device ID at once, a total of two
times `MAXDEVICES` info structures might be written to the allocation.

To avoid it, once one add/remove master is processed, send out the
device hierarchy event for the current state and continue. That event
thus only ever has exactly one of either added/removed in it (and
optionally slave attached/detached).

CVE-2024-21885, ZDI-CAN-22744

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

(cherry picked from commit 4a5e9b1895)
2024-01-16 09:57:59 +01:00
Peter Hutterer 8887cb1f27 Xi: when creating a new ButtonClass, set the number of buttons
There's a racy sequence where a master device may copy the button class
from the slave, without ever initializing numButtons. This leads to a
device with zero buttons but a button class which is invalid.

Let's copy the numButtons value from the source - by definition if we
don't have a button class yet we do not have any other slave devices
with more than this number of buttons anyway.

CVE-2024-0229, ZDI-CAN-22678

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

(cherry picked from commit df3c65706e)
2024-01-16 09:57:55 +01:00
Peter Hutterer 7173a8911e dix: fix DeviceStateNotify event calculation
The previous code only made sense if one considers buttons and keys to
be mutually exclusive on a device. That is not necessarily true, causing
a number of issues.

This function allocates and fills in the number of xEvents we need to
send the device state down the wire.  This is split across multiple
32-byte devices including one deviceStateNotify event and optional
deviceKeyStateNotify, deviceButtonStateNotify and (possibly multiple)
deviceValuator events.

The previous behavior would instead compose a sequence
of [state, buttonstate, state, keystate, valuator...]. This is not
protocol correct, and on top of that made the code extremely convoluted.

Fix this by streamlining: add both button and key into the deviceStateNotify
and then append the key state and button state, followed by the
valuators. Finally, the deviceValuator events contain up to 6 valuators
per event but we only ever sent through 3 at a time. Let's double that
troughput.

CVE-2024-0229, ZDI-CAN-22678

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

(cherry picked from commit 219c54b8a3)
2024-01-16 09:57:52 +01:00
Peter Hutterer c494debaa7 dix: Allocate sufficient xEvents for our DeviceStateNotify
If a device has both a button class and a key class and numButtons is
zero, we can get an OOB write due to event under-allocation.

This function seems to assume a device has either keys or buttons, not
both. It has two virtually identical code paths, both of which assume
they're applying to the first event in the sequence.

A device with both a key and button class triggered a logic bug - only
one xEvent was allocated but the deviceStateNotify pointer was pushed on
once per type. So effectively this logic code:

   int count = 1;
   if (button && nbuttons > 32) count++;
   if (key && nbuttons > 0) count++;
   if (key && nkeys > 32) count++; // this is basically always true
   // count is at 2 for our keys + zero button device

   ev = alloc(count * sizeof(xEvent));
   FixDeviceStateNotify(ev);
   if (button)
     FixDeviceStateNotify(ev++);
   if (key)
     FixDeviceStateNotify(ev++);   // santa drops into the wrong chimney here

If the device has more than 3 valuators, the OOB is pushed back - we're
off by one so it will happen when the last deviceValuator event is
written instead.

Fix this by allocating the maximum number of events we may allocate.
Note that the current behavior is not protocol-correct anyway, this
patch fixes only the allocation issue.

Note that this issue does not trigger if the device has at least one
button. While the server does not prevent a button class with zero
buttons, it is very unlikely.

CVE-2024-0229, ZDI-CAN-22678

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

(cherry picked from commit ece23be888)
2024-01-16 09:57:49 +01:00
Peter Hutterer 4e78bc3a6e dix: allocate enough space for logical button maps
Both DeviceFocusEvent and the XIQueryPointer reply contain a bit for
each logical button currently down. Since buttons can be arbitrarily mapped
to anything up to 255 make sure we have enough bits for the maximum mapping.

CVE-2023-6816, ZDI-CAN-22664, ZDI-CAN-22665

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

(cherry picked from commit 9e2ecb2af8)
2024-01-16 09:57:45 +01:00
Michael Wyraz c338d19f74 Removing the code that deletes an existing monitor in RRMonitorAdd
In commit 7e1f86d4 monitor support was added to randr. At this time it seemed to be reasonable not to have
more than one (virtual) monitor on a particular physical display. The code was never changed since.

Nowadays, extremely large displays exists (4k displays, ultra-wide displays). In some use cases it makes sense to
split these large physical displays into multiple virtual monitors. An example are ultra-wide screens that can be
split into 2 monitors. The change in this commit makes this work.

Besides that, removing a monitor in a function that is called "RRMonitorAdd" is bad practice and causes
unexpected behaviour.
2024-01-03 08:42:34 +01:00
Peter Hutterer 15e2409776 xserver 21.1.10
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-12-13 11:12:59 +10:00
Peter Hutterer a7bda3080d Xi: allocate enough XkbActions for our buttons
button->xkb_acts is supposed to be an array sufficiently large for all
our buttons, not just a single XkbActions struct. Allocating
insufficient memory here means when we memcpy() later in
XkbSetDeviceInfo we write into memory that wasn't ours to begin with,
leading to the usual security ooopsiedaisies.

CVE-2023-6377, ZDI-CAN-22412, ZDI-CAN-22413

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

(cherry picked from commit 0c1a93d319)
2023-12-13 11:00:15 +10:00
Peter Hutterer 58e83c6839 randr: avoid integer truncation in length check of ProcRRChange*Property
Affected are ProcRRChangeProviderProperty and ProcRRChangeOutputProperty.
See also xserver@8f454b79 where this same bug was fixed for the core
protocol and XI.

This fixes an OOB read and the resulting information disclosure.

Length calculation for the request was clipped to a 32-bit integer. With
the correct stuff->nUnits value the expected request size was
truncated, passing the REQUEST_FIXED_SIZE check.

The server then proceeded with reading at least stuff->num_items bytes
(depending on stuff->format) from the request and stuffing whatever it
finds into the property. In the process it would also allocate at least
stuff->nUnits bytes, i.e. 4GB.

CVE-2023-6478, ZDI-CAN-22561

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

(cherry picked from commit 14f480010a)
2023-12-13 11:00:13 +10:00
nerdopolis c1ad8df2fc xephyr: Don't check for SeatId anymore
After a change for the xserver to automatically determine the seat
based on the XDG_SEAT variable, xephyr stopped working. This was
because of an old feature where xephyr used to handle evdev
directly. This was dropped some time ago, and now this check is
not needed

(cherry picked from commit 4c03b67d33)
2023-10-25 11:35:42 -04:00
Peter Hutterer 6197bea02e xserver 21.1.9
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-10-25 11:05:28 +10:00
Peter Hutterer 3e290b3c7c mi: reset the PointerWindows reference on screen switch
PointerWindows[] keeps a reference to the last window our sprite
entered - changes are usually handled by CheckMotion().

If we switch between screens via XWarpPointer our
dev->spriteInfo->sprite->win is set to the new screen's root window.
If there's another window at the cursor location CheckMotion() will
trigger the right enter/leave events later. If there is not, it skips
that process and we never trigger LeaveWindow() - PointerWindows[] for
the device still refers to the previous window.

If that window is destroyed we have a dangling reference that will
eventually cause a use-after-free bug when checking the window hierarchy
later.

To trigger this, we require:
- two protocol screens
- XWarpPointer to the other screen's root window
- XDestroyWindow before entering any other window

This is a niche bug so we hack around it by making sure we reset the
PointerWindows[] entry so we cannot have a dangling pointer. This
doesn't handle Enter/Leave events correctly but the previous code didn't
either.

CVE-2023-5380, ZDI-CAN-21608

This vulnerability was discovered by:
Sri working with Trend Micro Zero Day Initiative

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit 564ccf2ce9)
2023-10-25 10:51:18 +10:00
Peter Hutterer f2922f6ffa Xi/randr: fix handling of PropModeAppend/Prepend
The handling of appending/prepending properties was incorrect, with at
least two bugs: the property length was set to the length of the new
part only, i.e. appending or prepending N elements to a property with P
existing elements always resulted in the property having N elements
instead of N + P.

Second, when pre-pending a value to a property, the offset for the old
values was incorrect, leaving the new property with potentially
uninitalized values and/or resulting in OOB memory writes.
For example, prepending a 3 element value to a 5 element property would
result in this 8 value array:
  [N, N, N, ?, ?, P, P, P ] P, P
                            ^OOB write

The XI2 code is a copy/paste of the RandR code, so the bug exists in
both.

CVE-2023-5367, ZDI-CAN-22153

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 541ab2ecd4)
2023-10-25 10:51:17 +10:00
Sam James 2c33ee9f1d Switch to libbsd-overlay
This is more portable than libbsd as everything Just Works, even on BSD systems,
and is the recommended method of consuming libbsd nowadays.

It also helpfully lets things work with glibc-provided functions for new
enough glibc.

[For the 21.1.x backport, take inspiration from @alanc's commit to libxdmcp
at c01da8ebd0.]

Closes: https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/973
Co-authored-by: Guillem Jover <guillem@hadrons.org>
(cherry picked from commit 94945a5274)
Signed-off-by: Sam James <sam@gentoo.org>
2023-10-23 23:30:14 -04:00
Adam Jackson b98fc07d34 present: Send a PresentConfigureNotify event for destroyed windows
This enables fixing a deadlock case on the client side, where the client
ends up blocked waiting for a Present event that will never come because
the window was destroyed. The new PresentWindowDestroyed flag allows the
client to avoid blocking indefinitely.

Signed-off-by: Adam Jackson <ajax@redhat.com>
See-also: https://gitlab.freedesktop.org/mesa/mesa/-/issues/116
See-also: https://gitlab.freedesktop.org/mesa/mesa/-/issues/6685
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
(cherry picked from commit 462b06033e)
2023-04-24 10:13:27 +02:00
Olivier Fourdan 7c791b1550 xserver 21.1.8
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2023-03-29 14:20:26 +02:00
Olivier Fourdan fb51d5dd53 composite: Fix use-after-free of the COW
ZDI-CAN-19866/CVE-2023-1393

If a client explicitly destroys the compositor overlay window (aka COW),
we would leave a dangling pointer to that window in the CompScreen
structure, which will trigger a use-after-free later.

Make sure to clear the CompScreen pointer to the COW when the latter gets
destroyed explicitly by the client.

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit 26ef545b35)
2023-03-29 14:20:26 +02:00
Benno Schulenberg 6bed5cfd51 xkbUtils: use existing symbol names instead of deleted deprecated ones
Symbols `XK_Cyrillic_DZHE` and `XK_Serbian_DZE` were pure synonyms.

(cherry picked from commit 6153c71cfb)
2023-03-29 10:14:00 +02:00
Peter Hutterer af9111ac7f xserver 21.1.7
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-02-07 10:30:59 +10:00
Peter Hutterer 9ca7d3f61a Xi: fix potential use-after-free in DeepCopyPointerClasses
CVE-2023-0494, ZDI-CAN-19596

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 0ba6d8c370)
2023-02-07 10:21:52 +10:00
Mike Gorse 4b925d388f dix: Use CopyPartialInternalEvent in EnqueueEvent
The event might be a DeviceEvent allocated on the stack, in
AccessXKeyboardEvent for instance. Fixes out-of-bounds read.

Signed-off-by: Mike Gorse <mgorse@suse.com>
(cherry picked from commit 2ef5ef57bd)
2023-02-07 10:21:52 +10:00
Jeremy Huddleston Sequoia 44d6c82ac8 darwin: Implement DetermineClientCmd for macOS
Withoug a proper implementation of DetermineClientCmd, clients that
connect via an ssh tunnel are miscategorized as local.  This results
in failures when we try to use SCM_RIGHTS (eg: in MIT-SHM).

Fixes: https://github.com/XQuartz/XQuartz/issues/314
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 0ea9b59589)
2023-01-26 09:56:12 -08:00
Jeremy Huddleston Sequoia 1317083fbc os: Use LOCAL_PEERPID from sys/un.h if it is available to detemine the pid when falling back on getpeereids()
This provides a way to determine the pid of a peer connection on
systems like darwin that do not support getpeerucred() nor
SO_PEERCRED.

Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 8a4ab22873)
2023-01-26 09:56:10 -08:00
Jeremy Huddleston Sequoia a6c49106ce os: Update GetLocalClientCreds to prefer getpeerucred() or SO_PEERCRED over getpeereid()
GetLocalClientCreds() was preferring getpeereid() above other implementations.

getpeereid(), however, only returns the effective uid and gid of the peer,
leaving the pid unset.  When this happens, we are unable to use the pid to
determine the peer's command line arguments and incorrectly treat ssh-tunneled
traffic as local.

To address this, we now prioritize getpeerucred() or SO_PEERCRED as those two
implementations will return the pid in addition to uid and gid.

Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 165d5c1260)
2023-01-26 09:55:51 -08:00
Jeremy Huddleston Sequoia a220f53cb8 os: Update AllocNewConnection() debug logging to include whether or not the client is local
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 2577291f01)
2023-01-26 09:55:51 -08:00
Jeremy Huddleston Sequoia 07f9689507 Revert "meson: Don't build COMPOSITE for XQuartz"
This will allow us to remove build-time conditionalization on COMPOSITE
while still allowing XQuartz to disable it and use ROOTLESS.

This reverts commit 5f2d652377

(cherry picked from commit 66e7b7349d)
2023-01-17 15:22:09 -08:00
Jeremy Huddleston Sequoia 8ea43dd8bf xquartz: Disable COMPOSITE at runtime
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 2567388a29)
2023-01-17 15:19:10 -08:00
Jeremy Huddleston Sequoia aa0d8d440c xquartz: Update the about box copyright to 2023
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 15077090d3)
2023-01-17 15:19:10 -08:00
Jeremy Huddleston Sequoia 8feba178f8 xquartz: Fix building with autoconf
Regressed-in: 5d302c378d
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2023-01-14 23:36:00 -08:00
Olivier Fourdan c8ef9e3818 dix: Fix overzealous caching of ResourceClientBits()
Commit c7311654 cached the value of ResourceClientBits(), but that value
depends on the `MaxClients` value set either from the command line or
from the configuration file.

For the latter, a call to ResourceClientBits() is issued before the
configuration file is read, meaning that the cached value is from the
default, not from the maximum number of clients set in the configuration
file.

That obviously causes all sort of issues, including memory corruption
and crashes of the Xserver when reaching the default limit value.

To avoid that issue, also keep the LimitClient value, and recompute the
ilog2() value if that changes, as on startup when the value is set from
the the xorg.conf ServerFlags section.

v2: Drop the `cache == 0` test
    Rename cache vars

Fixes: c7311654 - dix: cache ResourceClientBits() value
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1310
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit 2efa6d6595)
2023-01-11 09:01:14 +00:00
Jeremy Huddleston Sequoia a0216de236
rootless: Add additional debug logging to help triage XQuartz fb/rootless/damage crashes
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 07ed1a623a)
2022-12-21 01:23:50 -08:00
Jeremy Huddleston Sequoia 264272f3d7
xquartz: Use xorg_backtrace() instead of rolling our own for debugging
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit d1a9a50792)
2022-12-21 01:23:50 -08:00
Jeremy Huddleston Sequoia 20f380c6d9
xquartz: Ignore SIGPIPE at process launch
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 9a66690eaf)
2022-12-21 01:23:48 -08:00
Olivier Fourdan 59b6fc88ed xserver 21.1.6
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2022-12-19 10:48:21 +01:00
Peter Hutterer b7760d41c1 Xext: fix invalid event type mask in XTestSwapFakeInput
In commit b320ca0 the mask was inadvertently changed from octal 0177 to
hexadecimal 0x177.

Fixes commit b320ca0ffe
  Xtest: disallow GenericEvents in XTestSwapFakeInput

Found by Stuart Cassoff

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit bb1711b7fb)
2022-12-19 13:49:37 +10:00
Peter Hutterer 69ab3bcaa0 xkb: fix some possible memleaks in XkbGetKbdByName
GetComponentByName returns an allocated string, so let's free that if we
fail somewhere.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 18f91b950e)
2022-12-14 12:27:17 +01:00
Peter Hutterer 5dbb2b52cf xkb: proof GetCountedString against request length attacks
GetCountedString did a check for the whole string to be within the
request buffer but not for the initial 2 bytes that contain the length
field. A swapped client could send a malformed request to trigger a
swaps() on those bytes, writing into random memory.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 11beef0b7f)
2022-12-14 12:27:17 +01:00
Jeremy Huddleston Sequoia becf9d51c3
xquartz: Fix some formatting
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2022-12-14 00:20:00 -08:00
John D Pell 61d18bed66
XQuartz: stub: Call LSOpenApplication instead of fork()/exec()
Reviewed-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2022-12-14 00:19:57 -08:00
Peter Hutterer f292fbfaac xserver 21.1.5
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-12-14 11:35:12 +10:00
Peter Hutterer e860bbce4f xkb: reset the radio_groups pointer to NULL after freeing it
Unlike other elements of the keymap, this pointer was freed but not
reset. On a subsequent XkbGetKbdByName request, the server may access
already freed memory.

CVE-2022-4283, ZDI-CAN-19530

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit ccdd431cd8)
2022-12-14 11:24:47 +10:00
Peter Hutterer 8a1fa008b2 Xi: avoid integer truncation in length check of ProcXIChangeProperty
This fixes an OOB read and the resulting information disclosure.

Length calculation for the request was clipped to a 32-bit integer. With
the correct stuff->num_items value the expected request size was
truncated, passing the REQUEST_FIXED_SIZE check.

The server then proceeded with reading at least stuff->num_items bytes
(depending on stuff->format) from the request and stuffing whatever it
finds into the property. In the process it would also allocate at least
stuff->num_items bytes, i.e. 4GB.

The same bug exists in ProcChangeProperty and ProcXChangeDeviceProperty,
so let's fix that too.

CVE-2022-46344, ZDI-CAN 19405

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit 8f454b793e)
2022-12-14 11:24:46 +10:00
Peter Hutterer 40f431de8a Xi: return an error from XI property changes if verification failed
Both ProcXChangeDeviceProperty and ProcXIChangeProperty checked the
property for validity but didn't actually return the potential error.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit b8a84cb0f2)
2022-12-14 11:24:44 +10:00
Peter Hutterer d6c7de9ead Xext: free the screen saver resource when replacing it
This fixes a use-after-free bug:

When a client first calls ScreenSaverSetAttributes(), a struct
ScreenSaverAttrRec is allocated and added to the client's
resources.

When the same client calls ScreenSaverSetAttributes() again, a new
struct ScreenSaverAttrRec is allocated, replacing the old struct. The
old struct was freed but not removed from the clients resources.

Later, when the client is destroyed the resource system invokes
ScreenSaverFreeAttr and attempts to clean up the already freed struct.

Fix this by letting the resource system free the old attrs instead.

CVE-2022-46343, ZDI-CAN 19404

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit 842ca3ccef)
2022-12-14 11:24:43 +10:00
Peter Hutterer 67927cc41f Xext: free the XvRTVideoNotify when turning off from the same client
This fixes a use-after-free bug:

When a client first calls XvdiSelectVideoNotify() on a drawable with a
TRUE onoff argument, a struct XvVideoNotifyRec is allocated. This struct
is added twice to the resources:
  - as the drawable's XvRTVideoNotifyList. This happens only once per
    drawable, subsequent calls append to this list.
  - as the client's XvRTVideoNotify. This happens for every client.

The struct keeps the ClientPtr around once it has been added for a
client. The idea, presumably, is that if the client disconnects we can remove
all structs from the drawable's list that match the client (by resetting
the ClientPtr to NULL), but if the drawable is destroyed we can remove
and free the whole list.

However, if the same client then calls XvdiSelectVideoNotify() on the
same drawable with a FALSE onoff argument, only the ClientPtr on the
existing struct was set to NULL. The struct itself remained in the
client's resources.

If the drawable is now destroyed, the resource system invokes
XvdiDestroyVideoNotifyList which frees the whole list for this drawable
- including our struct. This function however does not free the resource
for the client since our ClientPtr is NULL.

Later, when the client is destroyed and the resource system invokes
XvdiDestroyVideoNotify, we unconditionally set the ClientPtr to NULL. On
a struct that has been freed previously. This is generally frowned upon.

Fix this by calling FreeResource() on the second call instead of merely
setting the ClientPtr to NULL. This removes the struct from the client
resources (but not from the list), ensuring that it won't be accessed
again when the client quits.

Note that the assignment tpn->client = NULL; is superfluous since the
XvdiDestroyVideoNotify function will do this anyway. But it's left for
clarity and to match a similar invocation in XvdiSelectPortNotify.

CVE-2022-46342, ZDI-CAN 19400

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit b79f32b57c)
2022-12-14 11:24:41 +10:00
Peter Hutterer a6c0d7b142 Xi: disallow passive grabs with a detail > 255
The XKB protocol effectively prevents us from ever using keycodes above
255. For buttons it's theoretically possible but realistically too niche
to worry about. For all other passive grabs, the detail must be zero
anyway.

This fixes an OOB write:

ProcXIPassiveUngrabDevice() calls DeletePassiveGrabFromList with a
temporary grab struct which contains tempGrab->detail.exact = stuff->detail.
For matching existing grabs, DeleteDetailFromMask is called with the
stuff->detail value. This function creates a new mask with the one bit
representing stuff->detail cleared.

However, the array size for the new mask is 8 * sizeof(CARD32) bits,
thus any detail above 255 results in an OOB array write.

CVE-2022-46341, ZDI-CAN 19381

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit 51eb63b0ee)
2022-12-14 11:24:39 +10:00
Peter Hutterer 936d34bdff Xtest: disallow GenericEvents in XTestSwapFakeInput
XTestSwapFakeInput assumes all events in this request are
sizeof(xEvent) and iterates through these in 32-byte increments.
However, a GenericEvent may be of arbitrary length longer than 32 bytes,
so any GenericEvent in this list would result in subsequent events to be
misparsed.

Additional, the swapped event is written into a stack-allocated struct
xEvent (size 32 bytes). For any GenericEvent longer than 32 bytes,
swapping the event may thus smash the stack like an avocado on toast.

Catch this case early and return BadValue for any GenericEvent.
Which is what would happen in unswapped setups anyway since XTest
doesn't support GenericEvent.

CVE-2022-46340, ZDI-CAN 19265

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit b320ca0ffe)
2022-12-14 11:24:37 +10:00
Jeremy Huddleston Sequoia 5f2d652377
meson: Don't build COMPOSITE for XQuartz
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 9c03733669)
2022-11-27 15:15:21 -08:00
Jeremy Huddleston Sequoia 3dee0aac2c
xquartz: Move default applications list outside of the main executable
This will allow side-wide customization.

Fixes: https://github.com/XQuartz/XQuartz/issues/274
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit e654de80ed)
2022-11-24 11:38:42 -08:00
Jeremy Huddleston Sequoia 5d302c378d
xquartz: Remove unused macro (X11LIBDIR)
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 3dbd809c0e)
2022-11-24 11:34:22 -08:00
Povilas Kanapickas 6bf62381d0 xserver 21.1.4 2022-07-12 16:09:23 +03:00
Peter Hutterer 06b23cccb1 xkb: add request length validation for XkbSetGeometry
No validation of the various fields on that report were done, so a
malicious client could send a short request that claims it had N
sections, or rows, or keys, and the server would process the request for
N sections, running out of bounds of the actual request data.

Fix this by adding size checks to ensure our data is valid.

ZDI-CAN 16062, CVE-2022-2319.

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 6907b6ea2b)
2022-07-12 15:24:59 +03:00
Peter Hutterer e3a530540f xkb: swap XkbSetDeviceInfo and XkbSetDeviceInfoCheck
XKB often uses a FooCheck and Foo function pair, the former is supposed
to check all values in the request and error out on BadLength,
BadValue, etc. The latter is then called once we're confident the values
are good (they may still fail on an individual device, but that's a
different topic).

In the case of XkbSetDeviceInfo, those functions were incorrectly
named, with XkbSetDeviceInfo ending up as the checker function and
XkbSetDeviceInfoCheck as the setter function. As a result, the setter
function was called before the checker function, accessing request
data and modifying device state before we ensured that the data is
valid.

In particular, the setter function relied on values being already
byte-swapped. This in turn could lead to potential OOB memory access.

Fix this by correctly naming the functions and moving the length checks
over to the checker function. These were added in 87c64fc5b0 to the
wrong function, probably due to the incorrect naming.

Fixes ZDI-CAN 16070, CVE-2022-2320.

This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Introduced in c06e27b2f6

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit dd8caf39e9)
2022-07-12 15:24:53 +03:00
Peter Hutterer e758405657 xkb: switch to array index loops to moving pointers
Most similar loops here use a pointer that advances with each loop
iteration, let's do the same here for consistency.

No functional changes.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit f1070c01d6)
2022-07-12 15:24:39 +03:00
Jeremy Huddleston Sequoia f3d9c6ff12 xquartz: Add missing files to distribution tarball
Fixes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1346
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2022-07-04 14:16:43 -07:00
Jeremy Huddleston Sequoia 147c17fc78 XQuartz: Improve type safety for X11Controller's application menu editor
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 4cfdc5af31)
2022-07-02 14:25:48 -07:00
Jeremy Huddleston Sequoia 9e2fc7e248 xquartz: Fix a possible crash when editing the Application menu due to mutaing immutable arrays
Crashing on exception: -[__NSCFArray replaceObjectAtIndex:withObject:]: mutating method sent to immutable object

Application Specific Backtrace 0:
0   CoreFoundation                      0x00007ff80d2c5e9b __exceptionPreprocess + 242
1   libobjc.A.dylib                     0x00007ff80d027e48 objc_exception_throw + 48
2   CoreFoundation                      0x00007ff80d38167b _CFThrowFormattedException + 194
3   CoreFoundation                      0x00007ff80d382a25 -[__NSCFArray removeObjectAtIndex:].cold.1 + 0
4   CoreFoundation                      0x00007ff80d2e6c0b -[__NSCFArray replaceObjectAtIndex:withObject:] + 119
5   X11.bin                             0x00000001003180f9 -[X11Controller tableView:setObjectValue:forTableColumn:row:] + 169

Fixes: https://github.com/XQuartz/XQuartz/issues/267
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit dfd057996b)
2022-07-02 14:25:47 -07:00
Jeremy Huddleston Sequoia 86ace20398 xquartz: Use correct defines when building to support Sparkle updates
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit aa636b97c6)
2022-07-01 14:37:01 -07:00
Povilas Kanapickas 855b96a85b xfree86: Fix event data alignment in inputtest driver
This fixes address sanitizer errors when running unit tests. The
additional copying may reduce performance by a small amount, but we
don't care about that because this driver is used for testing only.

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
(cherry picked from commit 7d2014e7d5)
2022-07-01 15:29:34 +03:00
Povilas Kanapickas 9d05ee10c2 dix: Don't send touch end to clients that do async grab without touches
GTK3 menu widget creates a selection for touch and other events and
after receiving touch events creates an async grab that excludes touch
events. Unfortunately it relies on X server not sending the touch end
event in order to function properly. Sending touch end event will cause
it to think that the initiating touch ended and when it actually ends,
the ButtonRelease event will make it think that the menu should be
closed. As a result, the menu will be open only for the duration of the
touch making it useless.

This commit reverts f682e0563f.

Fixes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1255

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
(cherry picked from commit 43e934a19f)
2022-07-01 15:29:19 +03:00
Povilas Kanapickas b713e717c3 dix: Correctly save replayed event into GrabInfoRec
When processing events we operate on InternalEvent pointers. They may
actually refer to a an instance of DeviceEvent, GestureEvent or any
other event that comprises the InternalEvent union. This works well in
practice because we always look into event type before doing anything,
except in the case of copying the event.

*dst_event = *src_event would copy whole InternalEvent event and would
cause out of bounds read in case the pointed to event was not
InternalEvent but e.g. DeviceEvent.

This regression has been introduced in
23a8b62d34.

Fixes https://gitlab.freedesktop.org/xorg/xserver/-/issues/1261

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
(cherry picked from commit 6ef5c05728)
2022-07-01 15:15:15 +03:00
Samuel Thibault cd3d21d8c4 xkb: fix XkbSetMap when changing a keysym without changing a keytype
As the comment says:

"symsPerKey/mapWidths must be filled regardless of client-side flags"

so we always have to call CheckKeyTypes which will notably fill mapWidths
and nTypes. That is needed for CheckKeySyms to work since it checks the
width. Without it, any request with XkbKeySymsMask but not
XkbKeyTypesMask will fail because of the missing width information, for
instance this:

  XkbDescPtr xkb;
  if (!(xkb = XkbGetMap (dpy, XkbKeyTypesMask|XkbKeySymsMask, XkbUseCoreKbd))) {
    fprintf (stderr, "ERROR getting map\n");
    exit(1);
  }
  XFlush (dpy);
  XSync (dpy, False);

  XkbMapChangesRec changes = { .changed = 0 };
  int oneGroupType[XkbNumKbdGroups] = { XkbOneLevelIndex };

  if (XkbChangeTypesOfKey(xkb, keycode, 1, XkbGroup1Mask, oneGroupType, &changes)) {
    fprintf(stderr, "ERROR changing type of key\n");
    exit(1);
  }
  XkbKeySymEntry(xkb,keycode,0,0) = keysym;

  if (!XkbChangeMap(dpy,xkb,&changes)) {
    fprintf(stderr, "ERROR changing map\n");
    exit(1);
  }

  XkbFreeKeyboard (xkb, 0, TRUE);
  XFlush (dpy);
  XSync (dpy, False);

This had being going under the radar since about ever until commit
de940e06f8 ("xkb: fix key type index check
in _XkbSetMapChecks") fixed checking the values of kt_index, which was
previously erroneously ignoring errors and ignoring all other checks, just
because nTypes was not set, precisely because CheckKeyTypes was not called.

Note: yes, CheckKeyTypes is meant to be callable without XkbKeyTypesMask, it
does properly check for that and just fills nTypes and mapWidths in that
case.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
(cherry picked from commit 0217cc6e0c)
2022-07-01 15:13:01 +03:00
Povilas Kanapickas f575524314 Revert "os: Try to discover the current seat with the XDG_SEAT var first"
This reverts commit b27eaa7283.
2022-07-01 15:13:01 +03:00
Jeremy Huddleston Sequoia 419fbf639d XQuartz: Add TCC reason keys to Info.plist
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 9ce7264889)
2022-06-26 13:25:51 -07:00
Jeremy Huddleston Sequoia 66ac50090d XQuartz: Build the bundle trampoline when using meson
This brings the change for e1fdc856ae into meson based builds

Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit b00cf4aef8)
2022-06-26 03:03:26 -07:00
Jeremy Huddleston Sequoia 033d93a021 meson: Support building Xnest and Xorg on darwin
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit ef8101560e)
2022-06-26 03:03:26 -07:00
Jeremy Huddleston Sequoia 433f53a1a0 tests: Fix build failure from missing micmap.c
FAILED: test/tests
clang  -o test/tests test/tests.p/.._mi_miinitext.c.o test/tests.p/fixes.c.o test/tests.p/input.c.o test/tests.p/list.c.o test/tests.p/misc.c.o test/tests.p/signal-logging.c.o test/tests.p/string.c.o test/tests.p/test_xkb.c.o test/tests.p/tests-common.c.o test/tests.p/tests.c.o test/tests.p/touch.c.o test/tests.p/xfree86.c.o test/tests.p/xtest.c.o test/tests.p/hashtabletest.c.o -Wl,-dead_strip_dylibs -Wl,-headerpad_max_install_names -Wl,-undefined,error -fvisibility=hidden -O0 -g3 -gdwarf-2 -mmacosx-version-min=10.9 -Werror=unguarded-availability-new -Werror=format -Werror=objc-method-access -Werror=incompatible-pointer-types -F/Applications/Utilities/XQuartz.app/Contents/Frameworks -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.13.sdk -arch x86_64 -O0 -g3 -gdwarf-2 -mmacosx-version-min=10.9 -Werror=unguarded-availability-new -Werror=format -Werror=objc-method-access -Werror=incompatible-pointer-types -F/Applications/Utilities/XQuartz.app/Contents/Frameworks -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.13.sdk -arch x86_64 -Wl,-rpath,/opt/X11/lib mi/liblibxserver_mi.a dix/liblibxserver_dix.a composite/liblibxserver_composite.a damageext/liblibxserver_damageext.a dbe/liblibxserver_dbe.a randr/liblibxserver_randr.a miext/damage/liblibxserver_miext_damage.a render/liblibxserver_render.a present/liblibxserver_present.a Xext/liblibxserver_xext.a miext/sync/liblibxserver_miext_sync.a xfixes/liblibxserver_xfixes.a Xi/liblibxserver_xi.a xkb/liblibxserver_xkb.a record/liblibxserver_record.a os/liblibxserver_os.a os/liblibxlibc.a glx/liblibglxvnd.a hw/xfree86/common/libxorg_common.a hw/xfree86/loader/libxorg_loader.a hw/xfree86/ddc/libxorg_ddc.a hw/xfree86/xkb/libxorg_xkb.a hw/xfree86/i2c/libxorg_i2c.a hw/xfree86/modes/libxorg_modes.a hw/xfree86/os-support/libxorg_os_support.a hw/xfree86/parser/libxorg_parser.a hw/xfree86/ramdac/libxorg_ramdac.a fb/liblibxserver_fb.a Xext/liblibxserver_xext_vidmode.a dix/liblibxserver_main.a config/liblibxserver_config.a /opt/X11/lib/libpixman-1.dylib /opt/X11/lib/libxcvt.dylib /opt/X11/lib/libxkbfile.dylib /opt/X11/lib/libXfont2.dylib /opt/X11/lib/libXdmcp.dylib -lm /opt/X11/lib/libxshmfence.dylib -ldl -lpthread /opt/X11/lib/libXau.dylib /opt/X11/lib/libGL.dylib
Undefined symbols for architecture x86_64:
  "_micmapScrPrivateKeyRec", referenced from:
      _DGAInstallCmap in libxorg_common.a(xf86DGA.c.o)
      _xf86HandleColormaps in libxorg_common.a(xf86cmap.c.o)
      _CMapInstallColormap in libxorg_common.a(xf86cmap.c.o)
      _CMapEnterVT in libxorg_common.a(xf86cmap.c.o)
      _CMapSwitchMode in libxorg_common.a(xf86cmap.c.o)
      _CMapSetDGAMode in libxorg_common.a(xf86cmap.c.o)
      _CMapChangeGamma in libxorg_common.a(xf86cmap.c.o)
      ...
ld: symbol(s) not found for architecture x86_64

Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 6645ff5906)
2022-06-26 03:03:26 -07:00
Jeremy Huddleston Sequoia 3868f36472 xf86-input-inputtest: Fix build on systems without SOCK_NONBLOCK
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 707f23dab8)
2022-06-26 03:03:26 -07:00
Jeremy Huddleston Sequoia afcaaac967 print_edid: Fix a format string error
../hw/xfree86/ddc/print_edid.c:511:20: error: format specifies type 'unsigned short' but the argument has type 'int' [-Werror,-Wformat]
                   det_mon->type - DS_VENDOR);
                   ^~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 199b8c0853)
2022-06-26 03:03:26 -07:00
Jeremy Huddleston Sequoia 6bb98fc62d xquartz: Update autotools-based builds of XQuartz to account for recent changes
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2022-06-21 11:54:06 -07:00
Jeremy Huddleston Sequoia 4ea6f661ed Revert "meson: Bump requirement to meson-0.50.0"
This bump is causing issues with our CI.  Sorry about that.

This reverts commit a6a20a7c40

(cherry picked from commit 8cd0397e5b)
2022-06-20 20:33:38 -07:00
Jeremy Huddleston Sequoia a6a20a7c40 meson: Provide options to set CFBundleVersion and CFBundleVersionString in XQuartz
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 4f5999826a)
2022-06-19 23:10:48 -07:00
Jeremy Huddleston Sequoia 37285e6252 xquartz: Update copyright for 2022
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit b12f5dc62d)
2022-06-19 22:23:40 -07:00
Jeremy Huddleston Sequoia 96e7b55c5d xquartz: Update Sparkle configuration to use SUPublicEDKey
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 1d90bef30c)
2022-06-19 22:23:40 -07:00
Jeremy Huddleston Sequoia 6465263be8 meson: Bump requirement to meson-0.50.0
WARNING: Project specifies a minimum meson_version '>= 0.47.0' but uses features which were added in newer versions:
 * 0.50.0: {'install arg in configure_file'}

Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 0a27f96d1d)
2022-06-19 22:23:40 -07:00
Jeremy Huddleston Sequoia e48acd9c40 XQuartz: Ensure scroll events are delivered to a single window (not both X11 and AppKit)
Fixes: https://github.com/XQuartz/XQuartz/issues/130
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 4532b696c6)
2022-06-16 07:27:38 -07:00
Jeremy Huddleston Sequoia 140d9a0f75 xquartz: Fold spaces related preferences into NSUserDefaults+XQuartzDefaults
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit f40610e0b4)
2022-06-14 23:36:40 -07:00
Jeremy Huddleston Sequoia 03ec5b132f xquartz pbproxy: Adopt NSUserDefaults+XQuartzDefaults for preferences
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 6134c73aeb)
2022-06-14 23:36:39 -07:00
Jeremy Huddleston Sequoia 6df6178bb9 xquartz: Create a separate category for organizing user preferences
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit 963ba6d9ad)
2022-06-14 23:36:39 -07:00
Jeremy Huddleston Sequoia c6c1cba397 os/connection: Improve abstraction for launchd secure sockets
This changes away from hard-coding the /tmp/launch-* path to now
supporting a generic <absolute path to unix socket>[.<screen>]
format for $DISPLAY.

cf-libxcb: d978a4f69b30b630f28d07f1003cf290284d24d8

Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
CC: Adam Jackson <ajax@kemper.freedesktop.org>
(cherry picked from commit 83d0d91106)
2022-06-14 23:36:39 -07:00
Jeremy Huddleston Sequoia 663af2f17e X11Application: Ensure TIS operations are done on the main thread
Fixes: https://github.com/XQuartz/XQuartz/issues/205
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit b1afcecc61)
2022-06-14 23:36:39 -07:00
Jeremy Huddleston Sequoia bd3564cf37 rootless: Dead code removal (ROOTLESS_REDISPLAY_DELAY is already defined)
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
(cherry picked from commit c11b55f3c0)
2022-06-14 23:36:39 -07:00
Olivier Fourdan 53173fdab4 render: Fix build with gcc 12
The xserver fails to compile with the latest gcc 12:

 render/picture.c: In function ‘CreateSolidPicture’:
 render/picture.c:874:26: error: array subscript ‘union _SourcePict[0]’ is partly outside array bounds of ‘unsigned char[16]’ [-Werror=array-bounds]
  874 |     pPicture->pSourcePict->type = SourcePictTypeSolidFill;
      |                          ^~
 render/picture.c:868:45: note: object of size 16 allocated by ‘malloc’
  868 |     pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictSolidFill));
      |                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 render/picture.c: In function ‘CreateLinearGradientPicture’:
 render/picture.c:906:26: error: array subscript ‘union _SourcePict[0]’ is partly outside array bounds of ‘unsigned char[32]’ [-Werror=array-bounds]
  906 |     pPicture->pSourcePict->linear.type = SourcePictTypeLinear;
      |                          ^~
 render/picture.c:899:45: note: object of size 32 allocated by ‘malloc’
  899 |     pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictLinearGradient));
      |                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 render/picture.c: In function ‘CreateConicalGradientPicture’:
 render/picture.c:989:26: error: array subscript ‘union _SourcePict[0]’ is partly outside array bounds of ‘unsigned char[32]’ [-Werror=array-bounds]
  989 |     pPicture->pSourcePict->conical.type = SourcePictTypeConical;
      |                          ^~
 render/picture.c:982:45: note: object of size 32 allocated by ‘malloc’
  982 |     pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictConicalGradient));
      |                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 cc1: some warnings being treated as errors
 ninja: build stopped: subcommand failed.

This is because gcc 12 has become stricter and raises a warning now.

Fix the warning/error by allocating enough memory to store the union
struct.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1256
(cherry picked from commit c6b0dcb82d)
2022-01-28 10:36:28 +01:00
Błażej Szczygieł 6977404471 present: Check for NULL to prevent crash
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1275
Signed-off-by: Błażej Szczygieł <spaz16@wp.pl>
Tested-by: Aaron Plattner <aplattner@nvidia.com>
(cherry picked from commit 22d5818851)
2022-01-19 11:04:14 -08:00
Povilas Kanapickas 85397cc2ef xserver 21.1.3
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2022-01-03 00:23:30 +02:00
Adam Jackson 001feb6692 glx/dri: Filter out fbconfigs that don't have a supported pixmap format
For depth 30 in particular it's not uncommon for the DDX to not have
a configured pixmap format. Since the client expects to back both
GLXPixmaps and GLXPbuffers with X Pixmaps, trying to use an x2rgb10
fbconfig would fail along various paths to CreatePixmap. Filter these
fbconfigs out so the client can't ask for something that we know won't
work.

(cherry picked from commit f6c070a1ac)
2022-01-01 14:46:19 +02:00
Jocelyn Falempe 66890ca569 xf86/logind: fix missing call to vtenter if the platform device is not paused
If there is one platform device, which is not paused nor resumed,
systemd_logind_vtenter() will never get called.
This break suspend/resume, and switching to VT on system with Nvidia
proprietary driver.
This is a regression introduced by f5bd039633

So now call systemd_logind_vtenter() if there are no paused
platform devices.

Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1271
Fixes: f5bd0396 - xf86/logind: fix call systemd_logind_vtenter after receiving drm device resume

Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
Tested-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2021-12-20 17:09:19 +01:00
Jocelyn Falempe fec0e2501b xf86/logind: Fix compilation error when built without logind/platform bus
This was introduced by commit 8eb1396d

Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1269
Fixes: da9d012a9 - xf86/logind: Fix drm_drop_master before vt_reldisp

Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2021-12-20 17:09:17 +01:00
Matthieu Herrb 8223a9d6d9 Convert more funcs to use InternalEvent.
This fixes a crash when a DeviceEvent struct converted to
InteralEvent was beeing copied as InternalEvent (and thus
causing out of bounds reads) in ActivateGrabNoDelivery()
in events.c: 3876    *grabinfo->sync.event = *real_event;

Possible fix for https://gitlab.freedesktop.org/xorg/xserver/-/issues/1253

Signed-off-by: Matthieu Herrb <matthieu@herrb.eu>
(cherry picked from commit 5b8817a019)
2021-12-19 23:33:28 +02:00
nerdopolis b27eaa7283 os: Try to discover the current seat with the XDG_SEAT var first
(cherry picked from commit ca1dfdc9aa)
2021-12-19 12:44:51 +02:00
Povilas Kanapickas 9852b29380 xserver 21.1.2
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-12-15 15:46:09 +02:00
Sam James 9fe2991075 hw/xfree86: fix sbus build for SPARC
Initially reported downstream in Gentoo. Manifests with errors like:
```
gnu/bin/ld: hw/xfree86/common/libxorg_common.a(xf86fbBus.c.o): in function `xf86ClaimFbSlot':
xf86fbBus.c:(.text+0x20): undefined reference to `sbusSlotClaimed'
/usr/lib/gcc/sparc-unknown-linux-gnu/11.2.0/../../../../sparc-unknown-linux-gnu/bin/ld: xf86fbBus.c:(.text+0x2c): undefined reference to `sbusSlotClaimed'
```

While we use the headers in meson.build, we don't reference xf86sbusBus.c
which defines the missing symbols like sbusSlotClaimed.

Bug: https://bugs.gentoo.org/828513
Signed-off-by: Sam James <sam@gentoo.org>
(cherry picked from commit 6c1a1fcc4b)
2021-12-15 10:41:22 +02:00
Povilas Kanapickas 0b67785cd1 render: Fix out of bounds access in SProcRenderCompositeGlyphs()
ZDI-CAN-14192, CVE-2021-4008

This vulnerability was discovered and the fix was suggested by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
(cherry picked from commit ebce7e2d80)
2021-12-15 10:41:21 +02:00
Povilas Kanapickas 7209982d2a Xext: Fix out of bounds access in SProcScreenSaverSuspend()
ZDI-CAN-14951, CVE-2021-4010

This vulnerability was discovered and the fix was suggested by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
(cherry picked from commit 6c4c530107)
2021-12-15 10:41:20 +02:00
Povilas Kanapickas 6f09e7d391 xfixes: Fix out of bounds access in *ProcXFixesCreatePointerBarrier()
ZDI-CAN-14950, CVE-2021-4009

This vulnerability was discovered and the fix was suggested by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
(cherry picked from commit b519675009)
2021-12-15 10:41:19 +02:00
Povilas Kanapickas a82d523edb record: Fix out of bounds access in SwapCreateRegister()
ZDI-CAN-14952, CVE-2021-4011

This vulnerability was discovered and the fix was suggested by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
(cherry picked from commit e56f61c79f)
2021-12-15 10:41:18 +02:00
Matthieu Herrb a39218d99c remove the PRE_RELEASE message.
With the new numbering scheme, XORG_VERISON_SNAP doesn't mean
a pre-release version anymore.

Signed-off-by: Matthieu Herrb <matthieu@herrb.eu>
(cherry picked from commit 4de9666b6d)
2021-12-15 10:41:17 +02:00
Matt Turner fc2eb7e8cc test: #undef NDEBUG so assert is not compiled away
(cherry picked from commit d189102c78)
2021-12-10 00:55:35 -05:00
Povilas Kanapickas 7caf29ca66 meson: Correctly set DDXOSVERRORF and DDXBEFORERESET on xwin
This worked with autotools, but not meson build system.

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
(cherry picked from commit 04c93b98e9)
2021-12-04 18:05:29 +02:00
Jonathan Gray 101791f80f glamor: fix free of uninitialised pointers
Attempting to run fvwm on a x61/965gm with xserver 1.21.1 with the
modesetting driver on OpenBSD/amd64 would cause the xserver to
reliably crash.

I tracked this down to the free() calls introduced in
2906ee5e4a
(d1ca47e124 in branch).

clang also warns about this:
glamor_program.c:296:13: warning: variable 'vs_prog_string' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
glamor_program.c:290:9: warning: variable 'vs_prog_string' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
glamor_program.c:288:9: warning: variable 'vs_prog_string' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
glamor_program.c:277:13: warning: variable 'vs_prog_string' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
glamor_program.c:296:13: warning: variable 'fs_prog_string' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
glamor_program.c:290:9: warning: variable 'fs_prog_string' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
glamor_program.c:288:9: warning: variable 'fs_prog_string' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
glamor_program.c:277:13: warning: variable 'fs_prog_string' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]

Signed-off-by: Jonathan Gray <jsg@jsg.id.au>
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Fixes: 2906ee5e4 ("glamor: Fix leak in glamor_build_program()")
(cherry picked from commit 5ac6319776)
2021-12-04 18:05:29 +02:00
Peter Hutterer 2c6989f81e xkb: fix XkbSetMap check for the keytypes count
The previous if/else condition resulted in us always setting the key
type count to the current number of key types. Split this up correctly.

Regression introduced in de940e06f8

Fixes #1249

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit be16bd8543)
2021-12-04 18:05:29 +02:00
Povilas Kanapickas 49444ce9f7 Revert "hw/xfree86: Propagate physical dimensions from DRM connector"
Quite a lot of applications currently expect the screen DPI exposed by
the X server to be 96 even when the real display DPI is different.
Additionally, currently Xwayland completely ignores any hardware
information and sets the DPI to 96. Accordingly the new behavior, even
if it fixes a bug, should not be enabled automatically to all users.

A better solution would be to make the default DPI stay as is and enable
the correct behavior with a command line option (maybe -dpi auto, or
similar). For now let's just revert the bug fix.

This reverts commit 05b3c681ea.

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
(cherry picked from commit 35af1299e7)
2021-12-03 03:10:06 +02:00
Dave Airlie 6f11b3c803 dri2: add crocus to the list of va_gl users
(cherry picked from commit a7b0a7fabd)
2021-12-03 03:10:06 +02:00
Jocelyn Falempe 8eb1396d3e xf86/logind: Fix drm_drop_master before vt_reldisp
When switching to VT, the ioctl DRM_DROP_MASTER must be done before
the ioctl VT_RELDISP. Otherwise the kernel can't change the modesetting
reliably, and this leads to the console not showing up in some cases, like
after unplugging a docking station with a DP or HDMI monitor.

Before doing the VT_RELDISP, send a dbus message to logind, to
pause the drm device, so logind will do the ioctl DRM_DROP_MASTER.

With this patch, it changes the order logind will send the resume
event, and drm will be sent last instead of first.
so there is a also fix to call systemd_logind_vtenter() at the right time.

Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit da9d012a9c)
2021-12-03 00:46:11 +00:00
Jocelyn Falempe 6834f977a5 xf86/logind: fix call systemd_logind_vtenter after receiving drm device resume
logind send the resume event for input devices and drm device,
in any order. if we call vt_enter before logind resume the drm device,
it leads to a driver error, because logind has not done the
DRM_IOCTL_SET_MASTER on it.

Keep the old workaround to make sure we call systemd_logind_vtenter at
least once if there are no platform device

Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit f5bd039633)
2021-12-03 00:46:11 +00:00
nerdopolis 0ed7b1224e xfree86: On Linux, while only seat0 can have TTYs, don't assmume all seat0s have TTYs
(cherry picked from commit b8c12aac65)
2021-11-23 13:01:55 -08:00
Povilas Kanapickas 6b997fb74e xserver 21.1.1
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-11-07 01:34:24 +02:00
Povilas Kanapickas 70a0c48ff3 Makefile.am: Add missing meson build files to release tarball 2021-11-06 21:22:23 +02:00
Matthieu Herrb db0da823f5 Make xf86CompatOutput() return NULL when there are no privates
Some drivers (mach64 w/o DRI for instance) don't initialize privates.

Signed-off-by: Matthieu Herrb <matthieu.herrb@laas.fr>
(cherry picked from commit 80eeff3eba)
2021-11-06 19:06:20 +02:00
Jon Turney fdb266ff81 s/__/@/ in inputtestdrv manpage
Update manpage subsitution style for 2e497bf8

(cherry picked from commit 0099412ea4)
2021-11-06 19:06:10 +02:00
Povilas Kanapickas 27a0ee32cc xserver 21.1
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-10-27 13:38:26 +03:00
Mario Kleiner d4944ceda1 Fix RandR leasing for more than 1 simultaneously active lease.
Due to a switched order of parameters in the xorg_list_add()
call inside ProcRRCreateLease(), adding a new lease for RandR
output leasing does not actually add the new RRLeasePtr lease
record to the list of existing leases for a X-Screen, but instead
replaces the existing list with a new list that has the new lease
as the only element, and probably leaks a bit of memory.

Therefore the server "forgets" all active leases for a screen,
except for the last added lease. If multiple leases are created
in a session, then destruction of all leases but the last one
will fail in many cases, e.g., during server shutdown in
RRCloseScreen(), or resource destruction, e.g., in
RRCrtcDestroyResource().

Most importantly, it fails if a client simply close(fd)'es the
DRM master descriptor to release a lease, quits, gets killed or
crashes. In this case the kernel will destroy the lease and shut
down the display output, then send a lease event via udev to the
ddx, which e.g., in the modesetting-ddx will trigger a call to
drmmode_validate_leases().

That function is supposed to detect the released lease and tell
the server to terminate the lease on the server side as well,
via xf86CrtcLeaseTerminated(), but this doesn't happen for all
the leases the server has forgotten. The end result is a dead
video output, as the server won't reinitialize the crtc's
corresponding to the terminated but forgotten lease.

This bug was observed when using the amdvlk AMD OSS Vulkan
driver and trying to lease multiple VKDisplay's, and also
under Mesa radv, as both Mesa Vulkan/WSI/Display and amdvlk
terminate leases by simply close()ing the lease fd, not by
sending explicit RandR protocol requests to free leases.

Leasing worked, but ending a session with multiple active
leases ended in a lot of unpleasant darkness.

Fixing the wrong argument order to xorg_list_add() fixes the
problem. Tested on single-X-Screen and dual-X-Screen setups,
with one, two or three active leases.

Please merge this for the upcoming server 21.1 branch.
Merging into server 1.20 would also make a lot of sense.

Fixes: e4e3447603
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Cc: Keith Packard <keithp@keithp.com>
(cherry picked from commit f467f85ca1)
2021-10-21 13:08:01 +03:00
Povilas Kanapickas e59faa4b8c xserver 21.1 RC 2 2021-10-14 17:33:40 +03:00
Alex Richardson 3fb94f3c5c dix/privates.c: Avoid undefined behaviour after realloc()
Adding the offset between the realloc result and the old allocation to
update pointers into the new allocation is undefined behaviour: the
old pointers are no longer valid after realloc() according to the C
standard. While this works on almost all architectures and compilers,
it causes  problems on architectures that track pointer bounds (e.g.
CHERI or Arm's Morello): the DevPrivateKey pointers will still have the
bounds of the previous allocation and therefore any dereference will
result in a run-time trap.

I found this due to a crash (dereferencing an invalid capability) while
trying to run `XVnc` on a CHERI-RISC-V system. With this commit I can
successfully connect to the XVnc instance running inside a QEMU with a
VNC viewer on my host.

This also changes the check whether the allocation was moved to use
uintptr_t instead of a pointer since according to the C standard:
"The value of a pointer becomes indeterminate when the object it
points to (or just past) reaches the end of its lifetime." Casting to an
integer type avoids this undefined behaviour.

Signed-off-by: Alex Richardson <Alexander.Richardson@cl.cam.ac.uk>
(cherry picked from commit f9f705bf3c)
2021-10-08 21:38:01 +03:00
nerdopolis b89fdd523e xf86: Accept devices with the 'simpledrm' driver.
SimpleDRM 'devices' are a fallback device, and do not have a busid
so they are getting skipped. This will allow simpledrm to work
with the modesetting driver

(cherry picked from commit b9218fadf3)
2021-10-08 21:38:00 +03:00
Mario Kleiner fbc690ccaf modesetting: Consider RandR primary output for selectioh of sync crtc.
The "sync crtc" is the crtc used to drive the display timing of a
drawable under DRI2 and DRI3/Present. If a drawable intersects
multiple video outputs, then normally the crtc is chosen which has
the largest intersection area with the drawable.

If multiple outputs / crtc's have exacty the same intersection
area then the crtc chosen was simply the first one with maximum
intersection. Iow. the choice was random, depending on plugging
order of displays.

This adds the ability to choose a preferred output in such a tie
situation. The RandR output marked as "primary output" is chosen
on such a tie.

This new behaviour and its implementation is consistent with other
video ddx drivers. See amdgpu-ddx, ati-ddx and nouveau-ddx for
reference. This commit is a straightforward port from amdgpu-ddx.

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
(cherry picked from commit 4b75e65766)
2021-10-08 21:37:59 +03:00
Mario Kleiner 22f4ff1026 modesetting: Handle mixed VRR and non-VRR display setups better.
In a setup with both VRR capable and non-VRR capable displays,
it was so far inconsistent if the driver would allow use of
VRR support or not, as "is_connector_vrr_capable" was set to
whatever the capabilities of the last added drm output were.
Iow. the plugging order of monitors determined the outcome.

Fix this: Now if at least one display is VRR capable, the driver
will treat an X-Screen as capable for VRR, plugging order no
longer matters.

Tested with a dual-display setup with one VRR monitor and one
non-VRR monitor. This is also beneficial with the new Option
"AsyncFlipSecondaries".

When we are at it, also add some so far missing description of
the "VariableRefresh" driver option, copied from amdgpu-ddx.

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
(cherry picked from commit 017ce26337)
2021-10-08 21:37:58 +03:00
Mario Kleiner 0d0986bf3b modesetting: Enable GAMMA_LUT for lut's with up to 4096 slots.
A lut size of 4096 slots has been verified to work correctly,
as tested with amdgpu-kms. Intel Tigerlake Gen12 hw has a very
large GAMMA_LUT size of 262145 slots, but also issues with its
current GAMMA_LUT implementation, as of Linux 5.14.

Therefore we keep GAMMA_LUT off for large lut's. This currently
excludes Intel Icelake, Tigerlake and later.

This can be overriden via the "UseGammaLUT" boolean xorg.conf option
to force use of GAMMA_LUT on or off.

See following link for the Tigerlake situation:
https://gitlab.freedesktop.org/drm/intel/-/issues/3916#note_1085315

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
(cherry picked from commit 66e5a5bb12)
2021-10-08 21:37:57 +03:00
Ray Strode bc1327e6de xkb: Drop check for XkbSetMapResizeTypes
Commit 446ff2d317 added checks to
prevalidate the size of incoming SetMap requests.

That commit checks for the XkbSetMapResizeTypes flag to be set before
allowing key types data to be processed.

key types data can be changed or even just sent wholesale unchanged
without the number of key types changing, however. The check for
XkbSetMapResizeTypes rejects those legitimate requests. In particular,
XkbChangeMap never sets XkbSetMapResizeTypes and so always fails now
any time XkbKeyTypesMask is in the changed mask.

This commit drops the check for XkbSetMapResizeTypes in flags when
prevalidating the request length.

(cherry picked from commit 8b7f4d3259)
2021-10-08 21:37:56 +03:00
Mario Kleiner b87536682c Revert "modesetting: Only use GAMMA_LUT if its size is 1024"
This reverts commit 617f591fc4.

The problem described in that commit exists, but the two
preceeding commits with improvements to the servers RandR
code should avoid the mentioned problems while allowing the
use of GAMMA_LUT's instead of legacy gamma lut.

Use of legacy gamma lut's is not a good fix, because it will reduce
color output precision of gpu's with more than 1024 GAMMA_LUT
slots, e.g., AMD, ARM MALI and KOMEDA with 4096 slot luts,
and some Mediathek parts with 512 slot luts. On KOMEDA, legacy
lut's are completely unsupported by the kms driver, so gamma
correction gets disabled.

The situation is especially bad on Intel Icelake and later:
Use of legacy gamma tables will cause the kms driver to switch
to hardware legacy lut's with 256 slots, 8 bit wide, without
interpolation. This way color output precision is restricted to
8 bpc and any deep color / HDR output (10 bpc, fp16, fixed point 16)
becomes impossible. The latest Intel gen gpu's would have worse
color precision than parts which are more than 10 years old.

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
(cherry picked from commit 545fa90cbf)
2021-10-08 21:37:55 +03:00
Mario Kleiner 473a48660f xfree86: Let xf86RandR12CrtcComputeGamma() deal with non-power-of-2 sizes.
The assumption in the upsampling code was that the crtc->gamma_size
size of the crtc's gamma table is a power of two. This is true for
almost all current driver + gpu combos at least on Linux, with typical
sizes of 256, 512, 1024 or 4096 slots.

However, Intel Gen-11 Icelake and later are outliers, as their gamma
table has 2^18 + 1 slots, very big and not a power of two!

Try to make upsampling behave at least reasonable: Replicate the
last gamma value to fill up remaining crtc->gamma_red/green/blue
slots, which would normally stay uninitialized. This is important,
because while the intel display driver does not actually use all
2^18+1 values passed as part of a GAMMA_LUT, it does need the
very last slot, which would not get initialized by the old code.

This should hopefully create reasonable behaviour with Icelake+
but is untested on the actual Intel hw due to lack of suitable
hw.

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
(cherry picked from commit 7326e131df)
2021-10-08 21:37:54 +03:00
Mario Kleiner b33f487a7c xfree86: Avoid crash in xf86RandR12CrtcSetGamma() memcpy path.
If randrp->palette_size is zero, the memcpy() path can read past the
end of the randr_crtc's gammaRed/Green/Blue tables if the hw crtc's
gamma_size is greater than the randr_crtc's gammaSize.

Avoid this by clamping the to-be-copied size to the smaller of both
sizes.

Note that during regular server startup, the memcpy() path is only
taken initially twice, but then a suitable palette is created for
use during a session. Therefore during an actual running X-Session,
the xf86RandR12CrtcComputeGamma() will be used, which makes sure that
data is properly up- or down-sampled for mismatching source and
target crtc gamma sizes.

This should avoid reading past randr_crtc gamma memory for gpu's
with big crtc->gamma_size, e.g., AMD/MALI/KOMEDA 4096 slots, or
Intel Icelake and later with 262145 slots.

Tested against modesetting-ddx and amdgpu-ddx under screen color
depth 24 (8 bpc) and 30 (10 bpc) to make sure that clamping happens
properly.

This is an alternative fix for the one attempted in commit
617f591fc4.

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
(cherry picked from commit 966f567432)
2021-10-08 21:37:53 +03:00
Olivier Fourdan d1ca47e124 glamor: Fix leak in glamor_build_program()
Fix the possible leak of `vs_prog_string` and `fs_prog_string` in case
of failure, as reported by covscan.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
(cherry picked from commit 2906ee5e4a)
2021-10-08 21:37:52 +03:00
Povilas Kanapickas d00e7dfc9d xserver 21.1 RC 1
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-09-21 23:37:48 +03:00
Povilas Kanapickas 4ee66f574a Drop XWayland DDX 2021-09-15 21:49:17 +03:00
178 changed files with 1606 additions and 15291 deletions

View File

@ -11,7 +11,8 @@ variables:
FDO_UPSTREAM_REPO: xorg/xserver
FDO_DISTRIBUTION_VERSION: buster-slim
FDO_DISTRIBUTION_EXEC: 'env FDO_CI_CONCURRENT=${FDO_CI_CONCURRENT} bash .gitlab-ci/debian-install.sh'
FDO_DISTRIBUTION_TAG: "2021-07-09"
FDO_DISTRIBUTION_TAG: "2024-08-23-21.1-fix-cross"
MESON_BUILDDIR: "build"
include:
- project: 'freedesktop/ci-templates'

View File

@ -11,7 +11,7 @@ HOST=$1
cat >/usr/local/bin/${HOST}-pkg-config <<EOF
#!/bin/sh
PKG_CONFIG_SYSROOT_DIR=/usr/${HOST} PKG_CONFIG_LIBDIR=/usr/${HOST}/lib/pkgconfig:/usr/share/pkgconfig pkg-config \$@
PKG_CONFIG_SYSROOT_DIR=/usr/${HOST} PKG_CONFIG_LIBDIR=/usr/${HOST}/lib/pkgconfig:/usr/${HOST}/share/pkgconfig pkg-config \$@
EOF
chmod +x /usr/local/bin/${HOST}-pkg-config

View File

@ -147,6 +147,8 @@ EXTRA_DIST += \
damageext/meson.build \
dbe/meson.build \
dix/meson.build \
doc/dtrace/meson.build \
doc/meson.build \
dri3/meson.build \
exa/meson.build \
fb/meson.build \
@ -160,8 +162,10 @@ EXTRA_DIST += \
hw/xfree86/common/meson.build \
hw/xfree86/ddc/meson.build \
hw/xfree86/dixmods/meson.build \
hw/xfree86/doc/meson.build \
hw/xfree86/dri2/meson.build \
hw/xfree86/dri/meson.build \
hw/xfree86/drivers/inputtest/meson.build \
hw/xfree86/drivers/modesetting/meson.build \
hw/xfree86/exa/meson.build \
hw/xfree86/fbdevhw/meson.build \
@ -179,8 +183,12 @@ EXTRA_DIST += \
hw/xfree86/x86emu/meson.build \
hw/xfree86/xkb/meson.build \
hw/xnest/meson.build \
hw/xquartz/bundle/meson.build \
hw/xquartz/GL/meson.build \
hw/xquartz/mach-startup/meson.build \
hw/xquartz/meson.build \
hw/xwayland/meson.build \
hw/xquartz/pbproxy/meson.build \
hw/xquartz/xpr/meson.build \
hw/xwin/dri/meson.build \
hw/xwin/glx/meson.build \
hw/xwin/meson.build \
@ -188,6 +196,7 @@ EXTRA_DIST += \
include/meson.build \
meson.build \
miext/damage/meson.build \
miext/rootless/meson.build \
miext/shadow/meson.build \
miext/sync/meson.build \
mi/meson.build \
@ -199,6 +208,8 @@ EXTRA_DIST += \
render/meson.build \
test/bigreq/meson.build \
test/bigreq/request-length.c \
test/damage/meson.build \
test/damage/primitives.c \
test/meson.build \
test/sync/meson.build \
test/sync/sync.c \

View File

@ -1051,7 +1051,7 @@ ScreenSaverSetAttributes(ClientPtr client)
pVlist++;
}
if (pPriv->attr)
FreeScreenAttr(pPriv->attr);
FreeResource(pPriv->attr->resource, AttrType);
pPriv->attr = pAttr;
pAttr->resource = FakeClientID(client->index);
if (!AddResource(pAttr->resource, AttrType, (void *) pAttr))
@ -1351,8 +1351,8 @@ SProcScreenSaverSuspend(ClientPtr client)
REQUEST(xScreenSaverSuspendReq);
swaps(&stuff->length);
swapl(&stuff->suspend);
REQUEST_SIZE_MATCH(xScreenSaverSuspendReq);
swapl(&stuff->suspend);
return ProcScreenSaverSuspend(client);
}

View File

@ -2318,6 +2318,7 @@ SProcSyncCreateFence(ClientPtr client)
REQUEST(xSyncCreateFenceReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xSyncCreateFenceReq);
swapl(&stuff->d);
swapl(&stuff->fid);
return ProcSyncCreateFence(client);

View File

@ -502,10 +502,11 @@ XTestSwapFakeInput(ClientPtr client, xReq * req)
nev = ((req->length << 2) - sizeof(xReq)) / sizeof(xEvent);
for (ev = (xEvent *) &req[1]; --nev >= 0; ev++) {
int evtype = ev->u.u.type & 0177;
/* Swap event */
proc = EventSwapVector[ev->u.u.type & 0177];
proc = EventSwapVector[evtype];
/* no swapping proc; invalid event type? */
if (!proc || proc == NotImplemented) {
if (!proc || proc == NotImplemented || evtype == GenericEvent) {
client->errorValue = ev->u.u.type;
return BadValue;
}

View File

@ -811,8 +811,10 @@ XvdiSelectVideoNotify(ClientPtr client, DrawablePtr pDraw, BOOL onoff)
tpn = pn;
while (tpn) {
if (tpn->client == client) {
if (!onoff)
if (!onoff) {
tpn->client = NULL;
FreeResource(tpn->id, XvRTVideoNotify);
}
return Success;
}
if (!tpn->client)

View File

@ -605,22 +605,25 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
to->button = calloc(1, sizeof(ButtonClassRec));
if (!to->button)
FatalError("[Xi] no memory for class shift.\n");
to->button->numButtons = from->button->numButtons;
}
else
classes->button = NULL;
}
if (from->button->xkb_acts) {
if (!to->button->xkb_acts) {
to->button->xkb_acts = calloc(1, sizeof(XkbAction));
if (!to->button->xkb_acts)
FatalError("[Xi] not enough memory for xkb_acts.\n");
}
size_t maxbuttons = max(to->button->numButtons, from->button->numButtons);
to->button->xkb_acts = xnfreallocarray(to->button->xkb_acts,
maxbuttons,
sizeof(XkbAction));
memset(to->button->xkb_acts, 0, maxbuttons * sizeof(XkbAction));
memcpy(to->button->xkb_acts, from->button->xkb_acts,
sizeof(XkbAction));
from->button->numButtons * sizeof(XkbAction));
}
else
else {
free(to->button->xkb_acts);
to->button->xkb_acts = NULL;
}
memcpy(to->button->labels, from->button->labels,
from->button->numButtons * sizeof(Atom));
@ -1524,7 +1527,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
g = AllocGrab(devgrab);
BUG_WARN(!g);
*dev->deviceGrab.sync.event = *ev;
CopyPartialInternalEvent(dev->deviceGrab.sync.event, ev);
/* The listener array has a sequence of grabs and then one event
* selection. Implicit grab activation occurs through delivering an
@ -1901,7 +1904,7 @@ ProcessDeviceEvent(InternalEvent *ev, DeviceIntPtr device)
* nested) to clients. */
if (event->source_type == EVENT_SOURCE_FOCUS)
return;
if (!grab && CheckDeviceGrabs(device, event, 0))
if (!grab && CheckDeviceGrabs(device, ev, 0))
return;
break;
case ET_KeyRelease:
@ -1914,7 +1917,7 @@ ProcessDeviceEvent(InternalEvent *ev, DeviceIntPtr device)
if (b->map[key] == 0) /* there's no button 0 */
return;
event->detail.button = b->map[key];
if (!grab && CheckDeviceGrabs(device, event, 0)) {
if (!grab && CheckDeviceGrabs(device, ev, 0)) {
/* if a passive grab was activated, the event has been sent
* already */
return;

View File

@ -416,6 +416,11 @@ ProcXIChangeHierarchy(ClientPtr client)
size_t len; /* length of data remaining in request */
int rc = Success;
int flags[MAXDEVICES] = { 0 };
enum {
NO_CHANGE,
FLUSH,
CHANGED,
} changes = NO_CHANGE;
REQUEST(xXIChangeHierarchyReq);
REQUEST_AT_LEAST_SIZE(xXIChangeHierarchyReq);
@ -465,8 +470,9 @@ ProcXIChangeHierarchy(ClientPtr client)
rc = add_master(client, c, flags);
if (rc != Success)
goto unwind;
}
changes = FLUSH;
break;
}
case XIRemoveMaster:
{
xXIRemoveMasterInfo *r = (xXIRemoveMasterInfo *) any;
@ -475,8 +481,9 @@ ProcXIChangeHierarchy(ClientPtr client)
rc = remove_master(client, r, flags);
if (rc != Success)
goto unwind;
}
changes = FLUSH;
break;
}
case XIDetachSlave:
{
xXIDetachSlaveInfo *c = (xXIDetachSlaveInfo *) any;
@ -485,8 +492,9 @@ ProcXIChangeHierarchy(ClientPtr client)
rc = detach_slave(client, c, flags);
if (rc != Success)
goto unwind;
}
changes = CHANGED;
break;
}
case XIAttachSlave:
{
xXIAttachSlaveInfo *c = (xXIAttachSlaveInfo *) any;
@ -495,16 +503,25 @@ ProcXIChangeHierarchy(ClientPtr client)
rc = attach_slave(client, c, flags);
if (rc != Success)
goto unwind;
}
changes = CHANGED;
break;
}
default:
break;
}
if (changes == FLUSH) {
XISendDeviceHierarchyEvent(flags);
memset(flags, 0, sizeof(flags));
changes = NO_CHANGE;
}
len -= any->length * 4;
any = (xXIAnyHierarchyChangeInfo *) ((char *) any + any->length * 4);
}
unwind:
XISendDeviceHierarchyEvent(flags);
if (changes != NO_CHANGE)
XISendDeviceHierarchyEvent(flags);
return rc;
}

View File

@ -93,6 +93,7 @@ ProcXIPassiveGrabDevice(ClientPtr client)
GrabParameters param;
void *tmp;
int mask_len;
uint32_t length;
REQUEST(xXIPassiveGrabDeviceReq);
REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
@ -137,6 +138,12 @@ ProcXIPassiveGrabDevice(ClientPtr client)
return BadValue;
}
/* XI2 allows 32-bit keycodes but thanks to XKB we can never
* implement this. Just return an error for all keycodes that
* cannot work anyway, same for buttons > 255. */
if (stuff->detail > 255)
return XIAlreadyGrabbed;
if (XICheckInvalidMaskBits(client, (unsigned char *) &stuff[1],
stuff->mask_len * 4) != Success)
return BadValue;
@ -207,14 +214,8 @@ ProcXIPassiveGrabDevice(ClientPtr client)
&param, XI2, &mask);
break;
case XIGrabtypeKeycode:
/* XI2 allows 32-bit keycodes but thanks to XKB we can never
* implement this. Just return an error for all keycodes that
* cannot work anyway */
if (stuff->detail > 255)
status = XIAlreadyGrabbed;
else
status = GrabKey(client, dev, mod_dev, stuff->detail,
&param, XI2, &mask);
status = GrabKey(client, dev, mod_dev, stuff->detail,
&param, XI2, &mask);
break;
case XIGrabtypeEnter:
case XIGrabtypeFocusIn:
@ -247,9 +248,11 @@ ProcXIPassiveGrabDevice(ClientPtr client)
}
}
/* save the value before SRepXIPassiveGrabDevice swaps it */
length = rep.length;
WriteReplyToClient(client, sizeof(rep), &rep);
if (rep.num_modifiers)
WriteToClient(client, rep.length * 4, modifiers_failed);
WriteToClient(client, length * 4, modifiers_failed);
out:
free(modifiers_failed);
@ -334,6 +337,12 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
return BadValue;
}
/* We don't allow passive grabs for details > 255 anyway */
if (stuff->detail > 255) {
client->errorValue = stuff->detail;
return BadValue;
}
rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess);
if (rc != Success)
return rc;

View File

@ -730,7 +730,7 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type,
XIDestroyDeviceProperty(prop);
return BadAlloc;
}
new_value.size = len;
new_value.size = total_len;
new_value.type = type;
new_value.format = format;
@ -747,7 +747,7 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type,
case PropModePrepend:
new_data = new_value.data;
old_data = (void *) (((char *) new_value.data) +
(prop_value->size * size_in_bytes));
(len * size_in_bytes));
break;
}
if (new_data)
@ -890,7 +890,7 @@ ProcXChangeDeviceProperty(ClientPtr client)
REQUEST(xChangeDevicePropertyReq);
DeviceIntPtr dev;
unsigned long len;
int totalSize;
uint64_t totalSize;
int rc;
REQUEST_AT_LEAST_SIZE(xChangeDevicePropertyReq);
@ -902,6 +902,8 @@ ProcXChangeDeviceProperty(ClientPtr client)
rc = check_change_property(client, stuff->property, stuff->type,
stuff->format, stuff->mode, stuff->nUnits);
if (rc != Success)
return rc;
len = stuff->nUnits;
if (len > (bytes_to_int32(0xffffffff - sizeof(xChangeDevicePropertyReq))))
@ -1128,7 +1130,7 @@ ProcXIChangeProperty(ClientPtr client)
{
int rc;
DeviceIntPtr dev;
int totalSize;
uint64_t totalSize;
unsigned long len;
REQUEST(xXIChangePropertyReq);
@ -1141,6 +1143,9 @@ ProcXIChangeProperty(ClientPtr client)
rc = check_change_property(client, stuff->property, stuff->type,
stuff->format, stuff->mode, stuff->num_items);
if (rc != Success)
return rc;
len = stuff->num_items;
if (len > bytes_to_int32(0xffffffff - sizeof(xXIChangePropertyReq)))
return BadLength;

View File

@ -149,8 +149,7 @@ ProcXIQueryPointer(ClientPtr client)
if (pDev->button) {
int i;
rep.buttons_len =
bytes_to_int32(bits_to_bytes(pDev->button->numButtons));
rep.buttons_len = bytes_to_int32(bits_to_bytes(256)); /* button map up to 255 */
rep.length += rep.buttons_len;
buttons = calloc(rep.buttons_len, 4);
if (!buttons)

View File

@ -349,6 +349,7 @@ ProcXIGetSelectedEvents(ClientPtr client)
InputClientsPtr others = NULL;
xXIEventMask *evmask = NULL;
DeviceIntPtr dev;
uint32_t length;
REQUEST(xXIGetSelectedEventsReq);
REQUEST_SIZE_MATCH(xXIGetSelectedEventsReq);
@ -418,10 +419,12 @@ ProcXIGetSelectedEvents(ClientPtr client)
}
}
/* save the value before SRepXIGetSelectedEvents swaps it */
length = reply.length;
WriteReplyToClient(client, sizeof(xXIGetSelectedEventsReply), &reply);
if (reply.num_masks)
WriteToClient(client, reply.length * 4, buffer);
WriteToClient(client, length * 4, buffer);
free(buffer);
return Success;

View File

@ -620,6 +620,11 @@ compDestroyWindow(WindowPtr pWin)
ret = (*pScreen->DestroyWindow) (pWin);
cs->DestroyWindow = pScreen->DestroyWindow;
pScreen->DestroyWindow = compDestroyWindow;
/* Did we just destroy the overlay window? */
if (pWin == cs->pOverlayWin)
cs->pOverlayWin = NULL;
/* compCheckTree (pWin->drawable.pScreen); can't check -- tree isn't good*/
return ret;
}

View File

@ -26,9 +26,9 @@ dnl
dnl Process this file with autoconf to create configure.
AC_PREREQ(2.60)
AC_INIT([xorg-server], 21.0.99.1, [https://gitlab.freedesktop.org/xorg/xserver/issues], xorg-server)
RELEASE_DATE="2021-07-05"
RELEASE_NAME="Carrot and Ginger Soup"
AC_INIT([xorg-server], 21.1.13, [https://gitlab.freedesktop.org/xorg/xserver/issues], xorg-server)
RELEASE_DATE="2024-04-12"
RELEASE_NAME="Caramel Ice Cream"
AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([foreign dist-xz])
@ -67,8 +67,6 @@ dnl xkb-config.h covers XKB for the Xorg and Xnest DDXs.
AC_CONFIG_HEADERS(include/xkb-config.h)
dnl xwin-config.h covers the XWin DDX.
AC_CONFIG_HEADERS(include/xwin-config.h)
dnl xwayland-config.h covers Xwayland.
AC_CONFIG_HEADERS(include/xwayland-config.h)
dnl version-config.h covers the version numbers so they can be bumped without
dnl forcing an entire recompile.x
AC_CONFIG_HEADERS(include/version-config.h)
@ -166,8 +164,16 @@ AC_REPLACE_FUNCS([reallocarray strcasecmp strcasestr strlcat strlcpy strndup\
timingsafe_memcmp])
AM_CONDITIONAL(POLL, [test "x$ac_cv_func_poll" = "xyes"])
AC_CHECK_LIB([bsd], [arc4random_buf])
AC_CHECK_FUNCS([arc4random_buf])
# Checks for non-standard functions and fallback to libbsd if we can
# We only check for arc4random_buf, because if we have that, we don't
# need/use getentropy.
AC_LINK_IFELSE([AC_LANG_CALL([], [arc4random_buf])],
[TRY_LIBBSD="no"], [TRY_LIBBSD="yes"])
AS_IF([test "x$TRY_LIBBSD" = "xyes"],
[PKG_CHECK_MODULES([LIBBSD], [libbsd-overlay], [
CFLAGS="$CFLAGS $LIBBSD_CFLAGS"
LIBS="$LIBS $LIBBSD_LIBS"
], [:])])
AC_CHECK_DECLS([program_invocation_short_name], [], [], [[#include <errno.h>]])
@ -575,10 +581,6 @@ AC_ARG_ENABLE(xorg, AS_HELP_STRING([--enable-xorg], [Build Xorg server
AC_ARG_ENABLE(xvfb, AS_HELP_STRING([--enable-xvfb], [Build Xvfb server (default: yes)]), [XVFB=$enableval], [XVFB=yes])
AC_ARG_ENABLE(xnest, AS_HELP_STRING([--enable-xnest], [Build Xnest server (default: auto)]), [XNEST=$enableval], [XNEST=auto])
AC_ARG_ENABLE(xquartz, AS_HELP_STRING([--enable-xquartz], [Build Xquartz server for OS-X (default: auto)]), [XQUARTZ=$enableval], [XQUARTZ=auto])
AC_ARG_ENABLE(xwayland, AS_HELP_STRING([--enable-xwayland], [Build Xwayland server (default: auto)]), [XWAYLAND=$enableval], [XWAYLAND=auto])
AC_ARG_ENABLE(xwayland-eglstream, AS_HELP_STRING([--enable-xwayland-eglstream], [Build Xwayland eglstream support (default: no)]), [XWAYLAND_EGLSTREAM=$enableval], [XWAYLAND_EGLSTREAM=no])
AC_ARG_WITH(xwayland-path, AS_HELP_STRING([--with-xwayland-path=PATH], [Directory containing Xwayland executable (default: ${bindir})]),
[ xwayland_path="$withval" ], [ xwayland_path="$bindir" ])
AC_ARG_ENABLE(standalone-xpbproxy, AS_HELP_STRING([--enable-standalone-xpbproxy], [Build a standalone xpbproxy (in addition to the one integrated into Xquartz as a separate thread) (default: no)]), [STANDALONE_XPBPROXY=$enableval], [STANDALONE_XPBPROXY=no])
AC_ARG_ENABLE(xwin, AS_HELP_STRING([--enable-xwin], [Build XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto])
AC_ARG_ENABLE(glamor, AS_HELP_STRING([--enable-glamor], [Build glamor dix module (default: auto)]), [GLAMOR=$enableval], [GLAMOR=auto])
@ -685,9 +687,7 @@ case $host_os in
XQUARTZ=yes
XVFB=no
XNEST=no
XWAYLAND=no
COMPOSITE=no
DGA=no
DPMSExtension=no
XF86VIDMODE=no
@ -763,7 +763,7 @@ PKG_CHECK_MODULES(PIXMAN, $LIBPIXMAN)
REQUIRED_LIBS="$REQUIRED_LIBS $LIBPIXMAN $LIBXFONT xau"
dnl Core modules for most extensions, et al.
SDK_REQUIRED_MODULES="$XPROTO $RANDRPROTO $RENDERPROTO $XEXTPROTO $INPUTPROTO $KBPROTO $FONTSPROTO $LIBPIXMAN $LIBXCVT"
SDK_REQUIRED_MODULES="$XPROTO $RANDRPROTO $RENDERPROTO $XEXTPROTO $INPUTPROTO $KBPROTO $FONTSPROTO $LIBPIXMAN"
# Make SDK_REQUIRED_MODULES available for inclusion in xorg-server.pc
AC_SUBST(SDK_REQUIRED_MODULES)
@ -2019,7 +2019,7 @@ AM_CONDITIONAL([XORG_DRIVER_INPUT_INPUTTEST], [test "x$XORG_DRIVER_INPUT_INPUTTE
dnl glamor
if test "x$GLAMOR" = xauto; then
if echo "$XORG" "$XEPHYR" "$XWAYLAND" | grep -q yes ; then
if echo "$XORG" "$XEPHYR" | grep -q yes ; then
GLAMOR=yes
fi
fi
@ -2142,7 +2142,7 @@ if test "x$XQUARTZ" = xyes; then
AC_DEFINE(XQUARTZ,1,[Have Quartz])
AC_DEFINE(ROOTLESS,1,[Build Rootless code])
XQUARTZ_LIBS="$FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB $PRESENT_LIB"
XQUARTZ_LIBS="$COMPOSITE_LIB $FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB $PRESENT_LIB"
AC_SUBST([XQUARTZ_LIBS])
AC_CHECK_LIB([Xplugin],[xp_init],[:])
@ -2234,92 +2234,6 @@ AC_SUBST([KDRIVE_LOCAL_LIBS])
AC_SUBST([KDRIVE_LIBS])
AM_CONDITIONAL(XEPHYR, [test "x$KDRIVE" = xyes && test "x$XEPHYR" = xyes])
dnl Xwayland DDX
XWAYLANDMODULES="wayland-client >= 1.5.0 wayland-protocols >= 1.18"
if test "x$XF86VIDMODE" = xyes; then
XWAYLANDMODULES="$XWAYLANDMODULES $VIDMODEPROTO"
fi
if test "x$DRM" = xyes; then
XWAYLANDMODULES="$XWAYLANDMODULES $LIBDRM"
fi
if test "x$GLAMOR" = xyes; then
XWAYLANDMODULES="$XWAYLANDMODULES epoxy"
fi
PKG_CHECK_MODULES(XWAYLANDMODULES, [$XWAYLANDMODULES], [have_xwayland=yes], [have_xwayland=no])
AC_MSG_CHECKING([whether to build Xwayland DDX])
if test "x$XWAYLAND" = xauto; then
XWAYLAND="$have_xwayland"
fi
AC_MSG_RESULT([$XWAYLAND])
AM_CONDITIONAL(XWAYLAND, [test "x$XWAYLAND" = xyes])
if test "x$XWAYLAND" = xyes; then
if test "x$have_xwayland" = xno; then
AC_MSG_ERROR([Xwayland build explicitly requested, but required modules not found.])
fi
if test "x$GLAMOR" = xyes && test "x$GBM" = xyes; then
AC_DEFINE(XWL_HAS_GLAMOR, 1,
[Build xwayland with glamor support])
AC_SUBST(have_glamor, "true")
else
AC_SUBST(have_glamor, "false")
fi
PKG_CHECK_MODULES(WAYLAND_EGLSTREAM, [wayland-eglstream-protocols >= 1.0.2], [have_wl_eglstream=yes], [have_wl_eglstream=no])
if test "x$XWAYLAND_EGLSTREAM" = xauto; then
if test "x$have_wl_eglstream" = xyes && test "x$GLAMOR" = xyes; then
XWAYLAND_EGLSTREAM=yes
fi
fi
if test "x$XWAYLAND_EGLSTREAM" = xyes; then
if test "x$GLAMOR" != xyes; then
AC_MSG_ERROR([Xwayland eglstream support explicitly requested, but required modules not found.])
fi
if test "x$have_wl_eglstream" = xno; then
AC_MSG_ERROR([Xwayland eglstream support requires wayland-eglstream-protocols >= 1.0.2])
fi
AC_SUBST(WAYLAND_EGLSTREAM_DATADIR, `$PKG_CONFIG --variable=pkgdatadir wayland-eglstream-protocols`)
AC_DEFINE(XWL_HAS_EGLSTREAM, 1,
[Build xwayland with eglstream support])
AC_SUBST(have_eglstream, "true")
else
AC_SUBST(have_eglstream, "false")
fi
PKG_CHECK_MODULES([LIBXCVT], $LIBXCVT)
XWAYLAND_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $PRESENT_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB $DIX_LIB $OS_LIB"
XWAYLAND_SYS_LIBS="$XWAYLANDMODULES_LIBS $GLX_SYS_LIBS $LIBXCVT_LIBS"
AC_SUBST([XWAYLAND_LIBS])
AC_SUBST([XWAYLAND_SYS_LIBS])
if test "x$MONOTONIC_CLOCK" != xyes; then
AC_MSG_ERROR([Xwayland requires CLOCK_MONOTONIC support.])
fi
AC_PATH_PROG([WAYLAND_SCANNER], [wayland-scanner])
if test "x$WAYLAND_SCANNER" = x; then
PKG_CHECK_MODULES(WAYLAND_SCANNER, [wayland-scanner])
AC_SUBST(WAYLAND_SCANNER, `$PKG_CONFIG --variable=wayland_scanner wayland-scanner`)
fi
PKG_CHECK_MODULES(WAYLAND_SCANNER, [wayland-scanner >= 1.14.91],
AC_SUBST(SCANNER_ARG, 'private-code'),
AC_SUBST(SCANNER_ARG, 'code'))
AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, `$PKG_CONFIG --variable=pkgdatadir wayland-protocols`)
AC_SUBST(xwayland_path)
fi
AM_CONDITIONAL(XWAYLAND_EGLSTREAM, [test "x$XWAYLAND_EGLSTREAM" = "xyes"])
dnl and the rest of these are generic, so they're in config.h
dnl
@ -2450,9 +2364,6 @@ hw/kdrive/Makefile
hw/kdrive/ephyr/Makefile
hw/kdrive/ephyr/man/Makefile
hw/kdrive/src/Makefile
hw/xwayland/Makefile
hw/xwayland/man/Makefile
hw/xwayland/xwayland.pc
test/Makefile
xserver.ent
xorg-server.pc

View File

@ -447,14 +447,20 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
{
DeviceIntPtr *prev, other;
BOOL enabled;
BOOL dev_in_devices_list = FALSE;
int flags[MAXDEVICES] = { 0 };
if (!dev->enabled)
return TRUE;
for (prev = &inputInfo.devices;
*prev && (*prev != dev); prev = &(*prev)->next);
if (*prev != dev)
for (other = inputInfo.devices; other; other = other->next) {
if (other == dev) {
dev_in_devices_list = TRUE;
break;
}
}
if (!dev_in_devices_list)
return FALSE;
TouchEndPhysicallyActiveTouches(dev);
@ -471,6 +477,13 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
flags[other->id] |= XISlaveDetached;
}
}
for (other = inputInfo.off_devices; other; other = other->next) {
if (!IsMaster(other) && GetMaster(other, MASTER_ATTACHED) == dev) {
AttachDevice(NULL, other, NULL);
flags[other->id] |= XISlaveDetached;
}
}
}
else {
for (other = inputInfo.devices; other; other = other->next) {
@ -505,6 +518,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
LeaveWindow(dev);
SetFocusOut(dev);
for (prev = &inputInfo.devices;
*prev && (*prev != dev); prev = &(*prev)->next);
*prev = dev->next;
dev->next = inputInfo.off_devices;
inputInfo.off_devices = dev;
@ -520,6 +536,7 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
}
RecalculateMasterButtons(dev);
dev->master = NULL;
return TRUE;
}
@ -1064,6 +1081,11 @@ CloseDownDevices(void)
dev->master = NULL;
}
for (dev = inputInfo.off_devices; dev; dev = dev->next) {
if (!IsMaster(dev) && !IsFloating(dev))
dev->master = NULL;
}
CloseDeviceList(&inputInfo.devices);
CloseDeviceList(&inputInfo.off_devices);
@ -2525,6 +2547,8 @@ RecalculateMasterButtons(DeviceIntPtr slave)
if (master->button && master->button->numButtons != maxbuttons) {
int i;
int last_num_buttons = master->button->numButtons;
DeviceChangedEvent event = {
.header = ET_Internal,
.type = ET_DeviceChanged,
@ -2535,6 +2559,14 @@ RecalculateMasterButtons(DeviceIntPtr slave)
};
master->button->numButtons = maxbuttons;
if (last_num_buttons < maxbuttons) {
master->button->xkb_acts = xnfreallocarray(master->button->xkb_acts,
maxbuttons,
sizeof(XkbAction));
memset(&master->button->xkb_acts[last_num_buttons],
0,
(maxbuttons - last_num_buttons) * sizeof(XkbAction));
}
memcpy(&event.buttons.names, master->button->labels, maxbuttons *
sizeof(Atom));

View File

@ -3780,9 +3780,11 @@ ProcEstablishConnection(ClientPtr client)
auth_proto = (char *) prefix + sz_xConnClientPrefix;
auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto);
if ((client->req_len << 2) != sz_xReq + sz_xConnClientPrefix +
pad_to_int32(prefix->nbytesAuthProto) +
pad_to_int32(prefix->nbytesAuthString))
if (client->swapped && !AllowByteSwappedClients) {
reason = "Prohibited client endianess, see the Xserver man page ";
} else if ((client->req_len << 2) != sz_xReq + sz_xConnClientPrefix +
pad_to_int32(prefix->nbytesAuthProto) +
pad_to_int32(prefix->nbytesAuthString))
reason = "Bad length";
else if ((prefix->majorVersion != X_PROTOCOL) ||
(prefix->minorVersion != X_PROTOCOL_REVISION))

View File

@ -615,9 +615,15 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v,
ev->type = DeviceValuator;
ev->deviceid = dev->id;
ev->num_valuators = nval < 3 ? nval : 3;
ev->num_valuators = nval < 6 ? nval : 6;
ev->first_valuator = first;
switch (ev->num_valuators) {
case 6:
ev->valuator2 = v->axisVal[first + 5];
case 5:
ev->valuator2 = v->axisVal[first + 4];
case 4:
ev->valuator2 = v->axisVal[first + 3];
case 3:
ev->valuator2 = v->axisVal[first + 2];
case 2:
@ -626,7 +632,6 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v,
ev->valuator0 = v->axisVal[first];
break;
}
first += ev->num_valuators;
}
static void
@ -646,7 +651,7 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k,
ev->num_buttons = b->numButtons;
memcpy((char *) ev->buttons, (char *) b->down, 4);
}
else if (k) {
if (k) {
ev->classes_reported |= (1 << KeyClass);
ev->num_keys = k->xkbInfo->desc->max_key_code -
k->xkbInfo->desc->min_key_code;
@ -670,14 +675,26 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k,
}
}
/**
* The device state notify event is split across multiple 32-byte events.
* The first one contains the first 32 button state bits, the first 32
* key state bits, and the first 3 valuator values.
*
* If a device has more than that, the server sends out:
* - one deviceButtonStateNotify for buttons 32 and above
* - one deviceKeyStateNotify for keys 32 and above
* - one deviceValuator event per 6 valuators above valuator 4
*
* All events but the last one have the deviceid binary ORed with MORE_EVENTS,
*/
static void
DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
{
/* deviceStateNotify, deviceKeyStateNotify, deviceButtonStateNotify
* and one deviceValuator for each 6 valuators */
deviceStateNotify sev[3 + (MAX_VALUATORS + 6)/6];
int evcount = 1;
deviceStateNotify *ev, *sev;
deviceKeyStateNotify *kev;
deviceButtonStateNotify *bev;
deviceStateNotify *ev = sev;
KeyClassPtr k;
ButtonClassPtr b;
@ -690,87 +707,53 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
if ((b = dev->button) != NULL) {
nbuttons = b->numButtons;
if (nbuttons > 32)
if (nbuttons > 32) /* first 32 are encoded in deviceStateNotify */
evcount++;
}
if ((k = dev->key) != NULL) {
nkeys = k->xkbInfo->desc->max_key_code - k->xkbInfo->desc->min_key_code;
if (nkeys > 32)
if (nkeys > 32) /* first 32 are encoded in deviceStateNotify */
evcount++;
if (nbuttons > 0) {
evcount++;
}
}
if ((v = dev->valuator) != NULL) {
nval = v->numAxes;
if (nval > 3)
evcount++;
if (nval > 6) {
if (!(k && b))
evcount++;
if (nval > 9)
evcount += ((nval - 7) / 3);
}
/* first three are encoded in deviceStateNotify, then
* it's 6 per deviceValuator event */
evcount += ((nval - 3) + 6)/6;
}
sev = ev = xallocarray(evcount, sizeof(xEvent));
FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first);
BUG_RETURN(evcount <= ARRAY_SIZE(sev));
if (b != NULL) {
FixDeviceStateNotify(dev, ev++, NULL, b, v, first);
first += 3;
nval -= 3;
if (nbuttons > 32) {
(ev - 1)->deviceid |= MORE_EVENTS;
bev = (deviceButtonStateNotify *) ev++;
bev->type = DeviceButtonStateNotify;
bev->deviceid = dev->id;
memcpy((char *) &bev->buttons[4], (char *) &b->down[4],
DOWN_LENGTH - 4);
}
if (nval > 0) {
(ev - 1)->deviceid |= MORE_EVENTS;
FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
first += 3;
nval -= 3;
}
FixDeviceStateNotify(dev, ev, k, b, v, first);
if (b != NULL && nbuttons > 32) {
deviceButtonStateNotify *bev = (deviceButtonStateNotify *) ++ev;
(ev - 1)->deviceid |= MORE_EVENTS;
bev->type = DeviceButtonStateNotify;
bev->deviceid = dev->id;
memcpy((char *) &bev->buttons[4], (char *) &b->down[4],
DOWN_LENGTH - 4);
}
if (k != NULL) {
FixDeviceStateNotify(dev, ev++, k, NULL, v, first);
first += 3;
nval -= 3;
if (nkeys > 32) {
(ev - 1)->deviceid |= MORE_EVENTS;
kev = (deviceKeyStateNotify *) ev++;
kev->type = DeviceKeyStateNotify;
kev->deviceid = dev->id;
memmove((char *) &kev->keys[0], (char *) &k->down[4], 28);
}
if (nval > 0) {
(ev - 1)->deviceid |= MORE_EVENTS;
FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
first += 3;
nval -= 3;
}
if (k != NULL && nkeys > 32) {
deviceKeyStateNotify *kev = (deviceKeyStateNotify *) ++ev;
(ev - 1)->deviceid |= MORE_EVENTS;
kev->type = DeviceKeyStateNotify;
kev->deviceid = dev->id;
memmove((char *) &kev->keys[0], (char *) &k->down[4], 28);
}
first = 3;
nval -= 3;
while (nval > 0) {
FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first);
first += 3;
nval -= 3;
if (nval > 0) {
(ev - 1)->deviceid |= MORE_EVENTS;
FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
first += 3;
nval -= 3;
}
ev->deviceid |= MORE_EVENTS;
FixDeviceValuator(dev, (deviceValuator *) ++ev, v, first);
first += 6;
nval -= 6;
}
DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount,
DeviceStateNotifyMask, NullGrab);
free(sev);
}
void
@ -784,8 +767,9 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
mouse = IsFloating(dev) ? dev : GetMaster(dev, MASTER_POINTER);
/* XI 2 event */
btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0;
/* XI 2 event contains the logical button map - maps are CARD8
* so we need 256 bits for the possibly maximum mapping */
btlen = (mouse->button) ? bits_to_bytes(256) : 0;
btlen = bytes_to_int32(btlen);
len = sizeof(xXIFocusInEvent) + btlen * 4;

View File

@ -58,8 +58,6 @@ extern void DeviceFocusEvent(DeviceIntPtr dev,
extern void EnterWindow(DeviceIntPtr dev, WindowPtr win, int mode);
extern void LeaveWindow(DeviceIntPtr dev);
extern void CoreFocusEvent(DeviceIntPtr kbd,
int type, int mode, int detail, WindowPtr pWin);

View File

@ -467,6 +467,20 @@ WindowXI2MaskIsset(DeviceIntPtr dev, WindowPtr win, xEvent *ev)
return xi2mask_isset(inputMasks->xi2mask, dev, evtype);
}
/**
* When processing events we operate on InternalEvent pointers. They may actually refer to a
* an instance of DeviceEvent, GestureEvent or any other event that comprises the InternalEvent
* union. This works well in practice because we always look into event type before doing anything,
* except in the case of copying the event. Any copying of InternalEvent should use this function
* instead of doing *dst_event = *src_event whenever it's not clear whether source event actually
* points to full InternalEvent instance.
*/
void
CopyPartialInternalEvent(InternalEvent* dst_event, const InternalEvent* src_event)
{
memcpy(dst_event, src_event, src_event->any.length);
}
Mask
GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients * other)
{
@ -1191,7 +1205,7 @@ EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
}
}
eventlen = event->length;
eventlen = sizeof(InternalEvent);
qe = malloc(sizeof(QdEventRec) + eventlen);
if (!qe)
@ -1201,7 +1215,7 @@ EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
qe->pScreen = pSprite->hotPhys.pScreen;
qe->months = currentTime.months;
qe->event = (InternalEvent *) (qe + 1);
memcpy(qe->event, event, eventlen);
CopyPartialInternalEvent(qe->event, (InternalEvent *)event);
xorg_list_append(&qe->next, &syncEvents.pending);
}
@ -1319,7 +1333,7 @@ ComputeFreezes(void)
syncEvents.replayDev = (DeviceIntPtr) NULL;
if (!CheckDeviceGrabs(replayDev, &event->device_event,
if (!CheckDeviceGrabs(replayDev, event,
syncEvents.replayWin)) {
if (IsTouchEvent(event)) {
TouchPointInfoPtr ti =
@ -1491,16 +1505,13 @@ UpdateTouchesForGrab(DeviceIntPtr mouse)
CLIENT_BITS(listener->listener) == grab->resource) {
if (grab->grabtype == CORE || grab->grabtype == XI ||
!xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin)) {
/* Note that the grab will override any current listeners and if these listeners
already received touch events then this is the place to send touch end event
to complete the touch sequence.
if (listener->type == TOUCH_LISTENER_REGULAR &&
listener->state != TOUCH_LISTENER_AWAITING_BEGIN &&
listener->state != TOUCH_LISTENER_HAS_END) {
/* if the listener already got any events relating to the touch, we must send
a touch end because the grab overrides the previous listener and won't
itself send any touch events.
*/
TouchEmitTouchEnd(mouse, ti, 0, listener->listener);
}
Unfortunately GTK3 menu widget implementation relies on not getting touch end
event, so we can't fix the current behavior.
*/
listener->type = TOUCH_LISTENER_POINTER_GRAB;
} else {
listener->type = TOUCH_LISTENER_GRAB;
@ -3027,7 +3038,7 @@ BOOL
ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
{
BOOL rc = FALSE;
DeviceEvent event;
InternalEvent event;
if (dev->deviceGrab.grab) {
if (!dev->deviceGrab.fromPassiveGrab ||
@ -3042,16 +3053,16 @@ ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
if (win == NoneWin || win == PointerRootWin)
return FALSE;
event = (DeviceEvent) {
.header = ET_Internal,
.type = ET_FocusIn,
.length = sizeof(DeviceEvent),
.time = GetTimeInMillis(),
.deviceid = dev->id,
.sourceid = dev->id,
.detail.button = 0
event = (InternalEvent) {
.device_event.header = ET_Internal,
.device_event.type = ET_FocusIn,
.device_event.length = sizeof(DeviceEvent),
.device_event.time = GetTimeInMillis(),
.device_event.deviceid = dev->id,
.device_event.sourceid = dev->id,
.device_event.detail.button = 0
};
rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE,
rc = (CheckPassiveGrabsOnWindow(win, dev, &event, FALSE,
TRUE) != NULL);
if (rc)
DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveGrab);
@ -3068,7 +3079,7 @@ static BOOL
ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
{
BOOL rc = FALSE;
DeviceEvent event;
InternalEvent event;
if (dev->deviceGrab.grab) {
if (!dev->deviceGrab.fromPassiveGrab ||
@ -3080,16 +3091,16 @@ ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
(*dev->deviceGrab.DeactivateGrab) (dev);
}
event = (DeviceEvent) {
.header = ET_Internal,
.type = ET_Enter,
.length = sizeof(DeviceEvent),
.time = GetTimeInMillis(),
.deviceid = dev->id,
.sourceid = dev->id,
.detail.button = 0
event = (InternalEvent) {
.device_event.header = ET_Internal,
.device_event.type = ET_Enter,
.device_event.length = sizeof(DeviceEvent),
.device_event.time = GetTimeInMillis(),
.device_event.deviceid = dev->id,
.device_event.sourceid = dev->id,
.device_event.detail.button = 0
};
rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE,
rc = (CheckPassiveGrabsOnWindow(win, dev, &event, FALSE,
TRUE) != NULL);
if (rc)
DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveGrab);
@ -3873,7 +3884,7 @@ void ActivateGrabNoDelivery(DeviceIntPtr dev, GrabPtr grab,
if (grabinfo->sync.state == FROZEN_NO_EVENT)
grabinfo->sync.state = FROZEN_WITH_EVENT;
*grabinfo->sync.event = *real_event;
CopyPartialInternalEvent(grabinfo->sync.event, real_event);
}
static BOOL
@ -4141,14 +4152,15 @@ CheckPassiveGrabsOnWindow(WindowPtr pWin,
*/
Bool
CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor)
CheckDeviceGrabs(DeviceIntPtr device, InternalEvent *ievent, WindowPtr ancestor)
{
int i;
WindowPtr pWin = NULL;
FocusClassPtr focus =
IsPointerEvent((InternalEvent *) event) ? NULL : device->focus;
IsPointerEvent(ievent) ? NULL : device->focus;
BOOL sendCore = (IsMaster(device) && device->coreEvents);
Bool ret = FALSE;
DeviceEvent *event = &ievent->device_event;
if (event->type != ET_ButtonPress && event->type != ET_KeyPress)
return FALSE;
@ -4171,7 +4183,7 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor)
if (focus) {
for (; i < focus->traceGood; i++) {
pWin = focus->trace[i];
if (CheckPassiveGrabsOnWindow(pWin, device, (InternalEvent *) event,
if (CheckPassiveGrabsOnWindow(pWin, device, ievent,
sendCore, TRUE)) {
ret = TRUE;
goto out;
@ -4186,7 +4198,7 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor)
for (; i < device->spriteInfo->sprite->spriteTraceGood; i++) {
pWin = device->spriteInfo->sprite->spriteTrace[i];
if (CheckPassiveGrabsOnWindow(pWin, device, (InternalEvent *) event,
if (CheckPassiveGrabsOnWindow(pWin, device, ievent,
sendCore, TRUE)) {
ret = TRUE;
goto out;
@ -4454,7 +4466,7 @@ FreezeThisEventIfNeededForSyncGrab(DeviceIntPtr thisDev, InternalEvent *event)
case FREEZE_NEXT_EVENT:
grabinfo->sync.state = FROZEN_WITH_EVENT;
FreezeThaw(thisDev, TRUE);
*grabinfo->sync.event = *event;
CopyPartialInternalEvent(grabinfo->sync.event, event);
break;
}
}

View File

@ -155,14 +155,13 @@ dixMovePrivates(PrivatePtr *privates, int new_offset, unsigned bytes)
static Bool
fixupOneScreen(ScreenPtr pScreen, FixupFunc fixup, unsigned bytes)
{
intptr_t dist;
char *old;
uintptr_t old;
char *new;
DevPrivateKey *keyp, key;
DevPrivateType type;
int size;
old = (char *) pScreen->devPrivates;
old = (uintptr_t) pScreen->devPrivates;
size = global_keys[PRIVATE_SCREEN].offset;
if (!fixup (&pScreen->devPrivates, size, bytes))
return FALSE;
@ -182,9 +181,7 @@ fixupOneScreen(ScreenPtr pScreen, FixupFunc fixup, unsigned bytes)
if (fixup == dixMovePrivates)
new += bytes;
dist = new - old;
if (dist) {
if ((uintptr_t) new != old) {
for (type = PRIVATE_XSELINUX; type < PRIVATE_LAST; type++)
/* Walk the privates list, being careful as the
@ -199,10 +196,11 @@ fixupOneScreen(ScreenPtr pScreen, FixupFunc fixup, unsigned bytes)
* is contained within the allocation. Privates
* stored elsewhere will be left alone
*/
if (old <= (char *) key && (char *) key < old + size)
if (old <= (uintptr_t) key && (uintptr_t) key < old + size)
{
/* Compute new location of key */
key = (DevPrivateKey) ((char *) key + dist);
/* Compute new location of key (deriving from the new
* allocation to avoid UB) */
key = (DevPrivateKey) (new + ((uintptr_t) key - old));
/* Patch the list */
*keyp = key;

View File

@ -205,7 +205,8 @@ ProcChangeProperty(ClientPtr client)
WindowPtr pWin;
char format, mode;
unsigned long len;
int sizeInBytes, totalSize, err;
int sizeInBytes, err;
uint64_t totalSize;
REQUEST(xChangePropertyReq);

View File

@ -620,12 +620,15 @@ ilog2(int val)
unsigned int
ResourceClientBits(void)
{
static unsigned int cached = 0;
static unsigned int cache_ilog2 = 0;
static unsigned int cache_limit = 0;
if (cached == 0)
cached = ilog2(LimitClients);
if (LimitClients != cache_limit) {
cache_limit = LimitClients;
cache_ilog2 = ilog2(LimitClients);
}
return cached;
return cache_ilog2;
}
/*****************

View File

@ -260,8 +260,8 @@ glamor_build_program(ScreenPtr screen,
char *fs_vars = NULL;
char *vs_vars = NULL;
char *vs_prog_string;
char *fs_prog_string;
char *vs_prog_string = NULL;
char *fs_prog_string = NULL;
GLint fs_prog, vs_prog;
Bool gpu_shader4 = FALSE;
@ -383,6 +383,8 @@ fail:
glDeleteProgram(prog->prog);
prog->prog = 0;
}
free(vs_prog_string);
free(fs_prog_string);
free(version_string);
free(fs_vars);
free(vs_vars);

View File

@ -48,6 +48,7 @@
#include "indirect_util.h"
#include "protocol-versions.h"
#include "glxvndabi.h"
#include "xace.h"
static char GLXServerVendorName[] = "SGI";
@ -1392,6 +1393,13 @@ DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
if (!pPixmap)
return BadAlloc;
err = XaceHook(XACE_RESOURCE_ACCESS, client, glxDrawableId, RT_PIXMAP,
pPixmap, RT_NONE, NULL, DixCreateAccess);
if (err != Success) {
(*pGlxScreen->pScreen->DestroyPixmap) (pPixmap);
return err;
}
/* Assign the pixmap the same id as the pbuffer and add it as a
* resource so it and the DRI2 drawable will be reclaimed when the
* pbuffer is destroyed. */

View File

@ -115,6 +115,16 @@ render_type_is_pbuffer_only(unsigned renderType)
| __DRI_ATTRIB_FLOAT_BIT));
}
static int
server_has_depth(int depth)
{
int i;
for (i = 0; i < screenInfo.numPixmapFormats; i++)
if (screenInfo.formats[i].depth == depth)
return 1;
return 0;
}
static __GLXconfig *
createModeFromConfig(const __DRIcoreExtension * core,
const __DRIconfig * driConfig,
@ -178,6 +188,16 @@ createModeFromConfig(const __DRIcoreExtension * core,
if (!render_type_is_pbuffer_only(renderType))
drawableType |= GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
/* Make sure we don't advertise things the server isn't configured for */
if ((drawableType & (GLX_PBUFFER_BIT | GLX_PIXMAP_BIT)) &&
!server_has_depth(config->config.rgbBits)) {
drawableType &= ~(GLX_PBUFFER_BIT | GLX_PIXMAP_BIT);
if (!drawableType) {
free(config);
return NULL;
}
}
config->config.next = NULL;
config->config.visualType = visualType;
config->config.renderType = renderType;

View File

@ -22,20 +22,15 @@ if XQUARTZ
XQUARTZ_SUBDIRS = xquartz
endif
if XWAYLAND
XWAYLAND_SUBDIRS = xwayland
endif
SUBDIRS = \
$(XORG_SUBDIRS) \
$(XWIN_SUBDIRS) \
$(XVFB_SUBDIRS) \
$(XNEST_SUBDIRS) \
$(KDRIVE_SUBDIRS) \
$(XQUARTZ_SUBDIRS) \
$(XWAYLAND_SUBDIRS)
$(XQUARTZ_SUBDIRS)
DIST_SUBDIRS = xfree86 vfb xnest xwin xquartz kdrive xwayland
DIST_SUBDIRS = xfree86 vfb xnest xwin xquartz kdrive
relink:
$(AM_V_at)for i in $(SUBDIRS) ; do $(MAKE) -C $$i relink || exit 1 ; done

View File

@ -50,16 +50,16 @@ ephyr_glamor_xv_stop_video(KdScreenInfo *screen, void *data, Bool cleanup)
static int
ephyr_glamor_xv_set_port_attribute(KdScreenInfo *screen,
Atom attribute, INT32 value, void *data)
Atom attribute, int value, void *data)
{
return glamor_xv_set_port_attribute(data, attribute, value);
return glamor_xv_set_port_attribute(data, attribute, (INT32)value);
}
static int
ephyr_glamor_xv_get_port_attribute(KdScreenInfo *screen,
Atom attribute, INT32 *value, void *data)
Atom attribute, int *value, void *data)
{
return glamor_xv_get_port_attribute(data, attribute, value);
return glamor_xv_get_port_attribute(data, attribute, (INT32 *)value);
}
static void

View File

@ -246,7 +246,7 @@ miPointerSpriteFuncRec EphyrPointerSpriteFuncs = {
Bool
ephyrCursorInit(ScreenPtr screen)
{
if (!dixRegisterPrivateKey(&ephyrCursorPrivateKey, PRIVATE_CURSOR_BITS,
if (!dixRegisterPrivateKey(&ephyrCursorPrivateKey, PRIVATE_CURSOR,
sizeof(ephyrCursorRec)))
return FALSE;

View File

@ -70,25 +70,23 @@ InitInput(int argc, char **argv)
KdKeyboardInfo *ki;
KdPointerInfo *pi;
if (!SeatId) {
KdAddKeyboardDriver(&EphyrKeyboardDriver);
KdAddPointerDriver(&EphyrMouseDriver);
KdAddKeyboardDriver(&EphyrKeyboardDriver);
KdAddPointerDriver(&EphyrMouseDriver);
if (!kdHasKbd) {
ki = KdNewKeyboard();
if (!ki)
FatalError("Couldn't create Xephyr keyboard\n");
ki->driver = &EphyrKeyboardDriver;
KdAddKeyboard(ki);
}
if (!kdHasKbd) {
ki = KdNewKeyboard();
if (!ki)
FatalError("Couldn't create Xephyr keyboard\n");
ki->driver = &EphyrKeyboardDriver;
KdAddKeyboard(ki);
}
if (!kdHasPointer) {
pi = KdNewPointer();
if (!pi)
FatalError("Couldn't create Xephyr pointer\n");
pi->driver = &EphyrMouseDriver;
KdAddPointer(pi);
}
if (!kdHasPointer) {
pi = KdNewPointer();
if (!pi)
FatalError("Couldn't create Xephyr pointer\n");
pi->driver = &EphyrMouseDriver;
KdAddPointer(pi);
}
KdInitInput();

View File

@ -18,10 +18,6 @@ if build_xquartz
subdir('xquartz')
endif
if build_xwayland
subdir('xwayland')
endif
if build_xwin
subdir('xwin')
endif

View File

@ -71,6 +71,10 @@ endif
if get_option('pciaccess')
srcs_xorg_common += ['xf86pciBus.c', 'xf86VGAarbiter.c']
if host_machine.cpu() == 'sparc' or host_machine.cpu() == 'sparc64'
srcs_xorg_common += 'xf86sbusBus.c'
endif
endif
srcs_xorg_common += custom_target(

View File

@ -646,6 +646,7 @@ typedef enum {
FLAG_MAX_CLIENTS,
FLAG_IGLX,
FLAG_DEBUG,
FLAG_ALLOW_BYTE_SWAPPED_CLIENTS,
} FlagValues;
/**
@ -705,6 +706,8 @@ static OptionInfoRec FlagOptions[] = {
{0}, FALSE},
{FLAG_DEBUG, "Debug", OPTV_STRING,
{0}, FALSE},
{FLAG_ALLOW_BYTE_SWAPPED_CLIENTS, "AllowByteSwappedClients", OPTV_BOOLEAN,
{0}, FALSE},
{-1, NULL, OPTV_NONE,
{0}, FALSE},
};
@ -746,6 +749,14 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
xf86Msg(X_CONFIG, "Ignoring ABI Version\n");
}
xf86GetOptValBool(FlagOptions, FLAG_ALLOW_BYTE_SWAPPED_CLIENTS, &AllowByteSwappedClients);
if (AllowByteSwappedClients) {
xf86Msg(X_CONFIG, "Allowing byte-swapped clients\n");
}
else {
xf86Msg(X_CONFIG, "Prohibiting byte-swapped clients\n");
}
if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ADD_DEVICES)) {
xf86GetOptValBool(FlagOptions, FLAG_AUTO_ADD_DEVICES,
&xf86Info.autoAddDevices);

View File

@ -382,6 +382,10 @@ xf86VTLeave(void)
for (i = 0; i < xf86NumGPUScreens; i++)
xf86GPUScreens[i]->LeaveVT(xf86GPUScreens[i]);
if (systemd_logind_controls_session()) {
systemd_logind_drop_master();
}
if (!xf86VTSwitchAway())
goto switch_failed;

View File

@ -55,7 +55,6 @@
#include "xf86Xinput.h"
#include "xf86InPriv.h"
#include "mivalidate.h"
#include "xf86Crtc.h"
/* For xf86GetClocks */
#if defined(CSRG_BASED) || defined(__GNU__)
@ -852,9 +851,8 @@ xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
{
MessageType from = X_DEFAULT;
xf86MonPtr DDC = (xf86MonPtr) (pScrn->monitor->DDC);
int probedWidthmm, probedHeightmm;
int ddcWidthmm, ddcHeightmm;
int widthErr, heightErr;
xf86OutputPtr compat = xf86CompatOutput(pScrn);
/* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */
pScrn->widthmm = pScrn->monitor->widthmm;
@ -864,15 +862,11 @@ xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
/* DDC gives display size in mm for individual modes,
* but cm for monitor
*/
probedWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */
probedHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */
}
else if (compat && compat->mm_width > 0 && compat->mm_height > 0) {
probedWidthmm = compat->mm_width;
probedHeightmm = compat->mm_height;
ddcWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */
ddcHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */
}
else {
probedWidthmm = probedHeightmm = 0;
ddcWidthmm = ddcHeightmm = 0;
}
if (monitorResolution > 0) {
@ -898,15 +892,15 @@ xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
pScrn->widthmm, pScrn->heightmm);
/* Warn if config and probe disagree about display size */
if (probedWidthmm && probedHeightmm) {
if (ddcWidthmm && ddcHeightmm) {
if (pScrn->widthmm > 0) {
widthErr = abs(probedWidthmm - pScrn->widthmm);
widthErr = abs(ddcWidthmm - pScrn->widthmm);
}
else {
widthErr = 0;
}
if (pScrn->heightmm > 0) {
heightErr = abs(probedHeightmm - pScrn->heightmm);
heightErr = abs(ddcHeightmm - pScrn->heightmm);
}
else {
heightErr = 0;
@ -915,17 +909,17 @@ xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
/* Should include config file name for monitor here */
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n",
probedWidthmm, probedHeightmm, pScrn->widthmm,
ddcWidthmm, ddcHeightmm, pScrn->widthmm,
pScrn->heightmm);
}
}
}
else if (probedWidthmm && probedHeightmm) {
else if (ddcWidthmm && ddcHeightmm) {
from = X_PROBED;
xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
probedWidthmm, probedHeightmm);
pScrn->widthmm = probedWidthmm;
pScrn->heightmm = probedHeightmm;
ddcWidthmm, ddcHeightmm);
pScrn->widthmm = ddcWidthmm;
pScrn->heightmm = ddcHeightmm;
if (pScrn->widthmm > 0) {
pScrn->xDpi =
(int) ((double) pScrn->virtualX * MMPERINCH / pScrn->widthmm);

View File

@ -85,6 +85,11 @@
#include <X11/extensions/dpmsconst.h>
#include "dpmsproc.h"
#endif
#ifdef __linux__
#include <linux/major.h>
#include <sys/sysmacros.h>
#endif
#include <hotplug.h>
void (*xf86OSPMClose) (void) = NULL;
@ -105,23 +110,10 @@ static PixmapFormatRec formats[MAXFORMATS] = {
static int numFormats = 7;
static Bool formatsDone = FALSE;
#ifndef PRE_RELEASE
#define PRE_RELEASE XORG_VERSION_SNAP
#endif
static void
xf86PrintBanner(void)
{
#if PRE_RELEASE
xf86ErrorFVerb(0, "\n"
"This is a pre-release version of the X server from "
XVENDORNAME ".\n" "It is not supported in any way.\n"
"Bugs may be filed in the bugzilla at http://bugs.freedesktop.org/.\n"
"Select the \"xorg\" product for bugs you find in this release.\n"
"Before reporting bugs in pre-release versions please check the\n"
"latest version in the X.Org Foundation git repository.\n"
"See http://wiki.x.org/wiki/GitPage for git access instructions.\n");
#endif
xf86ErrorFVerb(0, "\nX.Org X Server %d.%d.%d",
XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH);
#if XORG_VERSION_SNAP > 0
@ -201,6 +193,17 @@ xf86PrivsElevated(void)
return PrivsElevated();
}
Bool
xf86HasTTYs(void)
{
#ifdef __linux__
struct stat tty0devAttributes;
return (stat("/dev/tty0", &tty0devAttributes) == 0 && major(tty0devAttributes.st_rdev) == TTY_MAJOR);
#else
return TRUE;
#endif
}
static void
xf86AutoConfigOutputDevices(void)
{
@ -425,7 +428,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
want_hw_access = TRUE;
/* Non-seat0 X servers should not open console */
if (!(flags & HW_SKIP_CONSOLE) && !ServerIsNotSeat0())
if (!(flags & HW_SKIP_CONSOLE) && !ServerIsNotSeat0() && xf86HasTTYs())
xorgHWOpenConsole = TRUE;
}

View File

@ -507,6 +507,8 @@ xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
/* scan through the modes in the sort order above */
if ((p->type & type) != type)
continue;
if (p->name == NULL)
continue;
if (strcmp(p->name, modep->name) == 0) {

View File

@ -158,6 +158,8 @@ extern _X_EXPORT Bool
xf86CallDriverProbe(struct _DriverRec *drv, Bool detect_only);
extern _X_EXPORT Bool
xf86PrivsElevated(void);
extern _X_EXPORT Bool
xf86HasTTYs(void);
#endif /* _NO_XF86_PROTOTYPES */

View File

@ -557,8 +557,13 @@ xf86platformProbeDev(DriverPtr drvp)
}
else {
/* for non-seat0 servers assume first device is the master */
if (ServerIsNotSeat0())
if (ServerIsNotSeat0()) {
break;
} else {
/* Accept the device if the driver is simpledrm */
if (strcmp(xf86_platform_devices[j].attribs->driver, "simpledrm") == 0)
break;
}
if (xf86IsPrimaryPlatform(&xf86_platform_devices[j]))
break;

View File

@ -507,7 +507,7 @@ handle_detailed_print(struct detailed_monitor_section *det_mon, void *data)
}
if (det_mon->type >= DS_VENDOR && det_mon->type <= DS_VENDOR_MAX) {
xf86DrvMsg(scrnIndex, X_INFO,
"Unknown vendor-specific block %hx\n",
"Unknown vendor-specific block %x\n",
det_mon->type - DS_VENDOR);
}

View File

@ -1,6 +1,6 @@
.\" shorthand for double quote that works everywhere.
.ds q \N'34'
.TH INPUTTEST __drivermansuffix__ __vendorversion__
.TH INPUTTEST @drivermansuffix@ @vendorversion@
.SH NAME
inputtest \- An X.Org input driver for testing
.SH SYNOPSIS
@ -21,7 +21,7 @@ exposed by Xorg. The primary use cases of this input driver are various
integration tests that need to interface with the input subsystem.
.SH CONFIGURATION DETAILS
Please refer to __xconfigfile__(__filemansuffix__) for general configuration
Please refer to @xconfigfile@(@filemansuffix@) for general configuration
details and for options that can be used with all input drivers. This
section only covers configuration details specific to this driver.
.PP
@ -109,4 +109,4 @@ processed all input events sent to it so far.
.SH AUTHORS
Povilas Kanapickas <povilas@radix.lt>
.SH "SEE ALSO"
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
@xservername@(@appmansuffix@), @xconfigfile@(@filemansuffix@), Xserver(@appmansuffix@), X(@miscmansuffix@)

View File

@ -856,39 +856,48 @@ read_input_from_connection(InputInfoPtr pInfo)
driver_data->buffer.valid_length += read_size;
while (1) {
xf86ITEventHeader *event_header;
xf86ITEventHeader event_header;
char *event_begin = driver_data->buffer.data + processed_size;
if (driver_data->buffer.valid_length - processed_size < sizeof(xf86ITEventHeader))
break;
event_header = (xf86ITEventHeader*) event_begin;
/* Note that event_begin pointer is not aligned, accessing it directly is
undefined behavior. We must use memcpy to copy the data to aligned data
area. Most compilers will optimize out this call out and use whatever
is most efficient to access unaligned data on a particular platform */
memcpy(&event_header, event_begin, sizeof(xf86ITEventHeader));
if (event_header->length >= EVENT_BUFFER_SIZE) {
if (event_header.length >= EVENT_BUFFER_SIZE) {
xf86IDrvMsg(pInfo, X_ERROR, "Received event with too long length: %d\n",
event_header->length);
event_header.length);
teardown_client_connection(pInfo);
return;
}
if (driver_data->buffer.valid_length - processed_size < event_header->length)
if (driver_data->buffer.valid_length - processed_size < event_header.length)
break;
if (is_supported_event(event_header->type)) {
int expected_event_size = get_event_size(event_header->type);
if (is_supported_event(event_header.type)) {
int expected_event_size = get_event_size(event_header.type);
if (event_header->length != expected_event_size) {
if (event_header.length != expected_event_size) {
xf86IDrvMsg(pInfo, X_ERROR, "Unexpected event length: was %d bytes, "
"expected %d (event type: %d)\n",
event_header->length, expected_event_size,
(int) event_header->type);
event_header.length, expected_event_size,
(int) event_header.type);
teardown_client_connection(pInfo);
return;
}
handle_event(pInfo, (xf86ITEventAny*) event_begin);
/* We could use event_begin pointer directly, but we want to ensure correct
data alignment (if only so that address sanitizer does not complain) */
xf86ITEventAny event_data;
memset(&event_data, 0, sizeof(event_data));
memcpy(&event_data, event_begin, event_header.length);
handle_event(pInfo, &event_data);
}
processed_size += event_header->length;
processed_size += event_header.length;
}
if (processed_size > 0) {
@ -1005,7 +1014,19 @@ pre_init(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
unlink(driver_data->socket_path);
#ifdef SOCK_NONBLOCK
driver_data->socket_fd = socket(PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
#else
int fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (fd >= 0) {
flags = fcntl(fd, F_GETFL, 0);
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
fd = -1;
}
}
driver_data->socket_fd = fd;
#endif
if (driver_data->socket_fd < 0) {
xf86IDrvMsg(pInfo, X_ERROR, "Failed to create a socket for communication: %s\n",
strerror(errno));

View File

@ -1086,7 +1086,8 @@ ms_dri2_screen_init(ScreenPtr screen)
* guess that the DRI and VDPAU drivers have the same name.
*/
if (strcmp(driver_names[0], "i965") == 0 ||
strcmp(driver_names[0], "iris") == 0) {
strcmp(driver_names[0], "iris") == 0 ||
strcmp(driver_names[0], "crocus") == 0) {
driver_names[1] = "va_gl";
} else {
driver_names[1] = driver_names[0];

View File

@ -2404,24 +2404,23 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG,
"Allocated crtc nr. %d to this screen.\n", num);
drmmode_crtc->use_gamma_lut =
drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].prop_id &&
/* Only use GAMMA_LUT if the size is 1024.
*
* Currently, the modesetting driver always passes a sigRGBbits value of
* 10 to xf86HandleColormaps. This causes it to create a RRCrtc gamma
* ramp of 1024 elements. If DRMMODE_CRTC_GAMMA_LUT_SIZE is larger than
* 1024 (for example on Intel GEN11, where it has a value of 262145)
* then xf86RandR12CrtcSetGamma will read past the end of the RRCrtc's
* gamma ramp when trying to copy it into the larger xf86Crtc gamma
* ramp.
*
* Since the larger GEN11 gamma ramp size hasn't been tested, just
* disable it for now. This will cause the modesetting driver to disable
* the CTM property and use the legacy DRM gamma ramp rather than the
* GAMMA_LUT property. */
drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].value == 1024 &&
xf86ReturnOptValBool(drmmode->Options, OPTION_USE_GAMMA_LUT, TRUE);
if (drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].prop_id &&
drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].value) {
/*
* GAMMA_LUT property supported, and so far tested to be safe to use by
* default for lut sizes up to 4096 slots. Intel Tigerlake+ has some
* issues, and a large GAMMA_LUT with 262145 slots, so keep GAMMA_LUT
* off for large lut sizes by default for now.
*/
drmmode_crtc->use_gamma_lut = drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].value <= 4096;
/* Allow config override. */
drmmode_crtc->use_gamma_lut = xf86ReturnOptValBool(drmmode->Options,
OPTION_USE_GAMMA_LUT,
drmmode_crtc->use_gamma_lut);
} else {
drmmode_crtc->use_gamma_lut = FALSE;
}
if (drmmode_crtc->use_gamma_lut &&
drmmode_crtc->props[DRMMODE_CRTC_CTM].prop_id) {
@ -3310,7 +3309,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r
}
}
ms->is_connector_vrr_capable =
ms->is_connector_vrr_capable |=
drmmode_connector_check_vrr_capable(drmmode->fd,
drmmode_output->output_id);
return 1;

View File

@ -71,6 +71,13 @@ One of \*qglamor\*q or \*qnone\*q. Default: glamor.
Enable DRI3 page flipping. The default is
.B on.
.TP
.BI "Option \*qVariableRefresh\*q \*q" boolean \*q
Enables support for enabling variable refresh on the Screen's CRTCs
when an suitable application is flipping via the Present extension.
.br
The default is
.B off.
.TP
.BI "Option \*qAsyncFlipSecondaries\*q \*q" boolean \*q
Use async flips for secondary video outputs on multi-display setups. If a screen
has multiple displays attached and DRI3 page flipping is used, then only one of
@ -99,8 +106,8 @@ will assign xrandr outputs LVDS and VGA-0 to this instance of the driver.
.BI "Option \*qUseGammaLUT\*q \*q" boolean \*q
Enable or disable use of the GAMMA_LUT property, when available.
When enabled, this option allows the driver to use gamma ramps with more
entries, if supported by the kernel.
Default: on.
entries, if supported by the kernel. By default, GAMMA_LUT will be used for
kms drivers which are known to be safe for use of GAMMA_LUT.
.TP
.SH "SEE ALSO"
@xservername@(@appmansuffix@), @xconfigfile@(@filemansuffix@), Xserver(@appmansuffix@),

View File

@ -120,7 +120,8 @@ static RRCrtcPtr
rr_crtc_covering_box(ScreenPtr pScreen, BoxPtr box, Bool screen_is_xf86_hint)
{
rrScrPrivPtr pScrPriv;
RRCrtcPtr crtc, best_crtc;
RROutputPtr primary_output;
RRCrtcPtr crtc, best_crtc, primary_crtc;
int coverage, best_coverage;
int c;
BoxRec crtc_box, cover_box;
@ -136,6 +137,11 @@ rr_crtc_covering_box(ScreenPtr pScreen, BoxPtr box, Bool screen_is_xf86_hint)
if (!pScrPriv)
return NULL;
primary_crtc = NULL;
primary_output = RRFirstOutput(pScreen);
if (primary_output)
primary_crtc = primary_output->crtc;
for (c = 0; c < pScrPriv->numCrtcs; c++) {
crtc = pScrPriv->crtcs[c];
@ -146,7 +152,8 @@ rr_crtc_covering_box(ScreenPtr pScreen, BoxPtr box, Bool screen_is_xf86_hint)
rr_crtc_box(crtc, &crtc_box);
box_intersect(&cover_box, &crtc_box, box);
coverage = box_area(&cover_box);
if (coverage > best_coverage) {
if ((coverage > best_coverage) ||
(coverage == best_coverage && crtc == primary_crtc)) {
best_crtc = crtc;
best_coverage = coverage;
}

View File

@ -677,6 +677,9 @@ Possible values are
or
.BR sync .
Unset by default.
.TP 7
.BI "Option \*qAllowByteSwappedClients\*q \*q" boolean \*q
Allow clients with a different byte-order than the server. Enabled by default.
.SH "MODULE SECTION"
The
.B Module

View File

@ -75,7 +75,7 @@ endif
if host_machine.system() == 'cygwin' or host_machine.system() == 'windows'
linker_export_flags = '-Wl,--export-all-symbols'
elif host_machine.system() == 'sunos'
elif host_machine.system() == 'sunos' or host_machine.system() == 'darwin'
linker_export_flags = []
else
linker_export_flags = '-Wl,--export-dynamic'

View File

@ -3256,10 +3256,8 @@ xf86OutputSetEDID(xf86OutputPtr output, xf86MonPtr edid_mon)
free(output->MonInfo);
output->MonInfo = edid_mon;
if (edid_mon) {
output->mm_width = 0;
output->mm_height = 0;
}
output->mm_width = 0;
output->mm_height = 0;
if (debug_modes) {
xf86DrvMsg(scrn->scrnIndex, X_INFO, "EDID for output %s\n",

View File

@ -839,6 +839,9 @@ xf86CompatOutput(ScrnInfoPtr pScrn)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
if (xf86CrtcConfigPrivateIndex == -1)
return NULL;
if (config->compat_output < 0)
return NULL;
return config->output[config->compat_output];

View File

@ -803,10 +803,14 @@ xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
{
struct libxcvt_mode_info *libxcvt_mode_info;
DisplayModeRec *Mode = xnfcalloc(1, sizeof(DisplayModeRec));
char *tmp;
libxcvt_mode_info =
libxcvt_gen_mode_info(HDisplay, VDisplay, VRefresh, Reduced, Interlaced);
XNFasprintf(&tmp, "%dx%d", HDisplay, VDisplay);
Mode->name = tmp;
Mode->VDisplay = libxcvt_mode_info->vdisplay;
Mode->HDisplay = libxcvt_mode_info->hdisplay;
Mode->Clock = libxcvt_mode_info->dot_clock;

View File

@ -806,12 +806,6 @@ xf86RandR12CreateScreenResources(ScreenPtr pScreen)
mmWidth = output->conf_monitor->mon_width;
mmHeight = output->conf_monitor->mon_height;
}
else if (output &&
(output->mm_width > 0 &&
output->mm_height > 0)) {
mmWidth = output->mm_width;
mmHeight = output->mm_height;
}
else {
/*
* Otherwise, just set the screen to DEFAULT_DPI
@ -1255,8 +1249,8 @@ xf86RandR12CrtcComputeGamma(xf86CrtcPtr crtc, LOCO *palette,
{
int gamma_slots;
unsigned shift;
CARD32 value;
int i, j;
CARD32 value = 0;
for (shift = 0; (gamma_size << shift) < (1 << 16); shift++);
@ -1273,6 +1267,10 @@ xf86RandR12CrtcComputeGamma(xf86CrtcPtr crtc, LOCO *palette,
for (j = 0; j < gamma_slots; j++)
crtc->gamma_red[i * gamma_slots + j] = value;
}
/* Replicate last value until end of crtc for gamma_size not a power of 2 */
for (j = i * gamma_slots; j < crtc->gamma_size; j++)
crtc->gamma_red[j] = value;
} else {
/* Downsampling of larger palette to smaller hw lut size */
for (i = 0; i < crtc->gamma_size; i++) {
@ -1299,6 +1297,10 @@ xf86RandR12CrtcComputeGamma(xf86CrtcPtr crtc, LOCO *palette,
for (j = 0; j < gamma_slots; j++)
crtc->gamma_green[i * gamma_slots + j] = value;
}
/* Replicate last value until end of crtc for gamma_size not a power of 2 */
for (j = i * gamma_slots; j < crtc->gamma_size; j++)
crtc->gamma_green[j] = value;
} else {
/* Downsampling of larger palette to smaller hw lut size */
for (i = 0; i < crtc->gamma_size; i++) {
@ -1325,6 +1327,10 @@ xf86RandR12CrtcComputeGamma(xf86CrtcPtr crtc, LOCO *palette,
for (j = 0; j < gamma_slots; j++)
crtc->gamma_blue[i * gamma_slots + j] = value;
}
/* Replicate last value until end of crtc for gamma_size not a power of 2 */
for (j = i * gamma_slots; j < crtc->gamma_size; j++)
crtc->gamma_blue[j] = value;
} else {
/* Downsampling of larger palette to smaller hw lut size */
for (i = 0; i < crtc->gamma_size; i++) {
@ -1358,6 +1364,7 @@ xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
{
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
xf86CrtcPtr crtc = randr_crtc->devPrivate;
int max_size = crtc->gamma_size;
if (crtc->funcs->gamma_set == NULL)
return FALSE;
@ -1372,12 +1379,15 @@ xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
randr_crtc->gammaBlue,
randr_crtc->gammaSize);
} else {
if (max_size > randr_crtc->gammaSize)
max_size = randr_crtc->gammaSize;
memcpy(crtc->gamma_red, randr_crtc->gammaRed,
crtc->gamma_size * sizeof(crtc->gamma_red[0]));
max_size * sizeof(crtc->gamma_red[0]));
memcpy(crtc->gamma_green, randr_crtc->gammaGreen,
crtc->gamma_size * sizeof(crtc->gamma_green[0]));
max_size * sizeof(crtc->gamma_green[0]));
memcpy(crtc->gamma_blue, randr_crtc->gammaBlue,
crtc->gamma_size * sizeof(crtc->gamma_blue[0]));
max_size * sizeof(crtc->gamma_blue[0]));
}
xf86RandR12CrtcReloadGamma(crtc);

View File

@ -38,6 +38,7 @@
#include "xf86.h"
#include "xf86platformBus.h"
#include "xf86Xinput.h"
#include "xf86Priv.h"
#include "globals.h"
#include "systemd-logind.h"
@ -302,6 +303,37 @@ cleanup:
dbus_error_free(&error);
}
/*
* Send a message to logind, to pause the drm device
* and ensure the drm_drop_master is done before
* VT_RELDISP when switching VT
*/
void systemd_logind_drop_master(void)
{
int i;
for (i = 0; i < xf86_num_platform_devices; i++) {
if (xf86_platform_devices[i].flags & XF86_PDEV_SERVER_FD) {
dbus_int32_t major, minor;
struct systemd_logind_info *info = &logind_info;
xf86_platform_devices[i].flags |= XF86_PDEV_PAUSED;
major = xf86_platform_odev_attributes(i)->major;
minor = xf86_platform_odev_attributes(i)->minor;
systemd_logind_ack_pause(info, minor, major);
}
}
}
static Bool are_platform_devices_resumed(void) {
int i;
for (i = 0; i < xf86_num_platform_devices; i++) {
if (xf86_platform_devices[i].flags & XF86_PDEV_PAUSED) {
return FALSE;
}
}
return TRUE;
}
static DBusHandlerResult
message_filter(DBusConnection * connection, DBusMessage * message, void *data)
{
@ -393,14 +425,14 @@ message_filter(DBusConnection * connection, DBusMessage * message, void *data)
/* info->vt_active gets set by systemd_logind_vtenter() */
info->active = TRUE;
if (pdev)
if (pdev) {
pdev->flags &= ~XF86_PDEV_PAUSED;
else
} else
systemd_logind_set_input_fd_for_all_devs(major, minor, fd,
info->vt_active);
/* Always call vtenter(), in case there are only legacy video devs */
systemd_logind_vtenter();
/* Call vtenter if all platform devices are resumed, or if there are no platform device */
if (are_platform_devices_resumed())
systemd_logind_vtenter();
}
return DBUS_HANDLER_RESULT_HANDLED;
}
@ -583,7 +615,7 @@ static struct dbus_core_hook core_hook = {
int
systemd_logind_init(void)
{
if (!ServerIsNotSeat0() && linux_parse_vt_settings(TRUE) && !linux_get_keeptty()) {
if (!ServerIsNotSeat0() && xf86HasTTYs() && linux_parse_vt_settings(TRUE) && !linux_get_keeptty()) {
LogMessage(X_INFO,
"systemd-logind: logind integration requires -keeptty and "
"-keeptty was not provided, disabling logind integration\n");

View File

@ -19,7 +19,7 @@ if get_option('pciaccess')
if host_machine.system() != 'linux'
srcs_xorg_os_support += 'bus/bsd_pci.c'
endif
if host_machine.cpu() == 'sparc'
if host_machine.cpu() == 'sparc' or host_machine.cpu() == 'sparc64'
srcs_xorg_os_support += 'bus/Sbus.c'
install_data('bus/xf86Sbus.h', install_dir: xorgsdkdir)
endif

View File

@ -2,13 +2,14 @@ noinst_LTLIBRARIES = libXquartz.la
AM_CFLAGS = $(DIX_CFLAGS)
AM_OBJCFLAGS = $(DIX_CFLAGS)
AM_CPPFLAGS = \
-DXQUARTZ_DATA_DIR=\"$(datadir)/X11/XQuartz\" \
-DXSERVER_VERSION=\"$(VERSION)\" \
-DBUNDLE_ID_PREFIX=\"$(BUNDLE_ID_PREFIX)\" \
-DUSE_NEW_CLUT \
-DXFree86Server \
-I$(top_srcdir)/miext/rootless \
-I$(top_builddir)/pseudoramiX \
-I$(top_builddir) \
-DX11LIBDIR=\"$(libdir)\"
-I$(top_builddir)
if GLX
GL_DIR = GL
@ -21,6 +22,7 @@ DIST_SUBDIRS = bundle . GL xpr pbproxy mach-startup man
libXquartz_la_SOURCES = \
$(top_srcdir)/mi/miinitext.c \
$(top_srcdir)/mi/miinitext.h \
NSUserDefaults+XQuartzDefaults.m \
X11Application.m \
X11Controller.m \
applewm.c \
@ -36,12 +38,14 @@ libXquartz_la_SOURCES = \
libXquartz_la_LIBADD = $(top_builddir)/pseudoramiX/libPseudoramiX.la
EXTRA_DIST = \
NSUserDefaults+XQuartzDefaults.h \
X11Application.h \
X11Controller.h \
applewmExt.h \
darwin.h \
darwinfb.h \
darwinEvents.h \
defaults.plist \
keysym2ucs.h \
quartz.h \
quartzKeyboard.h \

View File

@ -0,0 +1,49 @@
//
// NSUserDefaults+XQuartzDefaults.h
// XQuartz
//
// Created by Jeremy Huddleston Sequoia on 2021.02.19.
// Copyright (c) 2021 Apple Inc. All rights reserved.
//
#import <Foundation/Foundation.h>
extern NSString * const XQuartzPrefKeyAppsMenu;
extern NSString * const XQuartzPrefKeyFakeButtons;
extern NSString * const XQuartzPrefKeyFakeButton2;
extern NSString * const XQuartzPrefKeyFakeButton3;
extern NSString * const XQuartzPrefKeyKeyEquivs;
extern NSString * const XQuartzPrefKeyFullscreenHotkeys;
extern NSString * const XQuartzPrefKeyFullscreenMenu;
extern NSString * const XQuartzPrefKeySyncKeymap;
extern NSString * const XQuartzPrefKeyDepth;
extern NSString * const XQuartzPrefKeyNoAuth;
extern NSString * const XQuartzPrefKeyNoTCP;
extern NSString * const XQuartzPrefKeyDoneXinitCheck;
extern NSString * const XQuartzPrefKeyNoQuitAlert;
extern NSString * const XQuartzPrefKeyNoRANDRAlert;
extern NSString * const XQuartzPrefKeyOptionSendsAlt;
extern NSString * const XQuartzPrefKeyAppKitModifiers;
extern NSString * const XQuartzPrefKeyWindowItemModifiers;
extern NSString * const XQuartzPrefKeyRootless;
extern NSString * const XQuartzPrefKeyRENDERExtension;
extern NSString * const XQuartzPrefKeyTESTExtension;
extern NSString * const XQuartzPrefKeyLoginShell;
extern NSString * const XQuartzPrefKeyClickThrough;
extern NSString * const XQuartzPrefKeyFocusFollowsMouse;
extern NSString * const XQuartzPrefKeyFocusOnNewWindow;
extern NSString * const XQuartzPrefKeyScrollInDeviceDirection;
extern NSString * const XQuartzPrefKeySyncPasteboard;
extern NSString * const XQuartzPrefKeySyncPasteboardToClipboard;
extern NSString * const XQuartzPrefKeySyncPasteboardToPrimary;
extern NSString * const XQuartzPrefKeySyncClipboardToPasteBoard;
extern NSString * const XQuartzPrefKeySyncPrimaryOnSelect;
@interface NSUserDefaults (XQuartzDefaults)
+ (NSUserDefaults *)globalDefaults;
+ (NSUserDefaults *)dockDefaults;
+ (NSUserDefaults *)xquartzDefaults;
@end

View File

@ -0,0 +1,148 @@
//
// NSUserDefaults+XQuartzDefaults.m
// XQuartz
//
// Created by Jeremy Huddleston Sequoia on 2021.02.19.
// Copyright (c) 2021 Apple Inc. All rights reserved.
//
#import "NSUserDefaults+XQuartzDefaults.h"
#import <dispatch/dispatch.h>
NSString * const XQuartzPrefKeyAppsMenu = @"apps_menu";
NSString * const XQuartzPrefKeyFakeButtons = @"enable_fake_buttons";
NSString * const XQuartzPrefKeyFakeButton2 = @"fake_button2";
NSString * const XQuartzPrefKeyFakeButton3 = @"fake_button3";
NSString * const XQuartzPrefKeyKeyEquivs = @"enable_key_equivalents";
NSString * const XQuartzPrefKeyFullscreenHotkeys = @"fullscreen_hotkeys";
NSString * const XQuartzPrefKeyFullscreenMenu = @"fullscreen_menu";
NSString * const XQuartzPrefKeySyncKeymap = @"sync_keymap";
NSString * const XQuartzPrefKeyDepth = @"depth";
NSString * const XQuartzPrefKeyNoAuth = @"no_auth";
NSString * const XQuartzPrefKeyNoTCP = @"nolisten_tcp";
NSString * const XQuartzPrefKeyDoneXinitCheck = @"done_xinit_check";
NSString * const XQuartzPrefKeyNoQuitAlert = @"no_quit_alert";
NSString * const XQuartzPrefKeyNoRANDRAlert = @"no_randr_alert";
NSString * const XQuartzPrefKeyOptionSendsAlt = @"option_sends_alt";
NSString * const XQuartzPrefKeyAppKitModifiers = @"appkit_modifiers";
NSString * const XQuartzPrefKeyWindowItemModifiers = @"window_item_modifiers";
NSString * const XQuartzPrefKeyRootless = @"rootless";
NSString * const XQuartzPrefKeyRENDERExtension = @"enable_render_extension";
NSString * const XQuartzPrefKeyTESTExtension = @"enable_test_extensions";
NSString * const XQuartzPrefKeyLoginShell = @"login_shell";
NSString * const XQuartzPrefKeyUpdateFeed = @"update_feed";
NSString * const XQuartzPrefKeyClickThrough = @"wm_click_through";
NSString * const XQuartzPrefKeyFocusFollowsMouse = @"wm_ffm";
NSString * const XQuartzPrefKeyFocusOnNewWindow = @"wm_focus_on_new_window";
NSString * const XQuartzPrefKeyScrollInDeviceDirection = @"scroll_in_device_direction";
NSString * const XQuartzPrefKeySyncPasteboard = @"sync_pasteboard";
NSString * const XQuartzPrefKeySyncPasteboardToClipboard = @"sync_pasteboard_to_clipboard";
NSString * const XQuartzPrefKeySyncPasteboardToPrimary = @"sync_pasteboard_to_primary";
NSString * const XQuartzPrefKeySyncClipboardToPasteBoard = @"sync_clipboard_to_pasteboard";
NSString * const XQuartzPrefKeySyncPrimaryOnSelect = @"sync_primary_on_select";
@implementation NSUserDefaults (XQuartzDefaults)
+ (NSUserDefaults *)globalDefaults
{
static dispatch_once_t once;
static NSUserDefaults *defaults;
dispatch_once(&once, ^{
NSString * const defaultsDomain = @".GlobalPreferences";
defaults = [[[NSUserDefaults alloc] initWithSuiteName:defaultsDomain] retain];
NSDictionary<NSString *, id> * const defaultDefaultsDict = @{
@"AppleSpacesSwitchOnActivate" : @(YES),
};
[defaults registerDefaults:defaultDefaultsDict];
});
return defaults;
}
+ (NSUserDefaults *)dockDefaults
{
static dispatch_once_t once;
static NSUserDefaults *defaults;
dispatch_once(&once, ^{
NSString * const defaultsDomain = @"com.apple.dock";
defaults = [[[NSUserDefaults alloc] initWithSuiteName:defaultsDomain] retain];
NSDictionary<NSString *, id> * const defaultDefaultsDict = @{
@"workspaces" : @(NO),
};
[defaults registerDefaults:defaultDefaultsDict];
});
return defaults;
}
+ (NSUserDefaults *)xquartzDefaults
{
static dispatch_once_t once;
static NSUserDefaults *defaults;
dispatch_once(&once, ^{
NSString * const defaultsDomain = @(BUNDLE_ID_PREFIX ".X11");
NSString * const defaultDefaultsDomain = NSBundle.mainBundle.bundleIdentifier;
if ([defaultsDomain isEqualToString:defaultDefaultsDomain]) {
defaults = [NSUserDefaults.standardUserDefaults retain];
} else {
defaults = [[[NSUserDefaults alloc] initWithSuiteName:defaultsDomain] retain];
}
NSString *defaultWindowItemModifiers = @"command";
NSString * const defaultWindowItemModifiersLocalized = NSLocalizedString(@"window item modifiers", @"window item modifiers");
if (![defaultWindowItemModifiersLocalized isEqualToString:@"window item modifiers"]) {
defaultWindowItemModifiers = defaultWindowItemModifiersLocalized;
}
NSDictionary<NSString *, id> * const defaultDefaultsDict = @{
XQuartzPrefKeyFakeButtons : @(NO),
// XQuartzPrefKeyFakeButton2 nil default
// XQuartzPrefKeyFakeButton3 nil default
XQuartzPrefKeyKeyEquivs : @(YES),
XQuartzPrefKeyFullscreenHotkeys : @(NO),
XQuartzPrefKeyFullscreenMenu : @(NO),
XQuartzPrefKeySyncKeymap : @(NO),
XQuartzPrefKeyDepth : @(-1),
XQuartzPrefKeyNoAuth : @(NO),
XQuartzPrefKeyNoTCP : @(NO),
XQuartzPrefKeyDoneXinitCheck : @(NO),
XQuartzPrefKeyNoQuitAlert : @(NO),
XQuartzPrefKeyNoRANDRAlert : @(NO),
XQuartzPrefKeyOptionSendsAlt : @(NO),
// XQuartzPrefKeyAppKitModifiers nil default
XQuartzPrefKeyWindowItemModifiers : defaultWindowItemModifiers,
XQuartzPrefKeyRootless : @(YES),
XQuartzPrefKeyRENDERExtension : @(YES),
XQuartzPrefKeyTESTExtension : @(NO),
XQuartzPrefKeyLoginShell : @"/bin/sh",
XQuartzPrefKeyClickThrough : @(NO),
XQuartzPrefKeyFocusFollowsMouse : @(NO),
XQuartzPrefKeyFocusOnNewWindow : @(YES),
XQuartzPrefKeyScrollInDeviceDirection : @(NO),
XQuartzPrefKeySyncPasteboard : @(YES),
XQuartzPrefKeySyncPasteboardToClipboard : @(YES),
XQuartzPrefKeySyncPasteboardToPrimary : @(YES),
XQuartzPrefKeySyncClipboardToPasteBoard : @(YES),
XQuartzPrefKeySyncPrimaryOnSelect : @(NO),
};
[defaults registerDefaults:defaultDefaultsDict];
NSString * const systemDefaultsPlistPath = [@(XQUARTZ_DATA_DIR) stringByAppendingPathComponent:@"defaults.plist"];
NSDictionary <NSString *, id> * const systemDefaultsDict = [NSDictionary dictionaryWithContentsOfFile:systemDefaultsPlistPath];
[defaults registerDefaults:systemDefaultsDict];
});
return defaults;
}
@end

View File

@ -42,20 +42,6 @@
@property (nonatomic, readwrite, strong) X11Controller *controller;
@property (nonatomic, readonly, assign) OSX_BOOL x_active;
- (CFPropertyListRef)prefs_get_copy:(NSString *)key CF_RETURNS_RETAINED;
- (int)prefs_get_integer:(NSString *)key default:(int)def;
- (const char *)prefs_get_string:(NSString *)key default:(const char *)def;
- (float)prefs_get_float:(NSString *)key default:(float)def;
- (int)prefs_get_boolean:(NSString *)key default:(int)def;
- (NSURL *)prefs_copy_url:(NSString *)key default:(NSURL *)def
NS_RETURNS_RETAINED;
- (NSArray *)prefs_get_array:(NSString *)key;
- (void)prefs_set_integer:(NSString *)key value:(int)value;
- (void)prefs_set_float:(NSString *)key value:(float)value;
- (void)prefs_set_boolean:(NSString *)key value:(int)value;
- (void)prefs_set_array:(NSString *)key value:(NSArray *)value;
- (void)prefs_set_string:(NSString *)key value:(NSString *)value;
- (void)prefs_synchronize;
@end
extern X11Application * X11App;
@ -84,40 +70,6 @@ X11ApplicationCanEnterRandR(void);
void
X11ApplicationMain(int argc, char **argv, char **envp);
#define PREFS_APPSMENU "apps_menu"
#define PREFS_FAKEBUTTONS "enable_fake_buttons"
#define PREFS_KEYEQUIVS "enable_key_equivalents"
#define PREFS_FULLSCREEN_HOTKEYS "fullscreen_hotkeys"
#define PREFS_FULLSCREEN_MENU "fullscreen_menu"
#define PREFS_SYNC_KEYMAP "sync_keymap"
#define PREFS_DEPTH "depth"
#define PREFS_NO_AUTH "no_auth"
#define PREFS_NO_TCP "nolisten_tcp"
#define PREFS_DONE_XINIT_CHECK "done_xinit_check"
#define PREFS_NO_QUIT_ALERT "no_quit_alert"
#define PREFS_NO_RANDR_ALERT "no_randr_alert"
#define PREFS_OPTION_SENDS_ALT "option_sends_alt"
#define PREFS_FAKE_BUTTON2 "fake_button2"
#define PREFS_FAKE_BUTTON3 "fake_button3"
#define PREFS_APPKIT_MODIFIERS "appkit_modifiers"
#define PREFS_WINDOW_ITEM_MODIFIERS "window_item_modifiers"
#define PREFS_ROOTLESS "rootless"
#define PREFS_RENDER_EXTENSION "enable_render_extension"
#define PREFS_TEST_EXTENSIONS "enable_test_extensions"
#define PREFS_XP_OPTIONS "xp_options"
#define PREFS_LOGIN_SHELL "login_shell"
#define PREFS_UPDATE_FEED "update_feed"
#define PREFS_CLICK_THROUGH "wm_click_through"
#define PREFS_FFM "wm_ffm"
#define PREFS_FOCUS_ON_NEW_WINDOW "wm_focus_on_new_window"
#define PREFS_SCROLL_IN_DEV_DIRECTION "scroll_in_device_direction"
extern Bool XQuartzScrollInDeviceDirection;
#define PREFS_SYNC_PB "sync_pasteboard"
#define PREFS_SYNC_PB_TO_CLIPBOARD "sync_pasteboard_to_clipboard"
#define PREFS_SYNC_PB_TO_PRIMARY "sync_pasteboard_to_primary"
#define PREFS_SYNC_CLIPBOARD_TO_PB "sync_clipboard_to_pasteboard"
#define PREFS_SYNC_PRIMARY_ON_SELECT "sync_primary_on_select"
#endif /* X11APPLICATION_H */

View File

@ -35,6 +35,7 @@
#endif
#import "X11Application.h"
#import "NSUserDefaults+XQuartzDefaults.h"
#include "darwin.h"
#include "quartz.h"
@ -55,8 +56,6 @@
extern int
xpbproxy_run(void);
#define DEFAULTS_FILE X11LIBDIR "/X11/xserver/Xquartz.plist"
#ifndef XSERVER_VERSION
#define XSERVER_VERSION "?"
#endif
@ -101,8 +100,6 @@ static BOOL bgMouseLocationUpdated = FALSE;
X11Application *X11App;
CFStringRef app_prefs_domain_cfstr = NULL;
#define ALL_KEY_MASKS (NSShiftKeyMask | NSControlKeyMask | \
NSAlternateKeyMask | NSCommandKeyMask)
@ -270,6 +267,8 @@ QuartzModeBundleInit(void);
case NSLeftMouseUp:
case NSRightMouseUp:
case NSOtherMouseUp:
case NSScrollWheel:
if ([e window] != nil) {
/* Pointer event has an (AppKit) window. Probably something for the kit. */
for_x = NO;
@ -420,7 +419,7 @@ QuartzModeBundleInit(void);
case NSApplicationActivatedEventType:
for_x = NO;
if ([e window] == nil && x_was_active) {
BOOL order_all_windows = YES, workspaces, ok;
BOOL order_all_windows = YES;
for_appkit = NO;
#if APPKIT_APPFLAGS_HACK
@ -433,26 +432,9 @@ QuartzModeBundleInit(void);
[self set_front_process:nil];
/* Get the Spaces preference for SwitchOnActivate */
(void)CFPreferencesAppSynchronize(CFSTR("com.apple.dock"));
workspaces =
CFPreferencesGetAppBooleanValue(CFSTR("workspaces"),
CFSTR(
"com.apple.dock"),
&ok);
if (!ok)
workspaces = NO;
BOOL const workspaces = [NSUserDefaults.dockDefaults boolForKey:@"workspaces"];
if (workspaces) {
(void)CFPreferencesAppSynchronize(CFSTR(
".GlobalPreferences"));
order_all_windows =
CFPreferencesGetAppBooleanValue(CFSTR(
"AppleSpacesSwitchOnActivate"),
CFSTR(
".GlobalPreferences"),
&ok);
if (!ok)
order_all_windows = YES;
order_all_windows = [NSUserDefaults.globalDefaults boolForKey:@"AppleSpacesSwitchOnActivate"];
}
/* TODO: In the workspaces && !AppleSpacesSwitchOnActivate case, the windows are ordered
@ -463,8 +445,7 @@ QuartzModeBundleInit(void);
* be restoring one of them.
*/
if ([e data2] & 0x10) { // 0x10 (bfCPSOrderAllWindowsForward) is set when we use cmd-tab or the dock icon
DarwinSendDDXEvent(kXquartzBringAllToFront, 1,
order_all_windows);
DarwinSendDDXEvent(kXquartzBringAllToFront, 1, order_all_windows);
}
}
break;
@ -487,12 +468,14 @@ QuartzModeBundleInit(void);
break; /* for gcc */
}
if (for_appkit) [super sendEvent:e];
if (for_appkit) {
[super sendEvent:e];
}
if (for_x) {
dispatch_async(eventTranslationQueue, ^{
[self sendX11NSEvent:e];
});
[self sendX11NSEvent:e];
});
}
}
@ -524,404 +507,50 @@ QuartzModeBundleInit(void);
(void)[self.controller application:self openFile:cmd];
}
/* user preferences */
/* Note that these functions only work for arrays whose elements
can be toll-free-bridged between NS and CF worlds. */
static const void *
cfretain(CFAllocatorRef a, const void *b)
{
return CFRetain(b);
}
static void
cfrelease(CFAllocatorRef a, const void *b)
{
CFRelease(b);
}
CF_RETURNS_RETAINED
static CFMutableArrayRef
nsarray_to_cfarray(NSArray *in)
{
CFMutableArrayRef out;
CFArrayCallBacks cb;
NSObject *ns;
const CFTypeRef *cf;
int i, count;
memset(&cb, 0, sizeof(cb));
cb.version = 0;
cb.retain = cfretain;
cb.release = cfrelease;
count = [in count];
out = CFArrayCreateMutable(NULL, count, &cb);
for (i = 0; i < count; i++) {
ns = [in objectAtIndex:i];
if ([ns isKindOfClass:[NSArray class]])
cf = (CFTypeRef)nsarray_to_cfarray((NSArray *)ns);
else
cf = CFRetain((CFTypeRef)ns);
CFArrayAppendValue(out, cf);
CFRelease(cf);
}
return out;
}
static NSMutableArray *
cfarray_to_nsarray(CFArrayRef in)
{
NSMutableArray *out;
const CFTypeRef *cf;
NSObject *ns;
int i, count;
count = CFArrayGetCount(in);
out = [[NSMutableArray alloc] initWithCapacity:count];
for (i = 0; i < count; i++) {
cf = CFArrayGetValueAtIndex(in, i);
if (CFGetTypeID(cf) == CFArrayGetTypeID())
ns = cfarray_to_nsarray((CFArrayRef)cf);
else
ns = [(id) cf retain];
[out addObject:ns];
[ns release];
}
return out;
}
- (CFPropertyListRef) prefs_get_copy:(NSString *)key
{
CFPropertyListRef value;
value = CFPreferencesCopyAppValue((CFStringRef)key,
app_prefs_domain_cfstr);
if (value == NULL) {
static CFDictionaryRef defaults;
if (defaults == NULL) {
CFStringRef error = NULL;
CFDataRef data;
CFURLRef url;
SInt32 error_code;
url = (CFURLCreateFromFileSystemRepresentation
(NULL, (unsigned char *)DEFAULTS_FILE,
strlen(DEFAULTS_FILE), false));
if (CFURLCreateDataAndPropertiesFromResource(NULL, url, &data,
NULL, NULL,
&error_code)) {
defaults = (CFPropertyListCreateFromXMLData
(NULL, data,
kCFPropertyListMutableContainersAndLeaves,
&error));
if (error != NULL) CFRelease(error);
CFRelease(data);
}
CFRelease(url);
if (defaults != NULL) {
NSMutableArray *apps, *elt;
int count, i;
NSString *name, *nname;
/* Localize the names in the default apps menu. */
apps =
[(NSDictionary *) defaults objectForKey:@PREFS_APPSMENU];
if (apps != nil) {
count = [apps count];
for (i = 0; i < count; i++) {
elt = [apps objectAtIndex:i];
if (elt != nil &&
[elt isKindOfClass:[NSArray class]]) {
name = [elt objectAtIndex:0];
if (name != nil) {
nname = NSLocalizedString(name, nil);
if (nname != nil && nname != name)
[elt replaceObjectAtIndex:0 withObject:
nname];
}
}
}
}
}
}
if (defaults != NULL) value = CFDictionaryGetValue(defaults, key);
if (value != NULL) CFRetain(value);
}
return value;
}
- (int) prefs_get_integer:(NSString *)key default:(int)def
{
CFPropertyListRef value;
int ret;
value = [self prefs_get_copy:key];
if (value != NULL && CFGetTypeID(value) == CFNumberGetTypeID())
CFNumberGetValue(value, kCFNumberIntType, &ret);
else if (value != NULL && CFGetTypeID(value) == CFStringGetTypeID())
ret = CFStringGetIntValue(value);
else
ret = def;
if (value != NULL) CFRelease(value);
return ret;
}
- (const char *) prefs_get_string:(NSString *)key default:(const char *)def
{
CFPropertyListRef value;
const char *ret = NULL;
value = [self prefs_get_copy:key];
if (value != NULL && CFGetTypeID(value) == CFStringGetTypeID()) {
NSString *s = (NSString *)value;
ret = [s UTF8String];
}
if (value != NULL) CFRelease(value);
return ret != NULL ? ret : def;
}
- (NSURL *) prefs_copy_url:(NSString *)key default:(NSURL *)def
{
CFPropertyListRef value;
NSURL *ret = NULL;
value = [self prefs_get_copy:key];
if (value != NULL && CFGetTypeID(value) == CFStringGetTypeID()) {
NSString *s = (NSString *)value;
ret = [NSURL URLWithString:s];
[ret retain];
}
if (value != NULL) CFRelease(value);
return ret != NULL ? ret : def;
}
- (float) prefs_get_float:(NSString *)key default:(float)def
{
CFPropertyListRef value;
float ret = def;
value = [self prefs_get_copy:key];
if (value != NULL
&& CFGetTypeID(value) == CFNumberGetTypeID()
&& CFNumberIsFloatType(value))
CFNumberGetValue(value, kCFNumberFloatType, &ret);
else if (value != NULL && CFGetTypeID(value) == CFStringGetTypeID())
ret = CFStringGetDoubleValue(value);
if (value != NULL) CFRelease(value);
return ret;
}
- (int) prefs_get_boolean:(NSString *)key default:(int)def
{
CFPropertyListRef value;
int ret = def;
value = [self prefs_get_copy:key];
if (value != NULL) {
if (CFGetTypeID(value) == CFNumberGetTypeID())
CFNumberGetValue(value, kCFNumberIntType, &ret);
else if (CFGetTypeID(value) == CFBooleanGetTypeID())
ret = CFBooleanGetValue(value);
else if (CFGetTypeID(value) == CFStringGetTypeID()) {
const char *tem = [(NSString *) value UTF8String];
if (strcasecmp(tem, "true") == 0 || strcasecmp(tem, "yes") == 0)
ret = YES;
else
ret = NO;
}
CFRelease(value);
}
return ret;
}
- (NSArray *) prefs_get_array:(NSString *)key
{
NSArray *ret = nil;
CFPropertyListRef value;
value = [self prefs_get_copy:key];
if (value != NULL) {
if (CFGetTypeID(value) == CFArrayGetTypeID())
ret = [cfarray_to_nsarray (value)autorelease];
CFRelease(value);
}
return ret;
}
- (void) prefs_set_integer:(NSString *)key value:(int)value
{
CFNumberRef x;
x = CFNumberCreate(NULL, kCFNumberIntType, &value);
CFPreferencesSetValue((CFStringRef)key, (CFTypeRef)x,
app_prefs_domain_cfstr,
kCFPreferencesCurrentUser,
kCFPreferencesAnyHost);
CFRelease(x);
}
- (void) prefs_set_float:(NSString *)key value:(float)value
{
CFNumberRef x;
x = CFNumberCreate(NULL, kCFNumberFloatType, &value);
CFPreferencesSetValue((CFStringRef)key, (CFTypeRef)x,
app_prefs_domain_cfstr,
kCFPreferencesCurrentUser,
kCFPreferencesAnyHost);
CFRelease(x);
}
- (void) prefs_set_boolean:(NSString *)key value:(int)value
{
CFPreferencesSetValue(
(CFStringRef)key,
(CFTypeRef)(value ? kCFBooleanTrue
: kCFBooleanFalse),
app_prefs_domain_cfstr,
kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
}
- (void) prefs_set_array:(NSString *)key value:(NSArray *)value
{
CFArrayRef cfarray;
cfarray = nsarray_to_cfarray(value);
CFPreferencesSetValue((CFStringRef)key,
(CFTypeRef)cfarray,
app_prefs_domain_cfstr,
kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
CFRelease(cfarray);
}
- (void) prefs_set_string:(NSString *)key value:(NSString *)value
{
CFPreferencesSetValue((CFStringRef)key, (CFTypeRef)value,
app_prefs_domain_cfstr, kCFPreferencesCurrentUser,
kCFPreferencesAnyHost);
}
- (void) prefs_synchronize
{
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
}
- (void) read_defaults
{
NSString *nsstr;
const char *tem;
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
XQuartzRootlessDefault = [self prefs_get_boolean:@PREFS_ROOTLESS
default :XQuartzRootlessDefault];
XQuartzFullscreenMenu = [self prefs_get_boolean:@PREFS_FULLSCREEN_MENU
default :XQuartzFullscreenMenu];
XQuartzFullscreenDisableHotkeys =
![self prefs_get_boolean:@PREFS_FULLSCREEN_HOTKEYS
default :!
XQuartzFullscreenDisableHotkeys];
darwinFakeButtons = [self prefs_get_boolean:@PREFS_FAKEBUTTONS
default :darwinFakeButtons];
XQuartzOptionSendsAlt = [self prefs_get_boolean:@PREFS_OPTION_SENDS_ALT
default :XQuartzOptionSendsAlt];
XQuartzRootlessDefault = [defaults boolForKey:XQuartzPrefKeyRootless];
XQuartzFullscreenMenu = [defaults boolForKey:XQuartzPrefKeyFullscreenMenu];
XQuartzFullscreenDisableHotkeys = ![defaults boolForKey:XQuartzPrefKeyFullscreenHotkeys];
darwinFakeButtons = [defaults boolForKey:XQuartzPrefKeyFakeButtons];
XQuartzOptionSendsAlt = [defaults boolForKey:XQuartzPrefKeyOptionSendsAlt];
if (darwinFakeButtons) {
const char *fake2, *fake3;
NSString * const fake2 = [defaults stringForKey:XQuartzPrefKeyFakeButton2];
if (fake2) {
darwinFakeMouse2Mask = DarwinParseModifierList(fake2.UTF8String, TRUE);
}
fake2 = [self prefs_get_string:@PREFS_FAKE_BUTTON2 default:NULL];
fake3 = [self prefs_get_string:@PREFS_FAKE_BUTTON3 default:NULL];
if (fake2 != NULL) darwinFakeMouse2Mask = DarwinParseModifierList(
fake2, TRUE);
if (fake3 != NULL) darwinFakeMouse3Mask = DarwinParseModifierList(
fake3, TRUE);
}
tem = [self prefs_get_string:@PREFS_APPKIT_MODIFIERS default:NULL];
if (tem != NULL) darwinAppKitModMask = DarwinParseModifierList(tem, TRUE);
tem = [self prefs_get_string:@PREFS_WINDOW_ITEM_MODIFIERS default:NULL];
if (tem != NULL) {
windowItemModMask = DarwinParseModifierList(tem, FALSE);
}
else {
nsstr = NSLocalizedString(@"window item modifiers",
@"window item modifiers");
if (nsstr != NULL) {
tem = [nsstr UTF8String];
if ((tem != NULL) && strcmp(tem, "window item modifiers")) {
windowItemModMask = DarwinParseModifierList(tem, FALSE);
}
NSString * const fake3 = [defaults stringForKey:XQuartzPrefKeyFakeButton3];
if (fake3) {
darwinFakeMouse3Mask = DarwinParseModifierList(fake3.UTF8String, TRUE);
}
}
XQuartzEnableKeyEquivalents = [self prefs_get_boolean:@PREFS_KEYEQUIVS
default :
XQuartzEnableKeyEquivalents];
darwinSyncKeymap = [self prefs_get_boolean:@PREFS_SYNC_KEYMAP
default :darwinSyncKeymap];
darwinDesiredDepth = [self prefs_get_integer:@PREFS_DEPTH
default :darwinDesiredDepth];
noTestExtensions = ![self prefs_get_boolean:@PREFS_TEST_EXTENSIONS
default :FALSE];
noRenderExtension = ![self prefs_get_boolean:@PREFS_RENDER_EXTENSION
default :TRUE];
XQuartzScrollInDeviceDirection =
[self prefs_get_boolean:@PREFS_SCROLL_IN_DEV_DIRECTION
default :
XQuartzScrollInDeviceDirection];
#if XQUARTZ_SPARKLE
NSURL *url = [self prefs_copy_url:@PREFS_UPDATE_FEED default:nil];
if (url) {
[[SUUpdater sharedUpdater] setFeedURL:url];
[url release];
NSString * const appKitModifiers = [defaults stringForKey:XQuartzPrefKeyAppKitModifiers];
if (appKitModifiers) {
darwinAppKitModMask = DarwinParseModifierList(appKitModifiers.UTF8String, TRUE);
}
#endif
NSString * const windowItemModifiers = [defaults stringForKey:XQuartzPrefKeyWindowItemModifiers];
if (windowItemModifiers) {
windowItemModMask = DarwinParseModifierList(windowItemModifiers.UTF8String, FALSE);
}
XQuartzEnableKeyEquivalents = [defaults boolForKey:XQuartzPrefKeyKeyEquivs];
darwinSyncKeymap = [defaults boolForKey:XQuartzPrefKeySyncKeymap];
darwinDesiredDepth = [defaults integerForKey:XQuartzPrefKeyDepth];
noTestExtensions = ![defaults boolForKey:XQuartzPrefKeyTESTExtension];
noRenderExtension = ![defaults boolForKey:XQuartzPrefKeyRENDERExtension];
XQuartzScrollInDeviceDirection = [defaults boolForKey:XQuartzPrefKeyScrollInDeviceDirection];
}
/* This will end up at the end of the responder chain. */
@ -1018,8 +647,9 @@ Bool
X11ApplicationCanEnterRandR(void)
{
NSString *title, *msg;
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
if ([X11App prefs_get_boolean:@PREFS_NO_RANDR_ALERT default:NO] ||
if ([defaults boolForKey:XQuartzPrefKeyNoRANDRAlert] ||
XQuartzShieldingWindowLevel != 0)
return TRUE;
@ -1042,8 +672,7 @@ X11ApplicationCanEnterRandR(void)
switch (alert_result) {
case NSAlertOtherReturn:
[X11App prefs_set_boolean:@PREFS_NO_RANDR_ALERT value:YES];
[X11App prefs_synchronize];
[defaults setBool:YES forKey:XQuartzPrefKeyNoRANDRAlert];
case NSAlertDefaultReturn:
return YES;
@ -1058,8 +687,9 @@ check_xinitrc(void)
{
char *tem, buf[1024];
NSString *msg;
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
if ([X11App prefs_get_boolean:@PREFS_DONE_XINIT_CHECK default:NO])
if ([defaults boolForKey:XQuartzPrefKeyDoneXinitCheck])
return;
tem = getenv("HOME");
@ -1093,8 +723,7 @@ check_xinitrc(void)
}
done:
[X11App prefs_set_boolean:@PREFS_DONE_XINIT_CHECK value:YES];
[X11App prefs_synchronize];
[defaults setBool:YES forKey:XQuartzPrefKeyDoneXinitCheck];
}
static inline pthread_t
@ -1130,15 +759,8 @@ X11ApplicationMain(int argc, char **argv, char **envp)
@autoreleasepool {
X11App = (X11Application *)[X11Application sharedApplication];
[X11App read_defaults];
app_prefs_domain_cfstr = (CFStringRef)[[NSBundle mainBundle] bundleIdentifier];
if (app_prefs_domain_cfstr == NULL) {
ErrorF("X11ApplicationMain: Unable to determine bundle identifier. Your installation of XQuartz may be broken.\n");
app_prefs_domain_cfstr = CFSTR(BUNDLE_ID_PREFIX ".X11");
}
[NSApp read_defaults];
[NSBundle loadNibNamed:@"main" owner:NSApp];
[NSNotificationCenter.defaultCenter addObserver:NSApp
selector:@selector (became_key:)
@ -1701,8 +1323,17 @@ handle_mouse:
}
if (darwinSyncKeymap) {
TISInputSourceRef key_layout =
TISCopyCurrentKeyboardLayoutInputSource();
__block TISInputSourceRef key_layout;
dispatch_block_t copyCurrentKeyboardLayoutInputSource = ^{
key_layout = TISCopyCurrentKeyboardLayoutInputSource();
};
/* This is an ugly ant-pattern, but it is more expedient to address the problem right now. */
if (pthread_main_np()) {
copyCurrentKeyboardLayoutInputSource();
} else {
dispatch_sync(dispatch_get_main_queue(), copyCurrentKeyboardLayoutInputSource);
}
TISInputSourceRef clear;
if (CFEqual(key_layout, last_key_layout)) {
CFRelease(key_layout);

View File

@ -36,6 +36,7 @@
#import "X11Controller.h"
#import "X11Application.h"
#import "NSUserDefaults+XQuartzDefaults.h"
#include "opaque.h"
#include "darwin.h"
@ -61,8 +62,8 @@ extern char *bundle_id_prefix;
@property (nonatomic, readwrite, strong) NSMenuItem *check_for_updates_item; // Programatically enabled
#endif
@property (nonatomic, readwrite, strong) NSArray *apps;
@property (nonatomic, readwrite, strong) NSMutableArray *table_apps;
@property (nonatomic, readwrite, strong) NSArray <NSArray <NSString *> *> *apps;
@property (nonatomic, readwrite, strong) NSMutableArray <NSMutableArray <NSString *> *> *table_apps;
@property (nonatomic, readwrite, assign) NSInteger windows_menu_nitems;
@property (nonatomic, readwrite, assign) int checked_window_item;
@property (nonatomic, readwrite, assign) x_list *pending_apps;
@ -74,21 +75,19 @@ extern char *bundle_id_prefix;
- (void) awakeFromNib
{
X11Application *xapp = NSApp;
NSArray *array;
/* Point X11Application at ourself. */
xapp.controller = self;
array = [xapp prefs_get_array:@PREFS_APPSMENU];
if (array != nil) {
int count;
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
NSArray *appsMenu = [defaults arrayForKey:XQuartzPrefKeyAppsMenu];
if (appsMenu) {
int count = appsMenu.count;
/* convert from [TITLE1 COMMAND1 TITLE2 COMMAND2 ...]
to [[TITLE1 COMMAND1] [TITLE2 COMMAND2] ...] format. */
count = [array count];
if (count > 0
&& ![[array objectAtIndex:0] isKindOfClass:[NSArray class]]) {
if (count > 0 && ![appsMenu[0] isKindOfClass:NSArray.class]) {
int i;
NSMutableArray *copy, *sub;
@ -96,24 +95,24 @@ extern char *bundle_id_prefix;
for (i = 0; i < count / 2; i++) {
sub = [[NSMutableArray alloc] initWithCapacity:3];
[sub addObject:[array objectAtIndex:i * 2]];
[sub addObject:[array objectAtIndex:i * 2 + 1]];
[sub addObject:appsMenu[i * 2]];
[sub addObject:appsMenu[i * 2 + 1]];
[sub addObject:@""];
[copy addObject:sub];
[sub release];
}
array = copy;
appsMenu = copy;
[defaults setObject:appsMenu forKey:XQuartzPrefKeyAppsMenu];
}
[self set_apps_menu:array];
[self set_apps_menu:appsMenu];
}
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(apps_table_done:)
name: NSWindowWillCloseNotification
object: self.apps_table.window];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(apps_table_done:)
name:NSWindowWillCloseNotification
object:self.apps_table.window];
}
- (void) item_selected:sender
@ -156,10 +155,10 @@ extern char *bundle_id_prefix;
self.apps = nil;
}
- (void) prepend_apps_item:(NSArray *)list index:(int)i menu:(NSMenu *)menu
- (void) prepend_apps_item:(NSArray <NSArray <NSString *> *> *)list index:(int)i menu:(NSMenu *)menu
{
NSString *title, *shortcut = @"";
NSArray *group;
NSArray <NSString *> *group;
NSMenuItem *item;
group = [list objectAtIndex:i];
@ -183,7 +182,7 @@ extern char *bundle_id_prefix;
[item setTag:i + 1]; /* can't be zero, so add one */
}
- (void) install_apps_menu:(NSArray *)list
- (void) install_apps_menu:(NSArray <NSArray <NSString *> *> *)list
{
NSMenu *menu;
int i, count;
@ -207,7 +206,7 @@ extern char *bundle_id_prefix;
self.apps = list;
}
- (void) set_window_menu:(NSArray *)list
- (void) set_window_menu:(NSArray <NSArray <NSString *> *> *)list
{
NSMenu * const menu = X11App.windowsMenu;
NSMenu * const dock_menu = self.dock_menu;
@ -303,7 +302,7 @@ extern char *bundle_id_prefix;
self.checked_window_item = n;
}
- (void) set_apps_menu:(NSArray *)list
- (void) set_apps_menu:(NSArray <NSArray <NSString *> *> *)list
{
[self remove_apps_menu];
[self install_apps_menu:list];
@ -349,9 +348,12 @@ extern char *bundle_id_prefix;
int stdout_pipe[2];
int stderr_pipe[2];
newargv[0] = [X11App prefs_get_string:@PREFS_LOGIN_SHELL default:"/bin/sh"];
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
NSString * const shell = [defaults stringForKey:XQuartzPrefKeyLoginShell];
newargv[0] = shell.fileSystemRepresentation;
newargv[1] = "-c";
newargv[2] = [filename UTF8String];
newargv[2] = filename.fileSystemRepresentation;
newargv[3] = NULL;
s = getenv("DISPLAY");
@ -446,7 +448,7 @@ extern char *bundle_id_prefix;
{
int tag;
NSString *item;
NSArray * const apps = self.apps;
NSArray <NSArray <NSString *> *> * const apps = self.apps;
tag = [sender tag] - 1;
if (apps == nil || tag < 0 || tag >= [apps count])
@ -460,15 +462,18 @@ extern char *bundle_id_prefix;
- (IBAction) apps_table_show:sender
{
NSArray *columns;
NSMutableArray *oldapps = self.table_apps;
NSMutableArray <NSMutableArray <NSString *> *> * const oldapps = self.table_apps;
NSTableView * const apps_table = self.apps_table;
NSMutableArray * const table_apps = [[NSMutableArray alloc] initWithCapacity:1];
NSMutableArray <NSMutableArray <NSString *> *> * const table_apps = [[NSMutableArray alloc] initWithCapacity:1];
self.table_apps = table_apps;
NSArray * const apps = self.apps;
if (apps != nil)
[table_apps addObjectsFromArray:apps];
NSArray <NSArray <NSString *> *> * const apps = self.apps;
if (apps != nil) {
for (NSArray <NSString *> * row in apps) {
[table_apps addObject:row.mutableCopy];
}
}
columns = [apps_table tableColumns];
[[columns objectAtIndex:0] setIdentifier:@"0"];
@ -487,15 +492,15 @@ extern char *bundle_id_prefix;
- (IBAction) apps_table_done:sender
{
NSMutableArray * const table_apps = self.table_apps;
NSMutableArray <NSMutableArray <NSString *> *> * const table_apps = self.table_apps;
NSTableView * const apps_table = self.apps_table;
[apps_table deselectAll:sender]; /* flush edits? */
[self remove_apps_menu];
[self install_apps_menu:table_apps];
[NSApp prefs_set_array:@PREFS_APPSMENU value:table_apps];
[NSApp prefs_synchronize];
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
[defaults setObject:table_apps forKey:XQuartzPrefKeyAppsMenu];
[[apps_table window] orderOut:sender];
@ -505,7 +510,7 @@ extern char *bundle_id_prefix;
- (IBAction) apps_table_new:sender
{
NSMutableArray *item;
NSMutableArray * const table_apps = self.table_apps;
NSMutableArray <NSMutableArray <NSString *> *> * const table_apps = self.table_apps;
NSTableView * const apps_table = self.apps_table;
int row = [apps_table selectedRow], i;
@ -534,10 +539,10 @@ extern char *bundle_id_prefix;
- (IBAction) apps_table_duplicate:sender
{
NSMutableArray * const table_apps = self.table_apps;
NSMutableArray <NSMutableArray <NSString *> *> * const table_apps = self.table_apps;
NSTableView * const apps_table = self.apps_table;
int row = [apps_table selectedRow], i;
NSObject *item;
NSMutableArray <NSString *> *item;
if (row < 0) {
[self apps_table_new:sender];
@ -560,7 +565,7 @@ extern char *bundle_id_prefix;
- (IBAction) apps_table_delete:sender
{
NSMutableArray * const table_apps = self.table_apps;
NSMutableArray <NSMutableArray <NSString *> *> * const table_apps = self.table_apps;
NSTableView * const apps_table = self.apps_table;
int row = [apps_table selectedRow];
@ -584,7 +589,7 @@ extern char *bundle_id_prefix;
- (NSInteger) numberOfRowsInTableView:(NSTableView *)tableView
{
NSMutableArray * const table_apps = self.table_apps;
NSMutableArray <NSMutableArray <NSString *> *> * const table_apps = self.table_apps;
if (table_apps == nil) return 0;
return [table_apps count];
@ -593,7 +598,7 @@ extern char *bundle_id_prefix;
- (id) tableView:(NSTableView *)tableView
objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSMutableArray * const table_apps = self.table_apps;
NSMutableArray <NSMutableArray <NSString *> *> * const table_apps = self.table_apps;
NSArray *item;
int col;
@ -611,8 +616,8 @@ extern char *bundle_id_prefix;
- (void) tableView:(NSTableView *)tableView setObjectValue:(id)object
forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSMutableArray * const table_apps = self.table_apps;
NSMutableArray *item;
NSMutableArray <NSMutableArray <NSString *> *> * const table_apps = self.table_apps;
NSMutableArray <NSString *> *item;
int col;
if (table_apps == nil) return;
@ -672,15 +677,15 @@ extern char *bundle_id_prefix;
- (IBAction) enable_fullscreen_changed:sender
{
XQuartzRootlessDefault = !self.enable_fullscreen.intValue;
XQuartzRootlessDefault = !self.enable_fullscreen.state;
[self.enable_fullscreen_menu setEnabled:!XQuartzRootlessDefault];
[self.enable_fullscreen_menu_text setTextColor:XQuartzRootlessDefault ? NSColor.disabledControlTextColor : NSColor.controlTextColor];
DarwinSendDDXEvent(kXquartzSetRootless, 1, XQuartzRootlessDefault);
[NSApp prefs_set_boolean:@PREFS_ROOTLESS value:XQuartzRootlessDefault];
[NSApp prefs_synchronize];
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
[defaults setBool:XQuartzRootlessDefault forKey:XQuartzPrefKeyRootless];
}
- (IBAction) toggle_fullscreen:sender
@ -693,55 +698,43 @@ extern char *bundle_id_prefix;
if (!sender)
return;
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
if (sender == self.fake_buttons) {
darwinFakeButtons = self.fake_buttons.intValue;
[NSApp prefs_set_boolean:@PREFS_FAKEBUTTONS value:darwinFakeButtons];
}
else if (sender == self.enable_keyequivs) {
XQuartzEnableKeyEquivalents = self.enable_keyequivs.intValue;
[NSApp prefs_set_boolean:@PREFS_KEYEQUIVS value:
XQuartzEnableKeyEquivalents];
}
else if (sender == self.sync_keymap) {
darwinSyncKeymap = self.sync_keymap.intValue;
[NSApp prefs_set_boolean:@PREFS_SYNC_KEYMAP value:darwinSyncKeymap];
}
else if (sender == self.enable_fullscreen_menu) {
XQuartzFullscreenMenu = self.enable_fullscreen_menu.intValue;
[NSApp prefs_set_boolean:@PREFS_FULLSCREEN_MENU value:
XQuartzFullscreenMenu];
}
else if (sender == self.option_sends_alt) {
darwinFakeButtons = !!self.fake_buttons.state;
[defaults setBool:darwinFakeButtons forKey:XQuartzPrefKeyFakeButtons];
} else if (sender == self.enable_keyequivs) {
XQuartzEnableKeyEquivalents = !!self.enable_keyequivs.state;
[defaults setBool:XQuartzEnableKeyEquivalents forKey:XQuartzPrefKeyKeyEquivs];
} else if (sender == self.sync_keymap) {
darwinSyncKeymap = !!self.sync_keymap.state;
[defaults setBool:darwinSyncKeymap forKey:XQuartzPrefKeySyncKeymap];
} else if (sender == self.enable_fullscreen_menu) {
XQuartzFullscreenMenu = !!self.enable_fullscreen_menu.state;
[defaults setBool:XQuartzFullscreenMenu forKey:XQuartzPrefKeyFullscreenMenu];
} else if (sender == self.option_sends_alt) {
BOOL prev_opt_sends_alt = XQuartzOptionSendsAlt;
XQuartzOptionSendsAlt = self.option_sends_alt.intValue;
[NSApp prefs_set_boolean:@PREFS_OPTION_SENDS_ALT value:
XQuartzOptionSendsAlt];
XQuartzOptionSendsAlt = !!self.option_sends_alt.state;
[defaults setBool:XQuartzOptionSendsAlt forKey:XQuartzPrefKeyOptionSendsAlt];
if (prev_opt_sends_alt != XQuartzOptionSendsAlt)
QuartsResyncKeymap(TRUE);
}
else if (sender == self.click_through) {
[NSApp prefs_set_boolean:@PREFS_CLICK_THROUGH value:self.click_through.intValue];
}
else if (sender == self.focus_follows_mouse) {
[NSApp prefs_set_boolean:@PREFS_FFM value:self.focus_follows_mouse.intValue];
}
else if (sender == self.focus_on_new_window) {
[NSApp prefs_set_boolean:@PREFS_FOCUS_ON_NEW_WINDOW value:self.focus_on_new_window.intValue];
}
else if (sender == self.enable_auth) {
[NSApp prefs_set_boolean:@PREFS_NO_AUTH value:!self.enable_auth.intValue];
}
else if (sender == self.enable_tcp) {
[NSApp prefs_set_boolean:@PREFS_NO_TCP value:!self.enable_tcp.intValue];
}
else if (sender == self.depth) {
[NSApp prefs_set_integer:@PREFS_DEPTH value:self.depth.selectedTag];
}
else if (sender == self.sync_pasteboard) {
} else if (sender == self.click_through) {
[defaults setBool:!!self.click_through.state forKey:XQuartzPrefKeyClickThrough];
} else if (sender == self.focus_follows_mouse) {
[defaults setBool:!!self.focus_follows_mouse.state forKey:XQuartzPrefKeyFocusFollowsMouse];
} else if (sender == self.focus_on_new_window) {
[defaults setBool:!!self.focus_on_new_window.state forKey:XQuartzPrefKeyFocusOnNewWindow];
} else if (sender == self.enable_auth) {
[defaults setBool:!self.enable_auth.state forKey:XQuartzPrefKeyNoAuth];
} else if (sender == self.enable_tcp) {
[defaults setBool:!self.enable_tcp.state forKey:XQuartzPrefKeyNoTCP];
} else if (sender == self.depth) {
[defaults setInteger:self.depth.selectedTag forKey:XQuartzPrefKeyDepth];
} else if (sender == self.sync_pasteboard) {
BOOL pbproxy_active = self.sync_pasteboard.intValue;
[NSApp prefs_set_boolean:@PREFS_SYNC_PB value:pbproxy_active];
[defaults setBool:pbproxy_active forKey:XQuartzPrefKeySyncPasteboard];
[self.sync_pasteboard_to_clipboard setEnabled:pbproxy_active];
[self.sync_pasteboard_to_primary setEnabled:pbproxy_active];
@ -751,33 +744,27 @@ extern char *bundle_id_prefix;
// setEnabled doesn't do this...
[self.sync_text1 setTextColor:pbproxy_active ? NSColor.controlTextColor : NSColor.disabledControlTextColor];
[self.sync_text2 setTextColor:pbproxy_active ? NSColor.controlTextColor : NSColor.disabledControlTextColor];
} else if (sender == self.sync_pasteboard_to_clipboard) {
[defaults setBool:!!self.sync_pasteboard_to_clipboard.state forKey:XQuartzPrefKeySyncPasteboardToClipboard];
} else if (sender == self.sync_pasteboard_to_primary) {
[defaults setBool:!!self.sync_pasteboard_to_primary.state forKey:XQuartzPrefKeySyncPasteboardToPrimary];
} else if (sender == self.sync_clipboard_to_pasteboard) {
[defaults setBool:!!self.sync_clipboard_to_pasteboard.state forKey:XQuartzPrefKeySyncClipboardToPasteBoard];
} else if (sender == self.sync_primary_immediately) {
[defaults setBool:!!self.sync_primary_immediately.state forKey:XQuartzPrefKeySyncPrimaryOnSelect];
} else if (sender == self.scroll_in_device_direction) {
XQuartzScrollInDeviceDirection = !!self.scroll_in_device_direction.state;
[defaults setBool:XQuartzScrollInDeviceDirection forKey:XQuartzPrefKeyScrollInDeviceDirection];
}
else if (sender == self.sync_pasteboard_to_clipboard) {
[NSApp prefs_set_boolean:@PREFS_SYNC_PB_TO_CLIPBOARD value:self.sync_pasteboard_to_clipboard.intValue];
}
else if (sender == self.sync_pasteboard_to_primary) {
[NSApp prefs_set_boolean:@PREFS_SYNC_PB_TO_PRIMARY value:self.sync_pasteboard_to_primary.intValue];
}
else if (sender == self.sync_clipboard_to_pasteboard) {
[NSApp prefs_set_boolean:@PREFS_SYNC_CLIPBOARD_TO_PB value:self.sync_clipboard_to_pasteboard.intValue];
}
else if (sender == self.sync_primary_immediately) {
[NSApp prefs_set_boolean:@PREFS_SYNC_PRIMARY_ON_SELECT value:self.sync_primary_immediately.intValue];
}
else if (sender == self.scroll_in_device_direction) {
XQuartzScrollInDeviceDirection = self.scroll_in_device_direction.intValue;
[NSApp prefs_set_boolean:@PREFS_SCROLL_IN_DEV_DIRECTION value:XQuartzScrollInDeviceDirection];
}
[NSApp prefs_synchronize];
DarwinSendDDXEvent(kXquartzReloadPreferences, 0);
}
- (IBAction) prefs_show:sender
{
BOOL pbproxy_active =
[NSApp prefs_get_boolean:@PREFS_SYNC_PB default:YES];
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
BOOL pbproxy_active = [defaults boolForKey:XQuartzPrefKeySyncPasteboard];
[self.scroll_in_device_direction setIntValue:XQuartzScrollInDeviceDirection];
@ -785,20 +772,20 @@ extern char *bundle_id_prefix;
[self.enable_keyequivs setIntValue:XQuartzEnableKeyEquivalents];
[self.sync_keymap setIntValue:darwinSyncKeymap];
[self.option_sends_alt setIntValue:XQuartzOptionSendsAlt];
[self.click_through setIntValue:[NSApp prefs_get_boolean:@PREFS_CLICK_THROUGH default:NO]];
[self.focus_follows_mouse setIntValue:[NSApp prefs_get_boolean:@PREFS_FFM default:NO]];
[self.focus_on_new_window setIntValue:[NSApp prefs_get_boolean:@PREFS_FOCUS_ON_NEW_WINDOW default:YES]];
[self.click_through setIntValue:[defaults boolForKey:XQuartzPrefKeyClickThrough]];
[self.focus_follows_mouse setIntValue:[defaults boolForKey:XQuartzPrefKeyFocusFollowsMouse]];
[self.focus_on_new_window setIntValue:[defaults boolForKey:XQuartzPrefKeyFocusOnNewWindow]];
[self.enable_auth setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_AUTH default:NO]];
[self.enable_tcp setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_TCP default:NO]];
[self.enable_auth setIntValue:![defaults boolForKey:XQuartzPrefKeyNoAuth]];
[self.enable_tcp setIntValue:![defaults boolForKey:XQuartzPrefKeyNoTCP]];
[self.depth selectItemAtIndex:[self.depth indexOfItemWithTag:[NSApp prefs_get_integer:@PREFS_DEPTH default:-1]]];
[self.depth selectItemAtIndex:[self.depth indexOfItemWithTag:[defaults integerForKey:XQuartzPrefKeyDepth]]];
[self.sync_pasteboard setIntValue:pbproxy_active];
[self.sync_pasteboard_to_clipboard setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_PB_TO_CLIPBOARD default:YES]];
[self.sync_pasteboard_to_primary setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_PB_TO_PRIMARY default:YES]];
[self.sync_clipboard_to_pasteboard setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_CLIPBOARD_TO_PB default:YES]];
[self.sync_primary_immediately setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_PRIMARY_ON_SELECT default:NO]];
[self.sync_pasteboard_to_clipboard setIntValue:[defaults boolForKey:XQuartzPrefKeySyncPasteboardToClipboard]];
[self.sync_pasteboard_to_primary setIntValue:[defaults boolForKey:XQuartzPrefKeySyncPasteboardToPrimary]];
[self.sync_clipboard_to_pasteboard setIntValue:[defaults boolForKey:XQuartzPrefKeySyncClipboardToPasteBoard]];
[self.sync_primary_immediately setIntValue:[defaults boolForKey:XQuartzPrefKeySyncPrimaryOnSelect]];
[self.sync_pasteboard_to_clipboard setEnabled:pbproxy_active];
[self.sync_pasteboard_to_primary setEnabled:pbproxy_active];
@ -863,9 +850,11 @@ extern char *bundle_id_prefix;
NSString *msg;
NSString *title;
if (self.can_quit ||
[X11App prefs_get_boolean:@PREFS_NO_QUIT_ALERT default:NO])
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
if (self.can_quit || [defaults boolForKey:XQuartzPrefKeyNoQuitAlert]) {
return NSTerminateNow;
}
/* Make sure we're frontmost. */
[NSApp activateIgnoringOtherApps:YES];
@ -887,8 +876,6 @@ extern char *bundle_id_prefix;
- (void) applicationWillTerminate:(NSNotification *)aNotification _X_NORETURN
{
[X11App prefs_synchronize];
/* shutdown the X server, it will exit () for us. */
DarwinSendDDXEvent(kXquartzQuit, 0);

View File

@ -28,20 +28,45 @@
<true/>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
<!-- Add generic usage descriptions for TCC
https://github.com/XQuartz/XQuartz/issues/245
-->
<key>NSAppleEventsUsageDescription</key>
<string>A process launched by APPLE_APPLICATION_NAME wants to use AppleScript.</string>
<key>NSCalendarsUsageDescription</key>
<string>A process launched by APPLE_APPLICATION_NAME wants access to your calendar data.</string>
<key>NSCameraUsageDescription</key>
<string>A process launched by APPLE_APPLICATION_NAME wants access to your camera.</string>
<key>NSContactsUsageDescription</key>
<string>A process launched by APPLE_APPLICATION_NAME wants access to your contacts.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>A process launched by APPLE_APPLICATION_NAME wants access to your location information, even when not in use.</string>
<key>NSLocationUsageDescription</key>
<string>A process launched by APPLE_APPLICATION_NAME wants access to your location information.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>A process launched by APPLE_APPLICATION_NAME wants access to your location information when in use.</string>
<key>NSMicrophoneUsageDescription</key>
<string>A process launched by APPLE_APPLICATION_NAME wants access to your microphone.</string>
<key>NSRemindersUsageDescription</key>
<string>A process launched by APPLE_APPLICATION_NAME wants access to your reminders.</string>
<key>NSSystemAdministrationUsageDescription</key>
<string>A process launched by APPLE_APPLICATION_NAME wants admin privileges.</string>
#ifdef XQUARTZ_SPARKLE
<key>SUEnableAutomaticChecks</key>
<true/>
<key>SUPublicDSAKeyFile</key>
<string>sparkle.pem</string>
<key>SUPublicEDKey</key>
<string>XQUARTZ_SPARKLE_PUBLIC_EDKEY</string>
<key>SUFeedURL</key>
<string>XQUARTZ_SPARKLE_FEED_URL</string>
#endif
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>NSHumanReadableCopyright</key>
<string>© 2003-2021 Apple Inc.
<string>© 2003-2023 Apple Inc.
© 2003 XFree86 Project, Inc.
© 2003-2021 X.org Foundation, Inc.
© 2003-2023 X.org Foundation, Inc.
</string>
<key>NSMainNibFile</key>
<string>main</string>

View File

@ -23,10 +23,8 @@ noinst_DATA = $(noinst_PRE:plist.cpp=plist)
CLEANFILES = $(noinst_DATA)
resourcedir=$(libdir)/X11/xserver
resource_DATA = Xquartz.plist
EXTRA_DIST = \
chown-bundle.sh \
mk_bundke.sh \
X11.sh \
Info.plist.cpp \
@ -181,5 +179,5 @@ EXTRA_DIST = \
Resources/zh_TW.lproj/Localizable.strings \
Resources/zh_TW.lproj/locversion.plist \
Resources/zh_TW.lproj/main.nib/designable.nib \
Resources/zh_TW.lproj/main.nib/keyedobjects.nib
Resources/zh_TW.lproj/main.nib/keyedobjects.nib \
Resources/zh_TW.lproj/main.nib/keyedobjects-110000.nib

View File

@ -10,10 +10,7 @@ cpp_defs = [
]
if build_sparkle
cpp_defs += [
'-DXQUARTZ_SPARKLE',
'-DXQUARTZ_SPARKLE_FEED_URL=@0@'.format(xquartz_sparkle_feed_url),
]
cpp_defs += sparkle_defs
endif
# bundle data
@ -56,7 +53,6 @@ install_data('PkgInfo',
install_mode: 'rw-r--r--')
install_data('X11.sh',
rename: 'X11',
install_dir: join_paths(bundle_root, 'Contents/MacOS'),
install_mode: 'rwxr-xr-x')

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!-- This file contains system-wide defaults for the Apple X11 server -->
<!-- This file contains system-wide defaults for XQuartz -->
<plist version="1.0">
<dict>
@ -12,16 +12,6 @@
<string>xterm</string>
<string>n</string>
</array>
<array>
<string>xman</string>
<string>xman</string>
<string></string>
</array>
<array>
<string>xlogo</string>
<string>xlogo</string>
<string></string>
</array>
</array>
</dict>
</plist>

View File

@ -72,6 +72,10 @@ FatalError(const char *f, ...) _X_ATTRIBUTE_PRINTF(1, 2) _X_NORETURN;
extern int noPanoramiXExtension;
#ifdef COMPOSITE
extern Bool noCompositeExtension;
#endif
#define DEFAULT_CLIENT X11BINDIR "/xterm"
#define DEFAULT_STARTX X11BINDIR "/startx -- " X11BINDIR "/Xquartz"
#define DEFAULT_SHELL "/bin/sh"
@ -626,12 +630,20 @@ main(int argc, char **argv, char **envp)
mach_port_t mp;
kern_return_t kr;
/* Ignore SIGPIPE */
signal(SIGPIPE, SIG_IGN);
/* Setup our environment for our children */
setup_env();
/* The server must not run the PanoramiX operations. */
noPanoramiXExtension = TRUE;
#ifdef COMPOSITE
/* https://gitlab.freedesktop.org/xorg/xserver/-/issues/1409 */
noCompositeExtension = TRUE;
#endif
/* Setup the initial crasherporter info */
strlcpy(__crashreporter_info_buff__, __crashreporter_info__base,
sizeof(__crashreporter_info_buff__));

View File

@ -70,6 +70,17 @@ x11_bin = executable('X11.bin',
install_dir: x11appdir,
)
# X11 (Bundle trampoline)
x11 = executable('X11',
[
'bundle_trampoline.c',
],
c_args: xquartz_defs,
link_args: ['-Objc'],
install: true,
install_dir: x11appdir,
)
# Xquartz
xquartz_deps = [
dependency('CoreServices', method: 'extraframework'),

View File

@ -52,39 +52,25 @@
#include "launchd_fd.h"
static char x11_path[PATH_MAX + 1];
static CFURLRef x11appURL;
static FSRef x11_appRef;
static pid_t x11app_pid = 0;
aslclient aslc;
static void
set_x11_path(void)
{
CFURLRef appURL = NULL;
OSStatus osstatus =
LSFindApplicationForInfo(kLSUnknownCreator, CFSTR(
kX11AppBundleId), nil, nil, &appURL);
OSStatus osstatus = LSFindApplicationForInfo(kLSUnknownCreator, CFSTR(kX11AppBundleId),
nil, &x11_appRef, &x11appURL);
switch (osstatus) {
case noErr:
if (appURL == NULL) {
asl_log(
aslc, NULL, ASL_LEVEL_ERR,
"Xquartz: Invalid response from LSFindApplicationForInfo(%s)",
kX11AppBundleId);
if (x11appURL == NULL) {
asl_log(aslc, NULL, ASL_LEVEL_ERR,
"Xquartz: Invalid response from LSFindApplicationForInfo(%s)",
kX11AppBundleId);
exit(1);
}
if (!CFURLGetFileSystemRepresentation(appURL, true,
(unsigned char *)x11_path,
sizeof(x11_path))) {
asl_log(aslc, NULL, ASL_LEVEL_ERR,
"Xquartz: Error resolving URL for %s",
kX11AppBundleId);
exit(3);
}
strlcat(x11_path, kX11AppBundlePath, sizeof(x11_path));
asl_log(aslc, NULL, ASL_LEVEL_INFO, "Xquartz: X11.app = %s", x11_path);
break;
case kLSApplicationNotFoundErr:
@ -96,8 +82,7 @@ set_x11_path(void)
default:
asl_log(aslc, NULL, ASL_LEVEL_ERR,
"Xquartz: Unable to find application for %s, error code = %d",
kX11AppBundleId,
(int)osstatus);
kX11AppBundleId, (int)osstatus);
exit(11);
}
}
@ -122,18 +107,15 @@ connect_to_socket(const char *filename)
ret_fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (ret_fd == -1) {
asl_log(aslc, NULL, ASL_LEVEL_ERR,
"Xquartz: Failed to create socket: %s - %s", filename,
strerror(
errno));
"Xquartz: Failed to create socket: %s - %d - %s",
filename, errno, strerror(errno));
return -1;
}
if (connect(ret_fd, servaddr, servaddr_len) < 0) {
asl_log(aslc, NULL, ASL_LEVEL_ERR,
"Xquartz: Failed to connect to socket: %s - %d - %s",
filename, errno,
strerror(
errno));
filename, errno, strerror(errno));
close(ret_fd);
return -1;
}
@ -176,10 +158,9 @@ send_fd_handoff(int connected_fd, int launchd_fd)
*((int *)CMSG_DATA(cmsg)) = launchd_fd;
if (sendmsg(connected_fd, &msg, 0) < 0) {
asl_log(
aslc, NULL, ASL_LEVEL_ERR,
"Xquartz: Error sending $DISPLAY file descriptor over fd %d: %d -- %s",
connected_fd, errno, strerror(errno));
asl_log(aslc, NULL, ASL_LEVEL_ERR,
"Xquartz: Error sending $DISPLAY file descriptor over fd %d: %d -- %s",
connected_fd, errno, strerror(errno));
return;
}
@ -253,24 +234,23 @@ main(int argc, char **argv, char **envp)
server_bootstrap_name);
set_x11_path();
/* This forking is ugly and will be cleaned up later */
child = fork();
if (child == -1) {
asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: Could not fork: %s",
strerror(
errno));
return EXIT_FAILURE;
}
char *listenOnlyArg = "--listenonly";
CFStringRef silentLaunchArg = CFStringCreateWithCString(NULL, listenOnlyArg, kCFStringEncodingUTF8);
CFStringRef args[] = { silentLaunchArg };
CFArrayRef passArgv = CFArrayCreate(NULL, (const void**) args, 1, NULL);
LSApplicationParameters params = { 0, /* CFIndex version == 0 */
kLSLaunchDefaults, /* LSLaunchFlags flags */
&x11_appRef, /* FSRef application */
NULL, /* void* asyncLaunchRefCon*/
NULL, /* CFDictionaryRef environment */
passArgv, /* CFArrayRef arguments */
NULL /* AppleEvent* initialEvent */
};
if (child == 0) {
char *_argv[3];
_argv[0] = x11_path;
_argv[1] = "--listenonly";
_argv[2] = NULL;
asl_log(aslc, NULL, ASL_LEVEL_NOTICE,
"Xquartz: Starting X server: %s --listenonly",
x11_path);
return execvp(x11_path, _argv);
OSStatus status = LSOpenApplication(&params, NULL);
if (status != noErr) {
asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: Unable to launch: %d", (int)status);
return EXIT_FAILURE;
}
/* Try connecting for 10 seconds */
@ -283,8 +263,7 @@ main(int argc, char **argv, char **envp)
if (kr != KERN_SUCCESS) {
asl_log(aslc, NULL, ASL_LEVEL_ERR,
"Xquartz: bootstrap_look_up(): %s", bootstrap_strerror(
kr));
"Xquartz: bootstrap_look_up(): %s", bootstrap_strerror(kr));
return EXIT_FAILURE;
}
}
@ -298,13 +277,10 @@ main(int argc, char **argv, char **envp)
int handoff_fd = -1;
for (try = 0, try_max = 5; try < try_max; try++) {
if (request_fd_handoff_socket(mp,
handoff_socket_filename) !=
KERN_SUCCESS) {
asl_log(
aslc, NULL, ASL_LEVEL_INFO,
"Xquartz: Failed to request a socket from the server to send the $DISPLAY fd over (try %d of %d)",
(int)try + 1, (int)try_max);
if (request_fd_handoff_socket(mp, handoff_socket_filename) != KERN_SUCCESS) {
asl_log(aslc, NULL, ASL_LEVEL_INFO,
"Xquartz: Failed to request a socket from the server to send the $DISPLAY fd over (try %d of %d)",
(int)try + 1, (int)try_max);
continue;
}
@ -312,16 +288,13 @@ main(int argc, char **argv, char **envp)
if (handoff_fd == -1) {
asl_log(aslc, NULL, ASL_LEVEL_ERR,
"Xquartz: Failed to connect to socket (try %d of %d)",
(int)try + 1,
(int)try_max);
(int)try + 1, (int)try_max);
continue;
}
asl_log(
aslc, NULL, ASL_LEVEL_INFO,
"Xquartz: Handoff connection established (try %d of %d) on fd %d, \"%s\". Sending message.",
(int)try + 1, (int)try_max, handoff_fd,
handoff_socket_filename);
asl_log(aslc, NULL, ASL_LEVEL_INFO,
"Xquartz: Handoff connection established (try %d of %d) on fd %d, \"%s\". Sending message.",
(int)try + 1, (int)try_max, handoff_fd, handoff_socket_filename);
send_fd_handoff(handoff_fd, launchd_fd);
close(handoff_fd);
break;
@ -342,8 +315,7 @@ main(int argc, char **argv, char **envp)
free(newargv);
free(newenvp);
asl_log(aslc, NULL, ASL_LEVEL_ERR,
"Xquartz: Memory allocation failure");
asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: Memory allocation failure");
return EXIT_FAILURE;
}
@ -361,8 +333,7 @@ main(int argc, char **argv, char **envp)
if (kr != KERN_SUCCESS) {
asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: start_x11_server: %s",
mach_error_string(
kr));
mach_error_string(kr));
return EXIT_FAILURE;
}
return EXIT_SUCCESS;

View File

@ -4,22 +4,44 @@ apple_applications_dir = get_option('apple-applications-dir')
apple_application_name = get_option('apple-application-name')
bundle_id_prefix = get_option('bundle-id-prefix')
xquartz_sparkle_feed_url = get_option('sparkle-feed-url')
xquartz_sparkle_public_edkey = get_option('sparkle-public-edkey')
bundle_version_string = meson.project_version() # CFBundleShortVersionString
bundle_version = release # CFBundleVersion
bundle_version_string = get_option('bundle-version-string') # CFBundleShortVersionString
if bundle_version_string == 'auto'
bundle_version_string = meson.project_version()
endif
bundle_version = get_option('bundle-version') # CFBundleVersion
if bundle_version == 'auto'
version_arr = bundle_version_string.split('.')
version_major = version_arr[0].to_int()
version_minor = version_arr[1].to_int()
version_tiny = version_arr[2].to_int()
bundle_version = '@0@.@1@.@2@'.format(version_major, version_minor, version_tiny)
endif
bundle_id_def = '-DBUNDLE_ID_PREFIX="@0@"'.format(bundle_id_prefix)
bundle_root = join_paths(apple_applications_dir, apple_application_name + '.app')
xquartz_data_dir = join_paths(get_option('prefix'), get_option('datadir'),'X11', 'XQuartz')
# using sparkle update framework?
build_sparkle = xquartz_sparkle_feed_url != ''
build_sparkle = xquartz_sparkle_feed_url != '' and xquartz_sparkle_public_edkey != ''
if build_sparkle
sparkle = dependency('Sparkle', method: 'extraframework')
sparkle_defs = [
'-DXQUARTZ_SPARKLE',
'-DXQUARTZ_SPARKLE_FEED_URL=@0@'.format(xquartz_sparkle_feed_url),
'-DXQUARTZ_SPARKLE_PUBLIC_EDKEY=@0@'.format(xquartz_sparkle_public_edkey),
]
else
sparkle_defs = []
endif
# libxquartz
srcs_libxquartz = [
'NSUserDefaults+XQuartzDefaults.m',
'X11Application.m',
'X11Controller.m',
'applewm.c',
@ -37,12 +59,12 @@ srcs_libxquartz = [
libxquartz_defs = [
'-DUSE_NEW_CLUT',
'-DX11LIBDIR="@0@"'.format(join_paths(get_option('prefix'),
get_option('libdir'))),
'-DXFree86Server',
'-DXQUARTZ',
'-DXQUARTZ_DATA_DIR="@0@"'.format(xquartz_data_dir),
'-DXSERVER_VERSION="@0@"'.format(meson.project_version()),
bundle_id_def,
sparkle_defs,
]
if cc.has_function('dispatch_async')
@ -73,3 +95,7 @@ xquartz_man = configure_file(
configuration: manpage_config,
)
install_man(xquartz_man)
install_data('defaults.plist',
install_dir: xquartz_data_dir,
install_mode: 'rw-r--r--')

View File

@ -1,4 +1,4 @@
AM_CPPFLAGS=-DBUNDLE_ID_PREFIX=\"$(BUNDLE_ID_PREFIX)\"
AM_CPPFLAGS=-I.. -DXQUARTZ_DATA_DIR=\"$(datadir)/X11/XQuartz\"
AM_CFLAGS=$(XPBPROXY_CFLAGS)
AM_OBJCFLAGS=$(XPBPROXY_CFLAGS)
@ -15,7 +15,7 @@ libxpbproxy_la_LDFLAGS=$(XPBPROXY_LIBS)
if STANDALONE_XPBPROXY
bin_PROGRAMS = xpbproxy
xpbproxy_SOURCES = app-main.m
xpbproxy_SOURCES = app-main.m ../NSUserDefaults+XQuartzDefaults.m
xpbproxy_LDADD = libxpbproxy.la
xpbproxy_LDFLAGS = -Wl,-framework,Cocoa

View File

@ -31,13 +31,6 @@
#include "pbproxy.h"
#import "x-selection.h"
#include <pthread.h>
#include <unistd.h> /*for getpid*/
#include <Cocoa/Cocoa.h>
static const char *app_prefs_domain = BUNDLE_ID_PREFIX ".xpbproxy";
CFStringRef app_prefs_domain_cfstr;
/* Stubs */
char *display = NULL;
@ -82,41 +75,8 @@ xq_asl_log(int level, const char *subsystem, const char *file,
int
main(int argc, const char *argv[])
{
const char *s;
int i;
#ifdef DEBUG
ErrorF("pid: %u\n", getpid());
#endif
xpbproxy_is_standalone = YES;
if ((s = getenv("X11_PREFS_DOMAIN")))
app_prefs_domain = s;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "--prefs-domain") == 0 && i + 1 < argc) {
app_prefs_domain = argv[++i];
}
else if (strcmp(argv[i], "--help") == 0) {
ErrorF(
"usage: xpbproxy OPTIONS\n"
"Pasteboard proxying for X11.\n\n"
"--prefs-domain <domain> Change the domain used for reading preferences\n"
" (default: %s)\n",
app_prefs_domain);
return 0;
}
else {
ErrorF("usage: xpbproxy OPTIONS...\n"
"Try 'xpbproxy --help' for more information.\n");
return 1;
}
}
app_prefs_domain_cfstr = CFStringCreateWithCString(NULL, app_prefs_domain,
kCFStringEncodingUTF8);
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
signal(SIGHUP, signal_handler);

View File

@ -1,6 +1,9 @@
build_standalone_pbproxy = get_option('xpbproxy')
pbproxy_defs = [bundle_id_def]
pbproxy_defs = [
'-DXQUARTZ_DATA_DIR="@0@"'.format(xquartz_data_dir),
bundle_id_def
]
if build_standalone_pbproxy
pbproxy_defs += ['-DSTANDALONE_XPBPROXY']
endif
@ -8,9 +11,11 @@ endif
libapplewm_dep = dependency('applewm', version: '>=1.4')
libxpbproxy = static_library('xpbproxy',
['main.m',
['../NSUserDefaults+XQuartzDefaults.m',
'main.m',
'x-input.m',
'x-selection.m'],
include_directories: ['..'],
dependencies: [applewmproto_dep, libapplewm_dep, dependency('xfixes'), dependency('x11')],
objc_args: pbproxy_defs,
)

View File

@ -38,6 +38,8 @@
#import <AppKit/NSImage.h>
#import <AppKit/NSBitmapImageRep.h>
#import "NSUserDefaults+XQuartzDefaults.h"
/*
* The basic design of the pbproxy code is as follows.
*
@ -99,18 +101,6 @@ dump_prefs()
}
#endif
extern CFStringRef app_prefs_domain_cfstr;
static BOOL
prefs_get_bool(CFStringRef key, BOOL defaultValue)
{
Boolean value, ok;
value = CFPreferencesGetAppBooleanValue(key, app_prefs_domain_cfstr, &ok);
return ok ? (BOOL)value : defaultValue;
}
static void
init_propdata(struct propdata *pdata)
{
@ -1394,35 +1384,18 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete,
- (void) reload_preferences
{
/*
* It's uncertain how we could handle the synchronization failing, so cast to void.
* The prefs_get_bool should fall back to defaults if the org.x.X11 plist doesn't exist or is invalid.
*/
(void)CFPreferencesAppSynchronize(app_prefs_domain_cfstr);
NSUserDefaults * const defaults = NSUserDefaults.xquartzDefaults;
#ifdef STANDALONE_XPBPROXY
if (xpbproxy_is_standalone)
pbproxy_prefs.active = YES;
else
#endif
pbproxy_prefs.active = prefs_get_bool(CFSTR(
"sync_pasteboard"),
pbproxy_prefs.active);
pbproxy_prefs.primary_on_grab =
prefs_get_bool(CFSTR(
"sync_primary_on_select"),
pbproxy_prefs.primary_on_grab);
pbproxy_prefs.clipboard_to_pasteboard =
prefs_get_bool(CFSTR(
"sync_clipboard_to_pasteboard"),
pbproxy_prefs.clipboard_to_pasteboard);
pbproxy_prefs.pasteboard_to_primary =
prefs_get_bool(CFSTR(
"sync_pasteboard_to_primary"),
pbproxy_prefs.pasteboard_to_primary);
pbproxy_prefs.pasteboard_to_clipboard =
prefs_get_bool(CFSTR(
"sync_pasteboard_to_clipboard"),
pbproxy_prefs.pasteboard_to_clipboard);
pbproxy_prefs.active = [defaults boolForKey:XQuartzPrefKeySyncPasteboard];
pbproxy_prefs.primary_on_grab = [defaults boolForKey:XQuartzPrefKeySyncPrimaryOnSelect];
pbproxy_prefs.clipboard_to_pasteboard = [defaults boolForKey:XQuartzPrefKeySyncClipboardToPasteBoard];
pbproxy_prefs.pasteboard_to_primary = [defaults boolForKey:XQuartzPrefKeySyncPasteboardToPrimary];
pbproxy_prefs.pasteboard_to_clipboard = [defaults boolForKey:XQuartzPrefKeySyncPasteboardToClipboard];
/* This is used for debugging. */
//dump_prefs();

View File

@ -85,14 +85,16 @@ int aquaMenuBarHeight = 0;
QuartzModeProcsPtr quartzProcs = NULL;
const char *quartzOpenGLBundle = NULL;
Bool XQuartzFullscreenDisableHotkeys = TRUE;
Bool XQuartzOptionSendsAlt = FALSE;
Bool XQuartzEnableKeyEquivalents = TRUE;
/* These are initialized by X11Application with default values set in NSUserDefaults+XQuartzDefaults */
Bool XQuartzFullscreenDisableHotkeys;
Bool XQuartzOptionSendsAlt;
Bool XQuartzEnableKeyEquivalents;
Bool XQuartzFullscreenMenu;
Bool XQuartzRootlessDefault;
Bool XQuartzFullscreenVisible = FALSE;
Bool XQuartzRootlessDefault = TRUE;
Bool XQuartzIsRootless = TRUE;
Bool XQuartzServerVisible = FALSE;
Bool XQuartzFullscreenMenu = FALSE;
int32_t XQuartzShieldingWindowLevel = 0;

View File

@ -272,6 +272,7 @@ ProcAppleDRICreatePixmap(ClientPtr client)
xAppleDRICreatePixmapReply rep;
int width, height, pitch, bpp;
void *ptr;
CARD32 stringLength;
REQUEST_SIZE_MATCH(xAppleDRICreatePixmapReq);
@ -307,6 +308,7 @@ ProcAppleDRICreatePixmap(ClientPtr client)
if (sizeof(rep) != sz_xAppleDRICreatePixmapReply)
ErrorF("error sizeof(rep) is %zu\n", sizeof(rep));
stringLength = rep.stringLength; /* save unswapped value */
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
@ -319,7 +321,7 @@ ProcAppleDRICreatePixmap(ClientPtr client)
}
WriteToClient(client, sizeof(rep), &rep);
WriteToClient(client, rep.stringLength, path);
WriteToClient(client, stringLength, path);
return Success;
}

View File

@ -45,10 +45,6 @@
#include <dispatch/dispatch.h>
#ifdef DEBUG_XP_LOCK_WINDOW
#include <execinfo.h>
#endif
#define DEFINE_ATOM_HELPER(func, atom_name) \
static Atom func(void) { \
static int generation; \
@ -353,15 +349,8 @@ xprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow)
xp_error err;
#ifdef DEBUG_XP_LOCK_WINDOW
void* callstack[128];
int i, frames = backtrace(callstack, 128);
char** strs = backtrace_symbols(callstack, frames);
ErrorF("=== LOCK %d ===\n", (int)x_cvt_vptr_to_uint(wid));
for (i = 0; i < frames; ++i) {
ErrorF(" %s\n", strs[i]);
}
free(strs);
xorg_backtrace();
#endif
err = xp_lock_window(x_cvt_vptr_to_uint(
@ -371,6 +360,10 @@ xprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow)
(int)x_cvt_vptr_to_uint(
wid), (int)err);
#ifdef DEBUG_XP_LOCK_WINDOW
ErrorF(" bits: %p\n", *data);
#endif
*pixelData = data[0];
*bytesPerRow = rowbytes[0];
}
@ -384,15 +377,8 @@ xprStopDrawing(RootlessFrameID wid, Bool flush)
xp_error err;
#ifdef DEBUG_XP_LOCK_WINDOW
void* callstack[128];
int i, frames = backtrace(callstack, 128);
char** strs = backtrace_symbols(callstack, frames);
ErrorF("=== UNLOCK %d ===\n", (int)x_cvt_vptr_to_uint(wid));
for (i = 0; i < frames; ++i) {
ErrorF(" %s\n", strs[i]);
}
free(strs);
xorg_backtrace();
#endif
err = xp_unlock_window(x_cvt_vptr_to_uint(wid), flush);

View File

@ -1,17 +0,0 @@
Xwayland
drm-client-protocol.h
drm-protocol.c
linux-dmabuf-unstable-v1-client-protocol.h
linux-dmabuf-unstable-v1-protocol.c
pointer-constraints-unstable-v1-client-protocol.h
pointer-constraints-unstable-v1-protocol.c
relative-pointer-unstable-v1-client-protocol.h
relative-pointer-unstable-v1-protocol.c
tablet-unstable-v2-client-protocol.h
tablet-unstable-v2-protocol.c
viewporter-client-protocol.h
viewporter-protocol.c
xdg-output-unstable-v1-client-protocol.h
xdg-output-unstable-v1-protocol.c
xwayland-keyboard-grab-unstable-v1-client-protocol.h
xwayland-keyboard-grab-unstable-v1-protocol.c

View File

@ -1,189 +0,0 @@
SUBDIRS = man
DIST_SUBDIRS = man
bindir = @xwayland_path@
bin_PROGRAMS = Xwayland
Xwayland_CFLAGS = \
-I$(top_srcdir)/glamor \
-I$(top_srcdir)/dri3 \
-DHAVE_DIX_CONFIG_H \
$(XWAYLANDMODULES_CFLAGS) \
$(DIX_CFLAGS) \
$(GLAMOR_CFLAGS) \
$(GBM_CFLAGS) \
$(LIBXCVT_CFLAGS)
Xwayland_SOURCES = \
xwayland.c \
xwayland-input.c \
xwayland-input.h \
xwayland-cursor.c \
xwayland-cursor.h \
xwayland-glamor.h \
xwayland-glx.h \
xwayland-pixmap.c \
xwayland-pixmap.h \
xwayland-present.h \
xwayland-screen.c \
xwayland-screen.h \
xwayland-shm.c \
xwayland-shm.h \
xwayland-types.h \
xwayland-output.c \
xwayland-output.h \
xwayland-cvt.c \
xwayland-cvt.h \
xwayland-vidmode.c \
xwayland-vidmode.h \
xwayland-window.c \
xwayland-window.h \
xwayland-window-buffers.c \
xwayland-window-buffers.h \
$(top_srcdir)/Xi/stubs.c \
$(top_srcdir)/mi/miinitext.c \
$(top_srcdir)/mi/miinitext.h
if GLAMOR
if GLX
Xwayland_SOURCES += \
xwayland-glx.c
Xwayland_CFLAGS += \
-I$(top_srcdir)/glx
GLXVND_LIB = $(top_builddir)/glx/libglxvnd.la
endif #GLX
endif # GLAMOR
Xwayland_LDADD = \
$(glamor_lib) \
$(XWAYLAND_LIBS) \
$(GLXVND_LIB) \
$(XWAYLAND_SYS_LIBS) \
$(top_builddir)/Xext/libXvidmode.la \
$(XSERVER_SYS_LIBS) \
$(LIBXCVT_LIBS)
Xwayland_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
Xwayland_built_sources =
if GLAMOR_EGL
Xwayland_SOURCES += \
xwayland-glamor.c \
xwayland-glamor-gbm.c \
xwayland-present.c
if XV
Xwayland_SOURCES += \
xwayland-glamor-xv.c
endif
if XWAYLAND_EGLSTREAM
Xwayland_SOURCES += \
xwayland-glamor-eglstream.c
endif
glamor_built_sources = \
drm-client-protocol.h \
drm-protocol.c
Xwayland_built_sources += $(glamor_built_sources)
glamor_lib = $(top_builddir)/glamor/libglamor.la
Xwayland_LDADD += $(GLAMOR_LIBS) $(GBM_LIBS) -lEGL -lGL
Xwayland_DEPENDENCIES = $(glamor_lib) $(XWAYLAND_LIBS)
endif
Xwayland_built_sources += \
relative-pointer-unstable-v1-client-protocol.h \
relative-pointer-unstable-v1-protocol.c \
pointer-constraints-unstable-v1-client-protocol.h \
pointer-constraints-unstable-v1-protocol.c \
tablet-unstable-v2-client-protocol.h \
tablet-unstable-v2-protocol.c \
xwayland-keyboard-grab-unstable-v1-protocol.c \
xwayland-keyboard-grab-unstable-v1-client-protocol.h \
xdg-output-unstable-v1-protocol.c \
xdg-output-unstable-v1-client-protocol.h \
linux-dmabuf-unstable-v1-client-protocol.h \
linux-dmabuf-unstable-v1-protocol.c \
viewporter-client-protocol.h \
viewporter-protocol.c\
xdg-shell-client-protocol.h\
xdg-shell-protocol.c
if XWAYLAND_EGLSTREAM
Xwayland_built_sources += \
wayland-eglstream-client-protocol.h \
wayland-eglstream-protocol.c \
wayland-eglstream-controller-client-protocol.h \
wayland-eglstream-controller-protocol.c
endif
nodist_Xwayland_SOURCES = $(Xwayland_built_sources)
CLEANFILES = $(Xwayland_built_sources)
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = xwayland.pc
EXTRA_DIST = xwayland.pc.in drm.xml
$(Xwayland_SOURCES): $(Xwayland_built_sources)
relink:
$(AM_V_at)rm -f Xwayland$(EXEEXT) && $(MAKE) Xwayland$(EXEEXT)
relative-pointer-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/relative-pointer/relative-pointer-unstable-v1.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
relative-pointer-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/relative-pointer/relative-pointer-unstable-v1.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
pointer-constraints-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
pointer-constraints-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
tablet-unstable-v2-protocol.c: $(WAYLAND_PROTOCOLS_DATADIR)/unstable/tablet/tablet-unstable-v2.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
tablet-unstable-v2-client-protocol.h: $(WAYLAND_PROTOCOLS_DATADIR)/unstable/tablet/tablet-unstable-v2.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
xwayland-keyboard-grab-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xwayland-keyboard-grab/xwayland-keyboard-grab-unstable-v1.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
xwayland-keyboard-grab-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xwayland-keyboard-grab/xwayland-keyboard-grab-unstable-v1.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
xdg-output-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xdg-output/xdg-output-unstable-v1.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
xdg-output-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xdg-output/xdg-output-unstable-v1.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
linux-dmabuf-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
linux-dmabuf-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
viewporter-protocol.c: $(WAYLAND_PROTOCOLS_DATADIR)/stable/viewporter/viewporter.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
viewporter-client-protocol.h: $(WAYLAND_PROTOCOLS_DATADIR)/stable/viewporter/viewporter.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
xdg-shell-protocol.c: $(WAYLAND_PROTOCOLS_DATADIR)/stable/xdg-shell/xdg-shell.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
xdg-shell-client-protocol.h: $(WAYLAND_PROTOCOLS_DATADIR)/stable/xdg-shell/xdg-shell.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
wayland-eglstream-client-protocol.h : $(WAYLAND_EGLSTREAM_DATADIR)/wayland-eglstream.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
wayland-eglstream-controller-client-protocol.h : $(WAYLAND_EGLSTREAM_DATADIR)/wayland-eglstream-controller.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
wayland-eglstream-protocol.c : $(WAYLAND_EGLSTREAM_DATADIR)/wayland-eglstream.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
wayland-eglstream-controller-protocol.c : $(WAYLAND_EGLSTREAM_DATADIR)/wayland-eglstream-controller.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
%-protocol.c : %.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
%-client-protocol.h : %.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@

View File

@ -1,185 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="drm">
<copyright>
Copyright © 2008-2011 Kristian Høgsberg
Copyright © 2010-2011 Intel Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that\n the above copyright notice appear in
all copies and that both that copyright notice and this permission
notice appear in supporting documentation, and that the name of
the copyright holders not be used in advertising or publicity
pertaining to distribution of the software without specific,
written prior permission. The copyright holders make no
representations about the suitability of this software for any
purpose. It is provided "as is" without express or implied
warranty.
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
</copyright>
<!-- drm support. This object is created by the server and published
using the display's global event. -->
<interface name="wl_drm" version="2">
<enum name="error">
<entry name="authenticate_fail" value="0"/>
<entry name="invalid_format" value="1"/>
<entry name="invalid_name" value="2"/>
</enum>
<enum name="format">
<!-- The drm format codes match the #defines in drm_fourcc.h.
The formats actually supported by the compositor will be
reported by the format event. -->
<entry name="c8" value="0x20203843"/>
<entry name="rgb332" value="0x38424752"/>
<entry name="bgr233" value="0x38524742"/>
<entry name="xrgb4444" value="0x32315258"/>
<entry name="xbgr4444" value="0x32314258"/>
<entry name="rgbx4444" value="0x32315852"/>
<entry name="bgrx4444" value="0x32315842"/>
<entry name="argb4444" value="0x32315241"/>
<entry name="abgr4444" value="0x32314241"/>
<entry name="rgba4444" value="0x32314152"/>
<entry name="bgra4444" value="0x32314142"/>
<entry name="xrgb1555" value="0x35315258"/>
<entry name="xbgr1555" value="0x35314258"/>
<entry name="rgbx5551" value="0x35315852"/>
<entry name="bgrx5551" value="0x35315842"/>
<entry name="argb1555" value="0x35315241"/>
<entry name="abgr1555" value="0x35314241"/>
<entry name="rgba5551" value="0x35314152"/>
<entry name="bgra5551" value="0x35314142"/>
<entry name="rgb565" value="0x36314752"/>
<entry name="bgr565" value="0x36314742"/>
<entry name="rgb888" value="0x34324752"/>
<entry name="bgr888" value="0x34324742"/>
<entry name="xrgb8888" value="0x34325258"/>
<entry name="xbgr8888" value="0x34324258"/>
<entry name="rgbx8888" value="0x34325852"/>
<entry name="bgrx8888" value="0x34325842"/>
<entry name="argb8888" value="0x34325241"/>
<entry name="abgr8888" value="0x34324241"/>
<entry name="rgba8888" value="0x34324152"/>
<entry name="bgra8888" value="0x34324142"/>
<entry name="xrgb2101010" value="0x30335258"/>
<entry name="xbgr2101010" value="0x30334258"/>
<entry name="rgbx1010102" value="0x30335852"/>
<entry name="bgrx1010102" value="0x30335842"/>
<entry name="argb2101010" value="0x30335241"/>
<entry name="abgr2101010" value="0x30334241"/>
<entry name="rgba1010102" value="0x30334152"/>
<entry name="bgra1010102" value="0x30334142"/>
<entry name="yuyv" value="0x56595559"/>
<entry name="yvyu" value="0x55595659"/>
<entry name="uyvy" value="0x59565955"/>
<entry name="vyuy" value="0x59555956"/>
<entry name="ayuv" value="0x56555941"/>
<entry name="nv12" value="0x3231564e"/>
<entry name="nv21" value="0x3132564e"/>
<entry name="nv16" value="0x3631564e"/>
<entry name="nv61" value="0x3136564e"/>
<entry name="yuv410" value="0x39565559"/>
<entry name="yvu410" value="0x39555659"/>
<entry name="yuv411" value="0x31315559"/>
<entry name="yvu411" value="0x31315659"/>
<entry name="yuv420" value="0x32315559"/>
<entry name="yvu420" value="0x32315659"/>
<entry name="yuv422" value="0x36315559"/>
<entry name="yvu422" value="0x36315659"/>
<entry name="yuv444" value="0x34325559"/>
<entry name="yvu444" value="0x34325659"/>
</enum>
<!-- Call this request with the magic received from drmGetMagic().
It will be passed on to the drmAuthMagic() or
DRIAuthConnection() call. This authentication must be
completed before create_buffer could be used. -->
<request name="authenticate">
<arg name="id" type="uint"/>
</request>
<!-- Create a wayland buffer for the named DRM buffer. The DRM
surface must have a name using the flink ioctl -->
<request name="create_buffer">
<arg name="id" type="new_id" interface="wl_buffer"/>
<arg name="name" type="uint"/>
<arg name="width" type="int"/>
<arg name="height" type="int"/>
<arg name="stride" type="uint"/>
<arg name="format" type="uint"/>
</request>
<!-- Create a wayland buffer for the named DRM buffer. The DRM
surface must have a name using the flink ioctl -->
<request name="create_planar_buffer">
<arg name="id" type="new_id" interface="wl_buffer"/>
<arg name="name" type="uint"/>
<arg name="width" type="int"/>
<arg name="height" type="int"/>
<arg name="format" type="uint"/>
<arg name="offset0" type="int"/>
<arg name="stride0" type="int"/>
<arg name="offset1" type="int"/>
<arg name="stride1" type="int"/>
<arg name="offset2" type="int"/>
<arg name="stride2" type="int"/>
</request>
<!-- Notification of the path of the drm device which is used by
the server. The client should use this device for creating
local buffers. Only buffers created from this device should
be be passed to the server using this drm object's
create_buffer request. -->
<event name="device">
<arg name="name" type="string"/>
</event>
<event name="format">
<arg name="format" type="uint"/>
</event>
<!-- Raised if the authenticate request succeeded -->
<event name="authenticated"/>
<enum name="capability" since="2">
<description summary="wl_drm capability bitmask">
Bitmask of capabilities.
</description>
<entry name="prime" value="1" summary="wl_drm prime available"/>
</enum>
<event name="capabilities">
<arg name="value" type="uint"/>
</event>
<!-- Version 2 additions -->
<!-- Create a wayland buffer for the prime fd. Use for regular and planar
buffers. Pass 0 for offset and stride for unused planes. -->
<request name="create_prime_buffer" since="2">
<arg name="id" type="new_id" interface="wl_buffer"/>
<arg name="name" type="fd"/>
<arg name="width" type="int"/>
<arg name="height" type="int"/>
<arg name="format" type="uint"/>
<arg name="offset0" type="int"/>
<arg name="stride0" type="int"/>
<arg name="offset1" type="int"/>
<arg name="stride1" type="int"/>
<arg name="offset2" type="int"/>
<arg name="stride2" type="int"/>
</request>
</interface>
</protocol>

View File

@ -1,2 +0,0 @@
include $(top_srcdir)/manpages.am
appman_PRE = Xwayland.man

View File

@ -1,107 +0,0 @@
'\" t
.\"
.\" Copyright 1984 - 1991, 1993, 1994, 1998 The Open Group
.\"
.\" Permission to use, copy, modify, distribute, and sell this software and its
.\" documentation for any purpose is hereby granted without fee, provided that
.\" the above copyright notice appear in all copies and that both that
.\" copyright notice and this permission notice appear in supporting
.\" documentation.
.\"
.\" The above copyright notice and this permission notice shall be included
.\" in all copies or substantial portions of the Software.
.\"
.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
.\" OTHER DEALINGS IN THE SOFTWARE.
.\"
.\" Except as contained in this notice, the name of The Open Group shall
.\" not be used in advertising or otherwise to promote the sale, use or
.\" other dealings in this Software without prior written authorization
.\" from The Open Group.
.\" shorthand for double quote that works everywhere.
.ds q \N'34'
.TH XWAYLAND 1 @xorgversion@
.SH NAME
Xwayland \- an X server for running X clients under Wayland.
.SH SYNOPSIS
.B Xwayland
[option ...]
.SH DESCRIPTION
.I Xwayland
is an X server and a Wayland client. It plays the role of a proxy between
legacy X clients which do not support the Wayland protocols and the Wayland
server.
.PP
Usually, \fIXwayland\fP is spawned automatically by the Wayland server
and runs rootless so that X clients integrate seamlessly with the rest
of the Wayland desktop. It is however possible for a user to launch Xwayland
non-rootless, mainly for testing purposes.
.PP
Like all of the X servers, \fIXwayland\fP accepts the command line options
described in the \fIXserver\fP(@miscmansuffix@) manual page.
The following additional arguments are supported as well.
.TP 8
.B \-eglstream
Use EGLStream backend for NVidia GPUs. If \fIXwayland\fP was compiled with
EGLStream support, this option will instruct \fIXwayland\fP to try that
backend first, then fallback to the GBM backend if EGLStream is not supported
by the Wayland server. Without this option, \fIXwayland\fP tries the GBM
backend first, and fallback to EGLStream if GBM is not usable.
.TP 8
.B \-initfd \fIfd\fP
Add the given \fIfd\fP as a listen socket for initialization of X clients.
This options is aimed at \fIWayland\fP servers which run \fIXwayland\fP
on-demand, to be able to spawn specific X clients which need to complete
before other regular X clients can connect to \fIXwayland\fP, like \fIxrdb\fP.
.TP 8
.B \-listen \fIfd\fP
deprecated, use \fI\-listenfd\fP instead.
.TP 8
.B \-listenfd \fIfd\\fP
Add given fd as a listen socket. This option is used by the \fIWayland\fP
server to pass \fIXwayland\fP the socket where X clients connect.
.TP 8
.B \-noTouchPointerEmulation
Disable touch pointer emulation. This allows the Wayland compositor to
implement its own pointer emulation mechanism for X11 clients that don't
support touch input.
.TP 8
.B \-rootless
Run \fIXwayland\fP rootless, so that X clients integrate seamlessly with
Wayland clients in a Wayland desktop. That requires the Wayland server
to be an X window manager as well.
.TP 8
.BI \-shm
Force the shared memory backend instead of glamor (if available) for passing
buffers to the Wayland server.
.TP 8
.BR \-verbose " [\fIn\fP]"
Sets the verbosity level for information printed on stderr. If the
.I n
value isn't supplied, each occurrence of this option increments the
verbosity level. When the
.I n
value is supplied, the verbosity level is set to that value. The default
verbosity level is 0.
.TP 8
.BI \-version
Show the server version and exit.
.TP 8
.B \-wm \fIfd\fP
This option is used by the \fIWayland\fP server to pass \fIXwayland\fP
the socket where the X window manager client connects, when \fIXwayland\fP
is running with \fI-rootless\fP.
.SH ENVIRONMENT
.TP 8
.B WAYLAND_DISPLAY
the name of the display of the Wayland server.
.TP 8
.B XWAYLAND_NO_GLAMOR
disable glamor and DRI3 support in \fIXwayland\fP, for testing purposes.
.SH "SEE ALSO"
General information: \fIX\fP(@miscmansuffix@)

View File

@ -1,160 +0,0 @@
srcs = [
'xwayland.c',
'xwayland-input.c',
'xwayland-input.h',
'xwayland-cursor.c',
'xwayland-cursor.h',
'xwayland-glamor.h',
'xwayland-glx.h',
'xwayland-pixmap.c',
'xwayland-pixmap.h',
'xwayland-present.h',
'xwayland-screen.c',
'xwayland-screen.h',
'xwayland-shm.c',
'xwayland-shm.h',
'xwayland-types.h',
'xwayland-output.c',
'xwayland-output.h',
'xwayland-cvt.c',
'xwayland-cvt.h',
'xwayland-vidmode.c',
'xwayland-vidmode.h',
'xwayland-window.c',
'xwayland-window.h',
'xwayland-window-buffers.c',
'xwayland-window-buffers.h',
'../../mi/miinitext.c',
'../../mi/miinitext.h',
]
scanner_dep = dependency('wayland-scanner', native: true)
scanner = find_program(scanner_dep.get_pkgconfig_variable('wayland_scanner'))
protocols_dep = dependency('wayland-protocols', version: wayland_protocols_req)
protodir = protocols_dep.get_pkgconfig_variable('pkgdatadir')
pointer_xml = join_paths(protodir, 'unstable', 'pointer-constraints', 'pointer-constraints-unstable-v1.xml')
relative_xml = join_paths(protodir, 'unstable', 'relative-pointer', 'relative-pointer-unstable-v1.xml')
tablet_xml = join_paths(protodir, 'unstable', 'tablet', 'tablet-unstable-v2.xml')
kbgrab_xml = join_paths(protodir, 'unstable', 'xwayland-keyboard-grab', 'xwayland-keyboard-grab-unstable-v1.xml')
xdg_output_xml = join_paths(protodir, 'unstable', 'xdg-output', 'xdg-output-unstable-v1.xml')
dmabuf_xml = join_paths(protodir, 'unstable', 'linux-dmabuf', 'linux-dmabuf-unstable-v1.xml')
viewporter_xml = join_paths(protodir, 'stable', 'viewporter', 'viewporter.xml')
xdg_shell_xml = join_paths(protodir, 'stable', 'xdg-shell', 'xdg-shell.xml')
client_header = generator(scanner,
output : '@BASENAME@-client-protocol.h',
arguments : ['client-header', '@INPUT@', '@OUTPUT@']
)
if scanner_dep.version().version_compare('>= 1.14.91')
scanner_argument = 'private-code'
else
scanner_argument = 'code'
endif
code = generator(scanner,
output : '@BASENAME@-protocol.c',
arguments : [scanner_argument, '@INPUT@', '@OUTPUT@']
)
srcs += client_header.process(relative_xml)
srcs += client_header.process(pointer_xml)
srcs += client_header.process(tablet_xml)
srcs += client_header.process(kbgrab_xml)
srcs += client_header.process(xdg_output_xml)
srcs += client_header.process(dmabuf_xml)
srcs += client_header.process(viewporter_xml)
srcs += client_header.process(xdg_shell_xml)
srcs += code.process(relative_xml)
srcs += code.process(pointer_xml)
srcs += code.process(tablet_xml)
srcs += code.process(kbgrab_xml)
srcs += code.process(xdg_output_xml)
srcs += code.process(dmabuf_xml)
srcs += code.process(viewporter_xml)
srcs += code.process(xdg_shell_xml)
xwayland_glamor = []
eglstream_srcs = []
if build_glamor
srcs += 'xwayland-glamor.c'
if build_glx
srcs += 'xwayland-glx.c'
endif
if gbm_dep.found()
srcs += 'xwayland-glamor-gbm.c'
endif
if build_eglstream
eglstream_protodir = eglstream_dep.get_pkgconfig_variable('pkgdatadir')
eglstream_xml = join_paths(eglstream_protodir, 'wayland-eglstream.xml')
eglstream_controller_xml = join_paths(eglstream_protodir, 'wayland-eglstream-controller.xml')
srcs += client_header.process(eglstream_xml)
srcs += client_header.process(eglstream_controller_xml)
srcs += code.process(eglstream_xml)
srcs += code.process(eglstream_controller_xml)
srcs += 'xwayland-glamor-eglstream.c'
endif
srcs += 'xwayland-present.c'
if build_xv
srcs += 'xwayland-glamor-xv.c'
endif
srcs += client_header.process('drm.xml')
srcs += code.process('drm.xml')
xwayland_dep += gbm_dep
xwayland_glamor += glamor
endif
wayland_inc = [ inc, ]
if build_glx
wayland_inc += glx_inc
endif
xwayland_server = executable(
'Xwayland',
srcs,
include_directories: wayland_inc,
dependencies: [
common_dep,
xwayland_dep,
],
link_with: [
libxserver_main,
xwayland_glamor,
libxserver_fb,
libxserver,
libxserver_xext_vidmode,
libxserver_xkb_stubs,
libxserver_xi_stubs,
libxserver_glx,
libglxvnd,
],
install: true,
install_dir: xwayland_path
)
xwayland_data = configuration_data()
xwayland_data.set('prefix', get_option('prefix'))
xwayland_data.set('exec_prefix', '${prefix}')
xwayland_data.set('PACKAGE_VERSION', meson.project_version())
xwayland_data.set('xwayland_path', xwayland_path)
xwayland_data.set('have_glamor', build_glamor ? 'true' : 'false')
xwayland_data.set('have_eglstream', build_eglstream ? 'true' : 'false')
configure_file(
input: 'xwayland.pc.in',
output: 'xwayland.pc',
configuration: xwayland_data,
install_dir: join_paths(get_option('prefix'),
get_option('libdir'),
'pkgconfig'),
)
xwayland_manpage = configure_file(
input: 'man/Xwayland.man',
output: 'Xwayland.1',
configuration: manpage_config,
)
install_man(xwayland_manpage)

View File

@ -1,428 +0,0 @@
/*
* Copyright © 2014 Intel Corporation
* Copyright © 2011 Kristian Høgsberg
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the
* copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#include <xwayland-config.h>
#include "scrnintstr.h"
#include "servermd.h"
#include "cursorstr.h"
#include "inputstr.h"
#include "mipointer.h"
#include "xwayland-cursor.h"
#include "xwayland-input.h"
#include "xwayland-pixmap.h"
#include "xwayland-screen.h"
#include "xwayland-shm.h"
#include "xwayland-types.h"
#include "tablet-unstable-v2-client-protocol.h"
#define DELAYED_X_CURSOR_TIMEOUT 5 /* ms */
static DevPrivateKeyRec xwl_cursor_private_key;
static void
expand_source_and_mask(CursorPtr cursor, CARD32 *data)
{
CARD32 *p, d, fg, bg;
CursorBitsPtr bits = cursor->bits;
int x, y, stride, i, bit;
p = data;
fg = ((cursor->foreRed & 0xff00) << 8) |
(cursor->foreGreen & 0xff00) | (cursor->foreGreen >> 8);
bg = ((cursor->backRed & 0xff00) << 8) |
(cursor->backGreen & 0xff00) | (cursor->backGreen >> 8);
stride = BitmapBytePad(bits->width);
for (y = 0; y < bits->height; y++)
for (x = 0; x < bits->width; x++) {
i = y * stride + x / 8;
bit = 1 << (x & 7);
if (bits->source[i] & bit)
d = fg;
else
d = bg;
if (bits->mask[i] & bit)
d |= 0xff000000;
else
d = 0x00000000;
*p++ = d;
}
}
static Bool
xwl_realize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
{
PixmapPtr pixmap;
pixmap = xwl_shm_create_pixmap(screen, cursor->bits->width,
cursor->bits->height, 32,
CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
dixSetPrivate(&cursor->devPrivates, &xwl_cursor_private_key, pixmap);
return TRUE;
}
static Bool
xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
{
PixmapPtr pixmap;
struct xwl_screen *xwl_screen;
struct xwl_seat *xwl_seat;
pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key);
if (!pixmap)
return TRUE;
dixSetPrivate(&cursor->devPrivates, &xwl_cursor_private_key, NULL);
/* When called from FreeCursor(), device is always NULL */
xwl_screen = xwl_screen_get(screen);
xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) {
if (cursor == xwl_seat->x_cursor)
xwl_seat->x_cursor = NULL;
}
return xwl_shm_destroy_pixmap(pixmap);
}
static void
clear_cursor_frame_callback(struct xwl_cursor *xwl_cursor)
{
if (xwl_cursor->frame_cb) {
wl_callback_destroy (xwl_cursor->frame_cb);
xwl_cursor->frame_cb = NULL;
}
}
static void
frame_callback(void *data,
struct wl_callback *callback,
uint32_t time)
{
struct xwl_cursor *xwl_cursor = data;
clear_cursor_frame_callback(xwl_cursor);
if (xwl_cursor->needs_update) {
xwl_cursor->needs_update = FALSE;
xwl_cursor->update_proc(xwl_cursor);
}
}
static const struct wl_callback_listener frame_listener = {
frame_callback
};
static void
xwl_cursor_buffer_release_callback(void *data)
{
/* drop the reference we took in set_cursor */
xwl_shm_destroy_pixmap(data);
}
static void
xwl_cursor_copy_bits_to_pixmap(CursorPtr cursor, PixmapPtr pixmap)
{
int stride;
stride = cursor->bits->width * 4;
if (cursor->bits->argb)
memcpy(pixmap->devPrivate.ptr,
cursor->bits->argb, cursor->bits->height * stride);
else
expand_source_and_mask(cursor, pixmap->devPrivate.ptr);
}
static void
xwl_cursor_attach_pixmap(struct xwl_seat *xwl_seat,
struct xwl_cursor *xwl_cursor, PixmapPtr pixmap)
{
struct wl_buffer *buffer;
buffer = xwl_shm_pixmap_get_wl_buffer(pixmap);
if (!buffer) {
ErrorF("cursor: Error getting buffer\n");
return;
}
wl_surface_attach(xwl_cursor->surface, buffer, 0, 0);
xwl_surface_damage(xwl_seat->xwl_screen, xwl_cursor->surface, 0, 0,
xwl_seat->x_cursor->bits->width,
xwl_seat->x_cursor->bits->height);
xwl_cursor->frame_cb = wl_surface_frame(xwl_cursor->surface);
wl_callback_add_listener(xwl_cursor->frame_cb, &frame_listener, xwl_cursor);
/* Hold a reference on the pixmap until it's released by the compositor */
pixmap->refcnt++;
xwl_pixmap_set_buffer_release_cb(pixmap,
xwl_cursor_buffer_release_callback,
pixmap);
wl_surface_commit(xwl_cursor->surface);
}
void
xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
{
struct xwl_cursor *xwl_cursor = &xwl_seat->cursor;
PixmapPtr pixmap;
CursorPtr cursor;
if (!xwl_seat->wl_pointer)
return;
if (!xwl_seat->x_cursor) {
wl_pointer_set_cursor(xwl_seat->wl_pointer,
xwl_seat->pointer_enter_serial, NULL, 0, 0);
clear_cursor_frame_callback(xwl_cursor);
xwl_cursor->needs_update = FALSE;
return;
}
if (xwl_cursor->frame_cb) {
xwl_cursor->needs_update = TRUE;
return;
}
cursor = xwl_seat->x_cursor;
pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key);
if (!pixmap)
return;
xwl_cursor_copy_bits_to_pixmap(cursor, pixmap);
wl_pointer_set_cursor(xwl_seat->wl_pointer,
xwl_seat->pointer_enter_serial,
xwl_cursor->surface,
xwl_seat->x_cursor->bits->xhot,
xwl_seat->x_cursor->bits->yhot);
xwl_cursor_attach_pixmap(xwl_seat, xwl_cursor, pixmap);
}
void
xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool)
{
struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
struct xwl_cursor *xwl_cursor = &xwl_tablet_tool->cursor;
PixmapPtr pixmap;
CursorPtr cursor;
if (!xwl_seat->x_cursor) {
zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool,
xwl_tablet_tool->proximity_in_serial,
NULL, 0, 0);
clear_cursor_frame_callback(xwl_cursor);
xwl_cursor->needs_update = FALSE;
return;
}
if (xwl_cursor->frame_cb) {
xwl_cursor->needs_update = TRUE;
return;
}
cursor = xwl_seat->x_cursor;
pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key);
if (!pixmap)
return;
xwl_cursor_copy_bits_to_pixmap(cursor, pixmap);
zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool,
xwl_tablet_tool->proximity_in_serial,
xwl_cursor->surface,
xwl_seat->x_cursor->bits->xhot,
xwl_seat->x_cursor->bits->yhot);
xwl_cursor_attach_pixmap(xwl_seat, xwl_cursor, pixmap);
}
static void
xwl_seat_update_cursor(struct xwl_seat *xwl_seat)
{
struct xwl_tablet_tool *xwl_tablet_tool;
xwl_seat_set_cursor(xwl_seat);
xorg_list_for_each_entry(xwl_tablet_tool, &xwl_seat->tablet_tools, link) {
if (xwl_tablet_tool->proximity_in_serial != 0)
xwl_tablet_tool_set_cursor(xwl_tablet_tool);
}
/* Clear delayed cursor if any */
xwl_seat->pending_x_cursor = NULL;
}
static void
xwl_seat_update_cursor_visibility(struct xwl_seat *xwl_seat)
{
xwl_seat->x_cursor = xwl_seat->pending_x_cursor;
xwl_seat_cursor_visibility_changed(xwl_seat);
xwl_seat_update_cursor(xwl_seat);
}
static void
xwl_set_cursor_free_timer(struct xwl_seat *xwl_seat)
{
if (xwl_seat->x_cursor_timer) {
TimerFree(xwl_seat->x_cursor_timer);
xwl_seat->x_cursor_timer = NULL;
}
}
static CARD32
xwl_set_cursor_timer_callback(OsTimerPtr timer, CARD32 time, void *arg)
{
struct xwl_seat *xwl_seat = arg;
xwl_set_cursor_free_timer(xwl_seat);
xwl_seat_update_cursor_visibility(xwl_seat);
/* Don't re-arm the timer */
return 0;
}
static void
xwl_set_cursor_delayed(struct xwl_seat *xwl_seat, CursorPtr cursor)
{
xwl_seat->pending_x_cursor = cursor;
if (xwl_seat->x_cursor_timer == NULL) {
xwl_seat->x_cursor_timer = TimerSet(xwl_seat->x_cursor_timer,
0, DELAYED_X_CURSOR_TIMEOUT,
&xwl_set_cursor_timer_callback,
xwl_seat);
}
}
static void
xwl_set_cursor(DeviceIntPtr device,
ScreenPtr screen, CursorPtr cursor, int x, int y)
{
struct xwl_seat *xwl_seat;
Bool cursor_visibility_changed;
xwl_seat = device->public.devicePrivate;
if (xwl_seat == NULL)
return;
cursor_visibility_changed = !!xwl_seat->x_cursor ^ !!cursor;
if (!cursor_visibility_changed) {
/* Cursor remains shown or hidden, apply the change immediately */
xwl_set_cursor_free_timer(xwl_seat);
xwl_seat->x_cursor = cursor;
xwl_seat_update_cursor(xwl_seat);
return;
}
xwl_seat->pending_x_cursor = cursor;
if (cursor) {
/* Cursor is being shown, delay the change until moved or timed out */
xwl_set_cursor_delayed(xwl_seat, cursor);
} else {
/* Cursor is being hidden, apply the change immediately */
xwl_seat_update_cursor_visibility(xwl_seat);
}
}
static void
xwl_move_cursor(DeviceIntPtr device, ScreenPtr screen, int x, int y)
{
struct xwl_seat *xwl_seat;
xwl_seat = device->public.devicePrivate;
if (xwl_seat == NULL)
return;
xwl_set_cursor_free_timer(xwl_seat);
if (xwl_seat->pending_x_cursor)
xwl_seat_update_cursor_visibility(xwl_seat);
}
static Bool
xwl_device_cursor_initialize(DeviceIntPtr device, ScreenPtr screen)
{
return TRUE;
}
static void
xwl_device_cursor_cleanup(DeviceIntPtr device, ScreenPtr screen)
{
struct xwl_seat *xwl_seat;
xwl_seat = device->public.devicePrivate;
if (xwl_seat)
xwl_set_cursor_free_timer(xwl_seat);
}
static miPointerSpriteFuncRec xwl_pointer_sprite_funcs = {
xwl_realize_cursor,
xwl_unrealize_cursor,
xwl_set_cursor,
xwl_move_cursor,
xwl_device_cursor_initialize,
xwl_device_cursor_cleanup
};
static Bool
xwl_cursor_off_screen(ScreenPtr *ppScreen, int *x, int *y)
{
return FALSE;
}
static void
xwl_cross_screen(ScreenPtr pScreen, Bool entering)
{
}
static void
xwl_pointer_warp_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
{
miPointerWarpCursor(pDev, pScreen, x, y);
}
static miPointerScreenFuncRec xwl_pointer_screen_funcs = {
xwl_cursor_off_screen,
xwl_cross_screen,
xwl_pointer_warp_cursor
};
Bool
xwl_screen_init_cursor(struct xwl_screen *xwl_screen)
{
if (!dixRegisterPrivateKey(&xwl_cursor_private_key, PRIVATE_CURSOR_BITS, 0))
return FALSE;
return miPointerInitialize(xwl_screen->screen,
&xwl_pointer_sprite_funcs,
&xwl_pointer_screen_funcs, TRUE);
}

View File

@ -1,38 +0,0 @@
/*
* Copyright © 2014 Intel Corporation
* Copyright © 2011 Kristian Høgsberg
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the
* copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#ifndef XWAYLAND_CURSOR_H
#define XWAYLAND_CURSOR_H
#include <xwayland-config.h>
#include <xwayland-types.h>
#include <xwayland-input.h>
void xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *tool);
void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
Bool xwl_screen_init_cursor(struct xwl_screen *xwl_screen);
#endif /* XWAYLAND_CURSOR_H */

View File

@ -1,62 +0,0 @@
/*
* Copyright 2005-2006 Luc Verhaegen.
* Copyright © 2021 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include <xwayland-config.h>
#include <string.h>
#include <randrstr.h>
#include <libxcvt/libxcvt.h>
#include "xwayland-cvt.h"
RRModePtr
xwayland_cvt(int hdisplay, int vdisplay, float vrefresh, Bool reduced,
Bool interlaced)
{
struct libxcvt_mode_info *libxcvt_mode_info;
char name[128];
xRRModeInfo modeinfo;
libxcvt_mode_info =
libxcvt_gen_mode_info(hdisplay, vdisplay, vrefresh, reduced, interlaced);
memset(&modeinfo, 0, sizeof modeinfo);
modeinfo.width = libxcvt_mode_info->hdisplay;
modeinfo.height = libxcvt_mode_info->vdisplay;
modeinfo.dotClock = libxcvt_mode_info->dot_clock * 1000.0;
modeinfo.hSyncStart = libxcvt_mode_info->hsync_start;
modeinfo.hSyncEnd = libxcvt_mode_info->hsync_end;
modeinfo.hTotal = libxcvt_mode_info->htotal;
modeinfo.vSyncStart = libxcvt_mode_info->vsync_start;
modeinfo.vSyncEnd = libxcvt_mode_info->vsync_end;
modeinfo.vTotal = libxcvt_mode_info->vtotal;
modeinfo.modeFlags = libxcvt_mode_info->mode_flags;
free(libxcvt_mode_info);
snprintf(name, sizeof name, "%dx%d",
modeinfo.width, modeinfo.height);
modeinfo.nameLength = strlen(name);
return RRModeGet(&modeinfo, name);
}

View File

@ -1,34 +0,0 @@
/*
* Copyright 2005-2006 Luc Verhaegen.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef XWAYLAND_CVT_H
#define XWAYLAND_CVT_H
#include <xwayland-config.h>
#include <dix.h>
#include <randrstr.h>
RRModePtr xwayland_cvt(int HDisplay, int VDisplay,
float VRefresh, Bool Reduced, Bool Interlaced);
#endif /* XWAYLAND_CVT_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,974 +0,0 @@
/*
* Copyright © 2011-2014 Intel Corporation
* Copyright © 2017 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including
* the next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Lyude Paul <lyude@redhat.com>
*
*/
#include <xwayland-config.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include <xf86drm.h>
#include <drm_fourcc.h>
#define MESA_EGL_NO_X11_HEADERS
#define EGL_NO_X11
#include <gbm.h>
#include <glamor_egl.h>
#include <glamor.h>
#include <glamor_context.h>
#include <dri3.h>
#include "drm-client-protocol.h"
#include "xwayland-glamor.h"
#include "xwayland-pixmap.h"
#include "xwayland-screen.h"
#include "linux-dmabuf-unstable-v1-client-protocol.h"
struct xwl_gbm_private {
char *device_name;
struct gbm_device *gbm;
struct wl_drm *drm;
int drm_fd;
int fd_render_node;
Bool drm_authenticated;
uint32_t capabilities;
int dmabuf_capable;
};
struct xwl_pixmap {
struct wl_buffer *buffer;
EGLImage image;
unsigned int texture;
struct gbm_bo *bo;
};
static DevPrivateKeyRec xwl_gbm_private_key;
static DevPrivateKeyRec xwl_auth_state_private_key;
static inline struct xwl_gbm_private *
xwl_gbm_get(struct xwl_screen *xwl_screen)
{
return dixLookupPrivate(&xwl_screen->screen->devPrivates,
&xwl_gbm_private_key);
}
static uint32_t
gbm_format_for_depth(int depth)
{
switch (depth) {
case 16:
return GBM_FORMAT_RGB565;
case 24:
return GBM_FORMAT_XRGB8888;
case 30:
return GBM_FORMAT_ARGB2101010;
default:
ErrorF("unexpected depth: %d\n", depth);
case 32:
return GBM_FORMAT_ARGB8888;
}
}
static char
is_device_path_render_node (const char *device_path)
{
char is_render_node;
int fd;
fd = open(device_path, O_RDWR | O_CLOEXEC);
if (fd < 0)
return 0;
is_render_node = (drmGetNodeTypeFromFd(fd) == DRM_NODE_RENDER);
close(fd);
return is_render_node;
}
static PixmapPtr
xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
int depth)
{
PixmapPtr pixmap;
struct xwl_pixmap *xwl_pixmap;
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
xwl_pixmap = calloc(1, sizeof(*xwl_pixmap));
if (xwl_pixmap == NULL)
return NULL;
pixmap = glamor_create_pixmap(screen,
gbm_bo_get_width(bo),
gbm_bo_get_height(bo),
depth,
GLAMOR_CREATE_PIXMAP_NO_TEXTURE);
if (!pixmap) {
free(xwl_pixmap);
return NULL;
}
xwl_glamor_egl_make_current(xwl_screen);
xwl_pixmap->bo = bo;
xwl_pixmap->buffer = NULL;
xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display,
xwl_screen->egl_context,
EGL_NATIVE_PIXMAP_KHR,
xwl_pixmap->bo, NULL);
if (xwl_pixmap->image == EGL_NO_IMAGE_KHR)
goto error;
glGenTextures(1, &xwl_pixmap->texture);
glBindTexture(GL_TEXTURE_2D, xwl_pixmap->texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, xwl_pixmap->image);
if (eglGetError() != EGL_SUCCESS)
goto error;
glBindTexture(GL_TEXTURE_2D, 0);
if (!glamor_set_pixmap_texture(pixmap, xwl_pixmap->texture))
goto error;
glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
xwl_pixmap_set_private(pixmap, xwl_pixmap);
return pixmap;
error:
if (xwl_pixmap->image != EGL_NO_IMAGE_KHR)
eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image);
if (pixmap)
glamor_destroy_pixmap(pixmap);
free(xwl_pixmap);
return NULL;
}
static PixmapPtr
xwl_glamor_gbm_create_pixmap(ScreenPtr screen,
int width, int height, int depth,
unsigned int hint)
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
struct gbm_bo *bo;
PixmapPtr pixmap = NULL;
if (width > 0 && height > 0 && depth >= 15 &&
(hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP ||
hint == CREATE_PIXMAP_USAGE_SHARED ||
(xwl_screen->rootless && hint == 0))) {
uint32_t format = gbm_format_for_depth(depth);
#ifdef GBM_BO_WITH_MODIFIERS
if (xwl_gbm->dmabuf_capable) {
uint32_t num_modifiers;
uint64_t *modifiers = NULL;
xwl_glamor_get_modifiers(screen, format, &num_modifiers, &modifiers);
bo = gbm_bo_create_with_modifiers(xwl_gbm->gbm, width, height,
format, modifiers, num_modifiers);
free(modifiers);
}
else
#endif
{
bo = gbm_bo_create(xwl_gbm->gbm, width, height, format,
GBM_BO_USE_RENDERING);
}
if (bo) {
pixmap = xwl_glamor_gbm_create_pixmap_for_bo(screen, bo, depth);
if (!pixmap) {
gbm_bo_destroy(bo);
}
else if (xwl_screen->rootless && hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP) {
glamor_clear_pixmap(pixmap);
}
}
}
if (!pixmap)
pixmap = glamor_create_pixmap(screen, width, height, depth, hint);
return pixmap;
}
static Bool
xwl_glamor_gbm_destroy_pixmap(PixmapPtr pixmap)
{
struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
if (xwl_pixmap && pixmap->refcnt == 1) {
xwl_pixmap_del_buffer_release_cb(pixmap);
if (xwl_pixmap->buffer)
wl_buffer_destroy(xwl_pixmap->buffer);
eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image);
if (xwl_pixmap->bo)
gbm_bo_destroy(xwl_pixmap->bo);
free(xwl_pixmap);
}
return glamor_destroy_pixmap(pixmap);
}
static const struct wl_buffer_listener xwl_glamor_gbm_buffer_listener = {
xwl_pixmap_buffer_release_cb,
};
static struct wl_buffer *
xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap)
{
struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
unsigned short width = pixmap->drawable.width;
unsigned short height = pixmap->drawable.height;
uint32_t format;
int prime_fd;
int num_planes;
uint32_t strides[4];
uint32_t offsets[4];
uint64_t modifier;
int i;
if (xwl_pixmap == NULL)
return NULL;
if (xwl_pixmap->buffer) {
/* Buffer already exists. */
return xwl_pixmap->buffer;
}
if (!xwl_pixmap->bo)
return NULL;
format = wl_drm_format_for_depth(pixmap->drawable.depth);
prime_fd = gbm_bo_get_fd(xwl_pixmap->bo);
if (prime_fd == -1)
return NULL;
#ifdef GBM_BO_WITH_MODIFIERS
num_planes = gbm_bo_get_plane_count(xwl_pixmap->bo);
modifier = gbm_bo_get_modifier(xwl_pixmap->bo);
for (i = 0; i < num_planes; i++) {
strides[i] = gbm_bo_get_stride_for_plane(xwl_pixmap->bo, i);
offsets[i] = gbm_bo_get_offset(xwl_pixmap->bo, i);
}
#else
num_planes = 1;
modifier = DRM_FORMAT_MOD_INVALID;
strides[0] = gbm_bo_get_stride(xwl_pixmap->bo);
offsets[0] = 0;
#endif
if (xwl_screen->dmabuf &&
xwl_glamor_is_modifier_supported(xwl_screen, format, modifier)) {
struct zwp_linux_buffer_params_v1 *params;
params = zwp_linux_dmabuf_v1_create_params(xwl_screen->dmabuf);
for (i = 0; i < num_planes; i++) {
zwp_linux_buffer_params_v1_add(params, prime_fd, i,
offsets[i], strides[i],
modifier >> 32, modifier & 0xffffffff);
}
xwl_pixmap->buffer =
zwp_linux_buffer_params_v1_create_immed(params, width, height,
format, 0);
zwp_linux_buffer_params_v1_destroy(params);
} else if (num_planes == 1) {
xwl_pixmap->buffer =
wl_drm_create_prime_buffer(xwl_gbm->drm, prime_fd, width, height,
format,
0, gbm_bo_get_stride(xwl_pixmap->bo),
0, 0,
0, 0);
}
close(prime_fd);
/* Add our listener now */
wl_buffer_add_listener(xwl_pixmap->buffer,
&xwl_glamor_gbm_buffer_listener, pixmap);
return xwl_pixmap->buffer;
}
static void
xwl_glamor_gbm_cleanup(struct xwl_screen *xwl_screen)
{
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
if (xwl_gbm->device_name)
free(xwl_gbm->device_name);
if (xwl_gbm->drm_fd)
close(xwl_gbm->drm_fd);
if (xwl_gbm->drm)
wl_drm_destroy(xwl_gbm->drm);
if (xwl_gbm->gbm)
gbm_device_destroy(xwl_gbm->gbm);
free(xwl_gbm);
}
struct xwl_auth_state {
int fd;
ClientPtr client;
struct wl_callback *callback;
};
static void
free_xwl_auth_state(ClientPtr pClient, struct xwl_auth_state *state)
{
dixSetPrivate(&pClient->devPrivates, &xwl_auth_state_private_key, NULL);
if (state) {
wl_callback_destroy(state->callback);
free(state);
}
}
static void
xwl_auth_state_client_callback(CallbackListPtr *pcbl, void *unused, void *data)
{
NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
ClientPtr pClient = clientinfo->client;
struct xwl_auth_state *state;
switch (pClient->clientState) {
case ClientStateGone:
case ClientStateRetained:
state = dixLookupPrivate(&pClient->devPrivates,
&xwl_auth_state_private_key);
free_xwl_auth_state(pClient, state);
break;
default:
break;
}
}
static void
sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
{
struct xwl_auth_state *state = data;
ClientPtr client = state->client;
/* if the client is gone, the callback is cancelled so it's safe to
* assume the client is still in ClientStateRunning at this point...
*/
dri3_send_open_reply(client, state->fd);
AttendClient(client);
free_xwl_auth_state(client, state);
}
static const struct wl_callback_listener sync_listener = {
sync_callback
};
static int
xwl_dri3_open_client(ClientPtr client,
ScreenPtr screen,
RRProviderPtr provider,
int *pfd)
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
struct xwl_auth_state *state;
drm_magic_t magic;
int fd;
fd = open(xwl_gbm->device_name, O_RDWR | O_CLOEXEC);
if (fd < 0)
return BadAlloc;
if (xwl_gbm->fd_render_node) {
*pfd = fd;
return Success;
}
state = malloc(sizeof *state);
if (state == NULL) {
close(fd);
return BadAlloc;
}
state->client = client;
state->fd = fd;
if (drmGetMagic(state->fd, &magic) < 0) {
close(state->fd);
free(state);
return BadMatch;
}
wl_drm_authenticate(xwl_gbm->drm, magic);
state->callback = wl_display_sync(xwl_screen->display);
wl_callback_add_listener(state->callback, &sync_listener, state);
dixSetPrivate(&client->devPrivates, &xwl_auth_state_private_key, state);
IgnoreClient(client);
return Success;
}
_X_EXPORT PixmapPtr
glamor_pixmap_from_fds(ScreenPtr screen, CARD8 num_fds, const int *fds,
CARD16 width, CARD16 height,
const CARD32 *strides, const CARD32 *offsets,
CARD8 depth, CARD8 bpp, uint64_t modifier)
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
struct gbm_bo *bo = NULL;
PixmapPtr pixmap;
int i;
if (width == 0 || height == 0 || num_fds == 0 ||
depth < 15 || bpp != BitsPerPixel(depth) ||
strides[0] < width * bpp / 8)
goto error;
if (xwl_gbm->dmabuf_capable && modifier != DRM_FORMAT_MOD_INVALID) {
#ifdef GBM_BO_WITH_MODIFIERS
struct gbm_import_fd_modifier_data data;
data.width = width;
data.height = height;
data.num_fds = num_fds;
data.format = gbm_format_for_depth(depth);
data.modifier = modifier;
for (i = 0; i < num_fds; i++) {
data.fds[i] = fds[i];
data.strides[i] = strides[i];
data.offsets[i] = offsets[i];
}
bo = gbm_bo_import(xwl_gbm->gbm, GBM_BO_IMPORT_FD_MODIFIER, &data,
GBM_BO_USE_RENDERING);
#endif
} else if (num_fds == 1) {
struct gbm_import_fd_data data;
data.fd = fds[0];
data.width = width;
data.height = height;
data.stride = strides[0];
data.format = gbm_format_for_depth(depth);
bo = gbm_bo_import(xwl_gbm->gbm, GBM_BO_IMPORT_FD, &data,
GBM_BO_USE_RENDERING);
} else {
goto error;
}
if (bo == NULL)
goto error;
pixmap = xwl_glamor_gbm_create_pixmap_for_bo(screen, bo, depth);
if (pixmap == NULL) {
gbm_bo_destroy(bo);
goto error;
}
return pixmap;
error:
return NULL;
}
_X_EXPORT int
glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
uint32_t *strides, uint32_t *offsets,
uint64_t *modifier)
{
struct xwl_pixmap *xwl_pixmap;
#ifdef GBM_BO_WITH_MODIFIERS
uint32_t num_fds;
int i;
#endif
xwl_pixmap = xwl_pixmap_get(pixmap);
if (xwl_pixmap == NULL)
return 0;
if (!xwl_pixmap->bo)
return 0;
#ifdef GBM_BO_WITH_MODIFIERS
num_fds = gbm_bo_get_plane_count(xwl_pixmap->bo);
*modifier = gbm_bo_get_modifier(xwl_pixmap->bo);
for (i = 0; i < num_fds; i++) {
fds[i] = gbm_bo_get_fd(xwl_pixmap->bo);
strides[i] = gbm_bo_get_stride_for_plane(xwl_pixmap->bo, i);
offsets[i] = gbm_bo_get_offset(xwl_pixmap->bo, i);
}
return num_fds;
#else
*modifier = DRM_FORMAT_MOD_INVALID;
fds[0] = gbm_bo_get_fd(xwl_pixmap->bo);
strides[0] = gbm_bo_get_stride(xwl_pixmap->bo);
offsets[0] = 0;
return 1;
#endif
}
/* Not actually used, just defined here so there's something for
* _glamor_egl_fds_from_pixmap() to link against
*/
_X_EXPORT int
glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap,
CARD16 *stride, CARD32 *size)
{
return -1;
}
static const dri3_screen_info_rec xwl_dri3_info = {
.version = 2,
.open = NULL,
.pixmap_from_fds = glamor_pixmap_from_fds,
.fds_from_pixmap = glamor_fds_from_pixmap,
.open_client = xwl_dri3_open_client,
.get_formats = xwl_glamor_get_formats,
.get_modifiers = xwl_glamor_get_modifiers,
.get_drawable_modifiers = glamor_get_drawable_modifiers,
};
static const char *
get_render_node_path_for_device(const drmDevicePtr drm_device,
const char *device_path)
{
char *render_node_path = NULL;
char device_found = 0;
int i;
for (i = 0; i < DRM_NODE_MAX; i++) {
if ((drm_device->available_nodes & (1 << i)) == 0)
continue;
if (!strcmp (device_path, drm_device->nodes[i]))
device_found = 1;
if (is_device_path_render_node(drm_device->nodes[i]))
render_node_path = drm_device->nodes[i];
if (device_found && render_node_path)
return render_node_path;
}
return NULL;
}
static char *
get_render_node_path(const char *device_path)
{
drmDevicePtr *devices = NULL;
char *render_node_path = NULL;
int i, n_devices, max_devices;
max_devices = drmGetDevices2(0, NULL, 0);
if (max_devices <= 0)
goto out;
devices = calloc(max_devices, sizeof(drmDevicePtr));
if (!devices)
goto out;
n_devices = drmGetDevices2(0, devices, max_devices);
if (n_devices < 0)
goto out;
for (i = 0; i < n_devices; i++) {
const char *node_path = get_render_node_path_for_device(devices[i],
device_path);
if (node_path) {
render_node_path = strdup(node_path);
break;
}
}
out:
free(devices);
return render_node_path;
}
static void
xwl_drm_handle_device(void *data, struct wl_drm *drm, const char *device)
{
struct xwl_screen *xwl_screen = data;
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
drm_magic_t magic;
char *render_node_path = NULL;
if (!is_device_path_render_node(device))
render_node_path = get_render_node_path(device);
if (render_node_path)
xwl_gbm->device_name = render_node_path;
else
xwl_gbm->device_name = strdup(device);
if (!xwl_gbm->device_name) {
xwl_glamor_gbm_cleanup(xwl_screen);
return;
}
xwl_gbm->drm_fd = open(xwl_gbm->device_name, O_RDWR | O_CLOEXEC);
if (xwl_gbm->drm_fd == -1) {
ErrorF("wayland-egl: could not open %s (%s)\n",
xwl_gbm->device_name, strerror(errno));
xwl_glamor_gbm_cleanup(xwl_screen);
return;
}
if (drmGetNodeTypeFromFd(xwl_gbm->drm_fd) == DRM_NODE_RENDER) {
xwl_gbm->fd_render_node = 1;
xwl_screen->expecting_event--;
} else {
drmGetMagic(xwl_gbm->drm_fd, &magic);
wl_drm_authenticate(xwl_gbm->drm, magic);
}
}
static void
xwl_drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
{
}
static void
xwl_drm_handle_authenticated(void *data, struct wl_drm *drm)
{
struct xwl_screen *xwl_screen = data;
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
xwl_gbm->drm_authenticated = TRUE;
xwl_screen->expecting_event--;
}
static void
xwl_drm_handle_capabilities(void *data, struct wl_drm *drm, uint32_t value)
{
xwl_gbm_get(data)->capabilities = value;
}
static const struct wl_drm_listener xwl_drm_listener = {
xwl_drm_handle_device,
xwl_drm_handle_format,
xwl_drm_handle_authenticated,
xwl_drm_handle_capabilities
};
Bool
xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
uint32_t id, uint32_t version)
{
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
if (version < 2)
return FALSE;
xwl_gbm->drm =
wl_registry_bind(xwl_screen->registry, id, &wl_drm_interface, 2);
wl_drm_add_listener(xwl_gbm->drm, &xwl_drm_listener, xwl_screen);
xwl_screen->expecting_event++;
return TRUE;
}
static Bool
xwl_glamor_gbm_init_wl_registry(struct xwl_screen *xwl_screen,
struct wl_registry *wl_registry,
uint32_t id, const char *name,
uint32_t version)
{
if (strcmp(name, "wl_drm") == 0) {
xwl_screen_set_drm_interface(xwl_screen, id, version);
return TRUE;
} else if (strcmp(name, "zwp_linux_dmabuf_v1") == 0) {
xwl_screen_set_dmabuf_interface(xwl_screen, id, version);
return TRUE;
}
/* no match */
return FALSE;
}
static Bool
xwl_glamor_gbm_has_egl_extension(void)
{
return (epoxy_has_egl_extension(NULL, "EGL_MESA_platform_gbm") ||
epoxy_has_egl_extension(NULL, "EGL_KHR_platform_gbm"));
}
static Bool
xwl_glamor_gbm_has_wl_interfaces(struct xwl_screen *xwl_screen)
{
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
if (xwl_gbm->drm == NULL) {
ErrorF("glamor: 'wl_drm' not supported\n");
return FALSE;
}
return TRUE;
}
static Bool
xwl_glamor_try_to_make_context_current(struct xwl_screen *xwl_screen)
{
if (xwl_screen->egl_context == EGL_NO_CONTEXT)
return FALSE;
return eglMakeCurrent(xwl_screen->egl_display, EGL_NO_SURFACE,
EGL_NO_SURFACE, xwl_screen->egl_context);
}
static void
xwl_glamor_maybe_destroy_context(struct xwl_screen *xwl_screen)
{
if (xwl_screen->egl_context == EGL_NO_CONTEXT)
return;
eglMakeCurrent(xwl_screen->egl_display, EGL_NO_SURFACE,
EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(xwl_screen->egl_display, xwl_screen->egl_context);
xwl_screen->egl_context = EGL_NO_CONTEXT;
}
static Bool
xwl_glamor_try_big_gl_api(struct xwl_screen *xwl_screen)
{
static const EGLint config_attribs_core[] = {
EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR,
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR,
EGL_CONTEXT_MAJOR_VERSION_KHR,
GLAMOR_GL_CORE_VER_MAJOR,
EGL_CONTEXT_MINOR_VERSION_KHR,
GLAMOR_GL_CORE_VER_MINOR,
EGL_NONE
};
int gl_version;
eglBindAPI(EGL_OPENGL_API);
xwl_screen->egl_context =
eglCreateContext(xwl_screen->egl_display, NULL,
EGL_NO_CONTEXT, config_attribs_core);
if (xwl_screen->egl_context == EGL_NO_CONTEXT)
xwl_screen->egl_context =
eglCreateContext(xwl_screen->egl_display, NULL,
EGL_NO_CONTEXT, NULL);
if (!xwl_glamor_try_to_make_context_current(xwl_screen)) {
ErrorF("Failed to make EGL context current with GL\n");
xwl_glamor_maybe_destroy_context(xwl_screen);
return FALSE;
}
/* glamor needs at least GL 2.1, if the GL version is less than 2.1,
* drop the context we created, it's useless.
*/
gl_version = epoxy_gl_version();
if (gl_version < 21) {
ErrorF("Supported GL version is not sufficient (required 21, found %i)\n",
gl_version);
xwl_glamor_maybe_destroy_context(xwl_screen);
return FALSE;
}
return TRUE;
}
static Bool
xwl_glamor_try_gles_api(struct xwl_screen *xwl_screen)
{
const EGLint gles_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION,
2,
EGL_NONE,
};
eglBindAPI(EGL_OPENGL_ES_API);
xwl_screen->egl_context = eglCreateContext(xwl_screen->egl_display, NULL,
EGL_NO_CONTEXT, gles_attribs);
if (!xwl_glamor_try_to_make_context_current(xwl_screen)) {
ErrorF("Failed to make EGL context current with GLES2\n");
xwl_glamor_maybe_destroy_context(xwl_screen);
return FALSE;
}
return TRUE;
}
static Bool
xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen)
{
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
EGLint major, minor;
const GLubyte *renderer;
if (!xwl_gbm->fd_render_node && !xwl_gbm->drm_authenticated) {
ErrorF("Failed to get wl_drm, disabling Glamor and DRI3\n");
return FALSE;
}
xwl_gbm->gbm = gbm_create_device(xwl_gbm->drm_fd);
if (!xwl_gbm->gbm) {
ErrorF("couldn't create gbm device\n");
goto error;
}
xwl_screen->egl_display = glamor_egl_get_display(EGL_PLATFORM_GBM_MESA,
xwl_gbm->gbm);
if (xwl_screen->egl_display == EGL_NO_DISPLAY) {
ErrorF("glamor_egl_get_display() failed\n");
goto error;
}
if (!eglInitialize(xwl_screen->egl_display, &major, &minor)) {
ErrorF("eglInitialize() failed\n");
goto error;
}
if (!xwl_glamor_try_big_gl_api(xwl_screen) &&
!xwl_glamor_try_gles_api(xwl_screen)) {
ErrorF("Cannot use neither GL nor GLES2\n");
goto error;
}
renderer = glGetString(GL_RENDERER);
if (!renderer) {
ErrorF("glGetString() returned NULL, your GL is broken\n");
goto error;
}
if (strstr((const char *)renderer, "llvmpipe")) {
ErrorF("Refusing to try glamor on llvmpipe\n");
goto error;
}
if (!epoxy_has_gl_extension("GL_OES_EGL_image")) {
ErrorF("GL_OES_EGL_image not available\n");
goto error;
}
if (epoxy_has_egl_extension(xwl_screen->egl_display,
"EXT_image_dma_buf_import") &&
epoxy_has_egl_extension(xwl_screen->egl_display,
"EXT_image_dma_buf_import_modifiers"))
xwl_gbm->dmabuf_capable = TRUE;
return TRUE;
error:
if (xwl_screen->egl_display != EGL_NO_DISPLAY) {
xwl_glamor_maybe_destroy_context(xwl_screen);
eglTerminate(xwl_screen->egl_display);
xwl_screen->egl_display = EGL_NO_DISPLAY;
}
xwl_glamor_gbm_cleanup(xwl_screen);
return FALSE;
}
static Bool
xwl_glamor_gbm_init_screen(struct xwl_screen *xwl_screen)
{
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
if (!dri3_screen_init(xwl_screen->screen, &xwl_dri3_info)) {
ErrorF("Failed to initialize dri3\n");
goto error;
}
if (xwl_gbm->fd_render_node)
goto skip_drm_auth;
if (!dixRegisterPrivateKey(&xwl_auth_state_private_key, PRIVATE_CLIENT,
0)) {
ErrorF("Failed to register private key\n");
goto error;
}
if (!AddCallback(&ClientStateCallback, xwl_auth_state_client_callback,
NULL)) {
ErrorF("Failed to add client state callback\n");
goto error;
}
skip_drm_auth:
xwl_screen->screen->CreatePixmap = xwl_glamor_gbm_create_pixmap;
xwl_screen->screen->DestroyPixmap = xwl_glamor_gbm_destroy_pixmap;
return TRUE;
error:
xwl_glamor_gbm_cleanup(xwl_screen);
return FALSE;
}
void
xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
{
struct xwl_gbm_private *xwl_gbm;
xwl_screen->gbm_backend.is_available = FALSE;
if (!xwl_glamor_gbm_has_egl_extension())
return;
if (!dixRegisterPrivateKey(&xwl_gbm_private_key, PRIVATE_SCREEN, 0))
return;
xwl_gbm = calloc(sizeof(*xwl_gbm), 1);
if (!xwl_gbm) {
ErrorF("glamor: Not enough memory to setup GBM, disabling\n");
return;
}
dixSetPrivate(&xwl_screen->screen->devPrivates, &xwl_gbm_private_key,
xwl_gbm);
xwl_screen->gbm_backend.init_wl_registry = xwl_glamor_gbm_init_wl_registry;
xwl_screen->gbm_backend.has_wl_interfaces = xwl_glamor_gbm_has_wl_interfaces;
xwl_screen->gbm_backend.init_egl = xwl_glamor_gbm_init_egl;
xwl_screen->gbm_backend.init_screen = xwl_glamor_gbm_init_screen;
xwl_screen->gbm_backend.get_wl_buffer_for_pixmap = xwl_glamor_gbm_get_wl_buffer_for_pixmap;
xwl_screen->gbm_backend.check_flip = NULL;
xwl_screen->gbm_backend.is_available = TRUE;
xwl_screen->gbm_backend.backend_flags = XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH |
XWL_EGL_BACKEND_NEEDS_N_BUFFERING;
}

View File

@ -1,415 +0,0 @@
/*
* Copyright (c) 1998-2003 by The XFree86 Project, Inc.
* Copyright © 2013 Red Hat
* Copyright © 2014 Intel Corporation
* Copyright © 2016 Red Hat
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* Authors:
* Olivier Fourdan <ofourdan@redhat.com>
*
* Derived from the glamor_xf86_xv, ephyr_glamor_xv and xf86xv
* implementations
*/
#include <xwayland-config.h>
#include "glamor_priv.h"
#include <X11/extensions/Xv.h>
#include "xwayland-glamor.h"
#define NUM_FORMATS 3
#define NUM_PORTS 16
#define ADAPTOR_NAME "glamor textured video"
#define ENCODER_NAME "XV_IMAGE"
static DevPrivateKeyRec xwlXvScreenPrivateKeyRec;
#define xwlXvScreenPrivateKey (&xwlXvScreenPrivateKeyRec)
typedef struct {
XvAdaptorPtr glxv_adaptor; /* We have only one adaptor, glamor Xv */
glamor_port_private *port_privates;
CloseScreenProcPtr CloseScreen;
} xwlXvScreenRec, *xwlXvScreenPtr;
typedef struct {
char depth;
short class;
} xwlVideoFormatRec, *xwlVideoFormatPtr;
static xwlVideoFormatRec Formats[NUM_FORMATS] = {
{15, TrueColor},
{16, TrueColor},
{24, TrueColor}
};
static int
xwl_glamor_xv_stop_video(XvPortPtr pPort,
DrawablePtr pDraw)
{
glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr);
if (pDraw->type != DRAWABLE_WINDOW)
return BadAlloc;
glamor_xv_stop_video(gpp);
return Success;
}
static int
xwl_glamor_xv_set_port_attribute(XvPortPtr pPort,
Atom attribute,
INT32 value)
{
glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr);
return glamor_xv_set_port_attribute(gpp, attribute, value);
}
static int
xwl_glamor_xv_get_port_attribute(XvPortPtr pPort,
Atom attribute,
INT32 *pValue)
{
glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr);
return glamor_xv_get_port_attribute(gpp, attribute, pValue);
}
static int
xwl_glamor_xv_query_best_size(XvPortPtr pPort,
CARD8 motion,
CARD16 vid_w,
CARD16 vid_h,
CARD16 drw_w,
CARD16 drw_h,
unsigned int *p_w,
unsigned int *p_h)
{
*p_w = drw_w;
*p_h = drw_h;
return Success;
}
static int
xwl_glamor_xv_query_image_attributes(XvPortPtr pPort,
XvImagePtr format,
CARD16 *width,
CARD16 *height,
int *pitches,
int *offsets)
{
return glamor_xv_query_image_attributes(format->id,
width,
height,
pitches,
offsets);
}
static int
xwl_glamor_xv_put_image(DrawablePtr pDrawable,
XvPortPtr pPort,
GCPtr pGC,
INT16 src_x,
INT16 src_y,
CARD16 src_w,
CARD16 src_h,
INT16 drw_x,
INT16 drw_y,
CARD16 drw_w,
CARD16 drw_h,
XvImagePtr format,
unsigned char *data,
Bool sync,
CARD16 width,
CARD16 height)
{
glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr);
RegionRec WinRegion;
RegionRec ClipRegion;
BoxRec WinBox;
int ret = Success;
if (pDrawable->type != DRAWABLE_WINDOW)
return BadWindow;
WinBox.x1 = pDrawable->x + drw_x;
WinBox.y1 = pDrawable->y + drw_y;
WinBox.x2 = WinBox.x1 + drw_w;
WinBox.y2 = WinBox.y1 + drw_h;
RegionInit(&WinRegion, &WinBox, 1);
RegionInit(&ClipRegion, NullBox, 1);
RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
if (RegionNotEmpty(&ClipRegion))
ret = glamor_xv_put_image(gpp,
pDrawable,
src_x,
src_y,
pDrawable->x + drw_x,
pDrawable->y + drw_y,
src_w,
src_h,
drw_w,
drw_h,
format->id,
data,
width,
height,
sync,
&ClipRegion);
RegionUninit(&WinRegion);
RegionUninit(&ClipRegion);
return ret;
}
static Bool
xwl_glamor_xv_add_formats(XvAdaptorPtr pa)
{
ScreenPtr pScreen;
XvFormatPtr pFormat, pf;
VisualPtr pVisual;
int numFormat;
int totFormat;
int numVisuals;
int i;
totFormat = NUM_FORMATS;
pFormat = xnfcalloc(totFormat, sizeof(XvFormatRec));
pScreen = pa->pScreen;
for (pf = pFormat, i = 0, numFormat = 0; i < NUM_FORMATS; i++) {
numVisuals = pScreen->numVisuals;
pVisual = pScreen->visuals;
while (numVisuals--) {
if ((pVisual->class == Formats[i].class) &&
(pVisual->nplanes == Formats[i].depth)) {
if (numFormat >= totFormat) {
void *moreSpace;
totFormat *= 2;
moreSpace = xnfreallocarray(pFormat, totFormat,
sizeof(XvFormatRec));
pFormat = moreSpace;
pf = pFormat + numFormat;
}
pf->visual = pVisual->vid;
pf->depth = Formats[i].depth;
pf++;
numFormat++;
}
pVisual++;
}
}
pa->nFormats = numFormat;
pa->pFormats = pFormat;
return numFormat != 0;
}
static Bool
xwl_glamor_xv_add_ports(XvAdaptorPtr pa)
{
XvPortPtr pPorts, pp;
xwlXvScreenPtr xwlXvScreen;
unsigned long PortResource = 0;
int nPorts;
int i;
pPorts = xnfcalloc(NUM_PORTS, sizeof(XvPortRec));
xwlXvScreen = dixLookupPrivate(&(pa->pScreen)->devPrivates,
xwlXvScreenPrivateKey);
xwlXvScreen->port_privates = xnfcalloc(NUM_PORTS,
sizeof(glamor_port_private));
PortResource = XvGetRTPort();
for (pp = pPorts, i = 0, nPorts = 0; i < NUM_PORTS; i++) {
if (!(pp->id = FakeClientID(0)))
continue;
pp->pAdaptor = pa;
glamor_xv_init_port(&xwlXvScreen->port_privates[i]);
pp->devPriv.ptr = &xwlXvScreen->port_privates[i];
if (AddResource(pp->id, PortResource, pp)) {
pp++;
nPorts++;
}
}
pa->base_id = pPorts->id;
pa->nPorts = nPorts;
pa->pPorts = pPorts;
return nPorts != 0;
}
static void
xwl_glamor_xv_add_attributes(XvAdaptorPtr pa)
{
int i;
pa->pAttributes = xnfcalloc(glamor_xv_num_attributes, sizeof(XvAttributeRec));
memcpy(pa->pAttributes, glamor_xv_attributes,
glamor_xv_num_attributes * sizeof(XvAttributeRec));
for (i = 0; i < glamor_xv_num_attributes; i++)
pa->pAttributes[i].name = strdup(glamor_xv_attributes[i].name);
pa->nAttributes = glamor_xv_num_attributes;
}
static void
xwl_glamor_xv_add_images(XvAdaptorPtr pa)
{
pa->pImages = xnfcalloc(glamor_xv_num_images, sizeof(XvImageRec));
memcpy(pa->pImages, glamor_xv_images, glamor_xv_num_images * sizeof(XvImageRec));
pa->nImages = glamor_xv_num_images;
}
static void
xwl_glamor_xv_add_encodings(XvAdaptorPtr pa)
{
XvEncodingPtr pe;
GLint texsize;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texsize);
pe = xnfcalloc(1, sizeof(XvEncodingRec));
pe->id = 0;
pe->pScreen = pa->pScreen;
pe->name = strdup(ENCODER_NAME);
pe->width = texsize;
pe->height = texsize;
pe->rate.numerator = 1;
pe->rate.denominator = 1;
pa->pEncodings = pe;
pa->nEncodings = 1;
}
static Bool
xwl_glamor_xv_add_adaptors(ScreenPtr pScreen)
{
DevPrivateKey XvScreenKey;
XvScreenPtr XvScreen;
xwlXvScreenPtr xwlXvScreen;
XvAdaptorPtr pa;
if (XvScreenInit(pScreen) != Success)
return FALSE;
XvScreenKey = XvGetScreenKey();
XvScreen = dixLookupPrivate(&(pScreen)->devPrivates, XvScreenKey);
XvScreen->nAdaptors = 0;
XvScreen->pAdaptors = NULL;
pa = xnfcalloc(1, sizeof(XvAdaptorRec));
pa->pScreen = pScreen;
pa->type = (unsigned char) (XvInputMask | XvImageMask);
pa->ddStopVideo = xwl_glamor_xv_stop_video;
pa->ddPutImage = xwl_glamor_xv_put_image;
pa->ddSetPortAttribute = xwl_glamor_xv_set_port_attribute;
pa->ddGetPortAttribute = xwl_glamor_xv_get_port_attribute;
pa->ddQueryBestSize = xwl_glamor_xv_query_best_size;
pa->ddQueryImageAttributes = xwl_glamor_xv_query_image_attributes;
pa->name = strdup(ADAPTOR_NAME);
xwl_glamor_xv_add_encodings(pa);
xwl_glamor_xv_add_images(pa);
xwl_glamor_xv_add_attributes(pa);
if (!xwl_glamor_xv_add_formats(pa))
goto failed;
if (!xwl_glamor_xv_add_ports(pa))
goto failed;
/* We're good now with out Xv adaptor */
XvScreen->nAdaptors = 1;
XvScreen->pAdaptors = pa;
xwlXvScreen = dixLookupPrivate(&(pa->pScreen)->devPrivates,
xwlXvScreenPrivateKey);
xwlXvScreen->glxv_adaptor = pa;
return TRUE;
failed:
XvFreeAdaptor(pa);
free(pa);
return FALSE;
}
static Bool
xwl_glamor_xv_close_screen(ScreenPtr pScreen)
{
xwlXvScreenPtr xwlXvScreen;
xwlXvScreen = dixLookupPrivate(&(pScreen)->devPrivates,
xwlXvScreenPrivateKey);
if (xwlXvScreen->glxv_adaptor) {
XvFreeAdaptor(xwlXvScreen->glxv_adaptor);
free(xwlXvScreen->glxv_adaptor);
}
free(xwlXvScreen->port_privates);
pScreen->CloseScreen = xwlXvScreen->CloseScreen;
return pScreen->CloseScreen(pScreen);
}
Bool
xwl_glamor_xv_init(ScreenPtr pScreen)
{
xwlXvScreenPtr xwlXvScreen;
if (!dixRegisterPrivateKey(xwlXvScreenPrivateKey, PRIVATE_SCREEN,
sizeof(xwlXvScreenRec)))
return FALSE;
xwlXvScreen = dixLookupPrivate(&(pScreen)->devPrivates,
xwlXvScreenPrivateKey);
xwlXvScreen->port_privates = NULL;
xwlXvScreen->glxv_adaptor = NULL;
xwlXvScreen->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = xwl_glamor_xv_close_screen;
glamor_xv_core_init(pScreen);
return xwl_glamor_xv_add_adaptors(pScreen);
}

View File

@ -1,491 +0,0 @@
/*
* Copyright © 2011-2014 Intel Corporation
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the
* copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#include <xwayland-config.h>
#define MESA_EGL_NO_X11_HEADERS
#define EGL_NO_X11
#include <glamor_egl.h>
#include <glamor.h>
#include <glamor_context.h>
#ifdef GLXEXT
#include "glx_extinit.h"
#endif
#include "linux-dmabuf-unstable-v1-client-protocol.h"
#include "drm-client-protocol.h"
#include <drm_fourcc.h>
#include "xwayland-glamor.h"
#include "xwayland-glx.h"
#include "xwayland-screen.h"
#include "xwayland-window.h"
static void
glamor_egl_make_current(struct glamor_context *glamor_ctx)
{
eglMakeCurrent(glamor_ctx->display, EGL_NO_SURFACE,
EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (!eglMakeCurrent(glamor_ctx->display,
EGL_NO_SURFACE, EGL_NO_SURFACE,
glamor_ctx->ctx))
FatalError("Failed to make EGL context current\n");
}
void
xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen)
{
if (lastGLContext == xwl_screen->glamor_ctx)
return;
lastGLContext = xwl_screen->glamor_ctx;
xwl_screen->glamor_ctx->make_current(xwl_screen->glamor_ctx);
}
void
glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
glamor_enable_dri3(screen);
glamor_ctx->ctx = xwl_screen->egl_context;
glamor_ctx->display = xwl_screen->egl_display;
glamor_ctx->make_current = glamor_egl_make_current;
xwl_screen->glamor_ctx = glamor_ctx;
}
Bool
xwl_glamor_check_flip(PixmapPtr pixmap)
{
struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
if (!xwl_glamor_pixmap_get_wl_buffer(pixmap))
return FALSE;
if (xwl_screen->egl_backend->check_flip)
return xwl_screen->egl_backend->check_flip(pixmap);
return TRUE;
}
Bool
xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen,
uint32_t format, uint64_t modifier)
{
struct xwl_format *xwl_format = NULL;
int i;
for (i = 0; i < xwl_screen->num_formats; i++) {
if (xwl_screen->formats[i].format == format) {
xwl_format = &xwl_screen->formats[i];
break;
}
}
if (xwl_format) {
for (i = 0; i < xwl_format->num_modifiers; i++) {
if (xwl_format->modifiers[i] == modifier) {
return TRUE;
}
}
}
return FALSE;
}
uint32_t
wl_drm_format_for_depth(int depth)
{
switch (depth) {
case 15:
return WL_DRM_FORMAT_XRGB1555;
case 16:
return WL_DRM_FORMAT_RGB565;
case 24:
return WL_DRM_FORMAT_XRGB8888;
case 30:
return WL_DRM_FORMAT_ARGB2101010;
default:
ErrorF("unexpected depth: %d\n", depth);
case 32:
return WL_DRM_FORMAT_ARGB8888;
}
}
Bool
xwl_glamor_get_formats(ScreenPtr screen,
CARD32 *num_formats, CARD32 **formats)
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
int i;
/* Explicitly zero the count as the caller may ignore the return value */
*num_formats = 0;
if (!xwl_screen->dmabuf)
return FALSE;
if (xwl_screen->num_formats == 0)
return TRUE;
*formats = calloc(xwl_screen->num_formats, sizeof(CARD32));
if (*formats == NULL)
return FALSE;
for (i = 0; i < xwl_screen->num_formats; i++)
(*formats)[i] = xwl_screen->formats[i].format;
*num_formats = xwl_screen->num_formats;
return TRUE;
}
Bool
xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
uint32_t *num_modifiers, uint64_t **modifiers)
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
struct xwl_format *xwl_format = NULL;
int i;
/* Explicitly zero the count as the caller may ignore the return value */
*num_modifiers = 0;
if (!xwl_screen->dmabuf)
return FALSE;
if (xwl_screen->num_formats == 0)
return TRUE;
for (i = 0; i < xwl_screen->num_formats; i++) {
if (xwl_screen->formats[i].format == format) {
xwl_format = &xwl_screen->formats[i];
break;
}
}
if (!xwl_format ||
(xwl_format->num_modifiers == 1 &&
xwl_format->modifiers[0] == DRM_FORMAT_MOD_INVALID))
return FALSE;
*modifiers = calloc(xwl_format->num_modifiers, sizeof(uint64_t));
if (*modifiers == NULL)
return FALSE;
for (i = 0; i < xwl_format->num_modifiers; i++)
(*modifiers)[i] = xwl_format->modifiers[i];
*num_modifiers = xwl_format->num_modifiers;
return TRUE;
}
static void
xwl_dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
uint32_t format)
{
}
static void
xwl_dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
uint32_t format, uint32_t modifier_hi,
uint32_t modifier_lo)
{
struct xwl_screen *xwl_screen = data;
struct xwl_format *xwl_format = NULL;
int i;
for (i = 0; i < xwl_screen->num_formats; i++) {
if (xwl_screen->formats[i].format == format) {
xwl_format = &xwl_screen->formats[i];
break;
}
}
if (xwl_format == NULL) {
xwl_screen->num_formats++;
xwl_screen->formats = realloc(xwl_screen->formats,
xwl_screen->num_formats * sizeof(*xwl_format));
if (!xwl_screen->formats)
return;
xwl_format = &xwl_screen->formats[xwl_screen->num_formats - 1];
xwl_format->format = format;
xwl_format->num_modifiers = 0;
xwl_format->modifiers = NULL;
}
xwl_format->num_modifiers++;
xwl_format->modifiers = realloc(xwl_format->modifiers,
xwl_format->num_modifiers * sizeof(uint64_t));
if (!xwl_format->modifiers)
return;
xwl_format->modifiers[xwl_format->num_modifiers - 1] = (uint64_t) modifier_lo;
xwl_format->modifiers[xwl_format->num_modifiers - 1] |= (uint64_t) modifier_hi << 32;
}
static const struct zwp_linux_dmabuf_v1_listener xwl_dmabuf_listener = {
.format = xwl_dmabuf_handle_format,
.modifier = xwl_dmabuf_handle_modifier
};
Bool
xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
uint32_t id, uint32_t version)
{
if (version < 3)
return FALSE;
xwl_screen->dmabuf =
wl_registry_bind(xwl_screen->registry, id, &zwp_linux_dmabuf_v1_interface, 3);
zwp_linux_dmabuf_v1_add_listener(xwl_screen->dmabuf, &xwl_dmabuf_listener, xwl_screen);
return TRUE;
}
void
xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
struct wl_registry *registry,
uint32_t id, const char *interface,
uint32_t version)
{
if (xwl_screen->gbm_backend.is_available &&
xwl_screen->gbm_backend.init_wl_registry(xwl_screen,
registry,
id,
interface,
version)) {
/* no-op */
} else if (xwl_screen->eglstream_backend.is_available &&
xwl_screen->eglstream_backend.init_wl_registry(xwl_screen,
registry,
id,
interface,
version)) {
/* no-op */
}
}
Bool
xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen,
struct xwl_egl_backend *xwl_egl_backend)
{
return xwl_egl_backend->has_wl_interfaces(xwl_screen);
}
struct wl_buffer *
xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap)
{
struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
if (xwl_screen->egl_backend->get_wl_buffer_for_pixmap)
return xwl_screen->egl_backend->get_wl_buffer_for_pixmap(pixmap);
return NULL;
}
Bool
xwl_glamor_post_damage(struct xwl_window *xwl_window,
PixmapPtr pixmap, RegionPtr region)
{
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
if (xwl_screen->egl_backend->post_damage)
return xwl_screen->egl_backend->post_damage(xwl_window, pixmap, region);
return TRUE;
}
Bool
xwl_glamor_allow_commits(struct xwl_window *xwl_window)
{
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
if (xwl_screen->egl_backend->allow_commits)
return xwl_screen->egl_backend->allow_commits(xwl_window);
else
return TRUE;
}
static Bool
xwl_glamor_create_screen_resources(ScreenPtr screen)
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
int ret;
screen->CreateScreenResources = xwl_screen->CreateScreenResources;
ret = (*screen->CreateScreenResources) (screen);
xwl_screen->CreateScreenResources = screen->CreateScreenResources;
screen->CreateScreenResources = xwl_glamor_create_screen_resources;
if (!ret)
return ret;
if (xwl_screen->rootless) {
screen->devPrivate =
fbCreatePixmap(screen, 0, 0, screen->rootDepth, 0);
}
else {
screen->devPrivate = screen->CreatePixmap(
screen, screen->width, screen->height, screen->rootDepth,
CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
}
SetRootClip(screen, xwl_screen->root_clip_mode);
return screen->devPrivate != NULL;
}
int
glamor_egl_fd_name_from_pixmap(ScreenPtr screen,
PixmapPtr pixmap,
CARD16 *stride, CARD32 *size)
{
return 0;
}
Bool
xwl_glamor_needs_buffer_flush(struct xwl_screen *xwl_screen)
{
if (!xwl_screen->glamor || !xwl_screen->egl_backend)
return FALSE;
return (xwl_screen->egl_backend->backend_flags &
XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH);
}
Bool
xwl_glamor_needs_n_buffering(struct xwl_screen *xwl_screen)
{
/* wl_shm benefits from n-buffering */
if (!xwl_screen->glamor || !xwl_screen->egl_backend)
return TRUE;
return (xwl_screen->egl_backend->backend_flags &
XWL_EGL_BACKEND_NEEDS_N_BUFFERING);
}
void
xwl_glamor_init_backends(struct xwl_screen *xwl_screen, Bool use_eglstream)
{
#ifdef GLAMOR_HAS_GBM
xwl_glamor_init_gbm(xwl_screen);
if (!xwl_screen->gbm_backend.is_available && !use_eglstream)
ErrorF("xwayland glamor: GBM backend (default) is not available\n");
#endif
#ifdef XWL_HAS_EGLSTREAM
xwl_glamor_init_eglstream(xwl_screen);
if (!xwl_screen->eglstream_backend.is_available && use_eglstream)
ErrorF("xwayland glamor: EGLStream backend requested but not available\n");
#endif
}
static Bool
xwl_glamor_select_gbm_backend(struct xwl_screen *xwl_screen)
{
#ifdef GLAMOR_HAS_GBM
if (xwl_screen->gbm_backend.is_available &&
xwl_glamor_has_wl_interfaces(xwl_screen, &xwl_screen->gbm_backend)) {
xwl_screen->egl_backend = &xwl_screen->gbm_backend;
return TRUE;
}
else
ErrorF("Missing Wayland requirements for glamor GBM backend\n");
#endif
return FALSE;
}
static Bool
xwl_glamor_select_eglstream_backend(struct xwl_screen *xwl_screen)
{
#ifdef XWL_HAS_EGLSTREAM
if (xwl_screen->eglstream_backend.is_available &&
xwl_glamor_has_wl_interfaces(xwl_screen, &xwl_screen->eglstream_backend)) {
xwl_screen->egl_backend = &xwl_screen->eglstream_backend;
return TRUE;
}
else
ErrorF("Missing Wayland requirements for glamor EGLStream backend\n");
#endif
return FALSE;
}
void
xwl_glamor_select_backend(struct xwl_screen *xwl_screen, Bool use_eglstream)
{
if (use_eglstream) {
if (!xwl_glamor_select_eglstream_backend(xwl_screen))
xwl_glamor_select_gbm_backend(xwl_screen);
}
else {
if (!xwl_glamor_select_gbm_backend(xwl_screen))
xwl_glamor_select_eglstream_backend(xwl_screen);
}
}
Bool
xwl_glamor_init(struct xwl_screen *xwl_screen)
{
ScreenPtr screen = xwl_screen->screen;
const char *no_glamor_env;
no_glamor_env = getenv("XWAYLAND_NO_GLAMOR");
if (no_glamor_env && *no_glamor_env != '0') {
ErrorF("Disabling glamor and dri3 support, XWAYLAND_NO_GLAMOR is set\n");
return FALSE;
}
if (!xwl_screen->egl_backend->init_egl(xwl_screen)) {
ErrorF("EGL setup failed, disabling glamor\n");
return FALSE;
}
if (!glamor_init(xwl_screen->screen, GLAMOR_USE_EGL_SCREEN)) {
ErrorF("Failed to initialize glamor\n");
return FALSE;
}
if (!xwl_screen->egl_backend->init_screen(xwl_screen)) {
ErrorF("EGL backend init_screen() failed, disabling glamor\n");
return FALSE;
}
xwl_screen->CreateScreenResources = screen->CreateScreenResources;
screen->CreateScreenResources = xwl_glamor_create_screen_resources;
#ifdef XV
if (!xwl_glamor_xv_init(screen))
ErrorF("Failed to initialize glamor Xv extension\n");
#endif
#ifdef GLXEXT
GlxPushProvider(&glamor_provider);
#endif
return TRUE;
}

View File

@ -1,158 +0,0 @@
/*
* Copyright © 2011-2014 Intel Corporation
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the
* copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#ifndef XWAYLAND_GLAMOR_H
#define XWAYLAND_GLAMOR_H
#include <xwayland-config.h>
#include <wayland-client.h>
#include "xwayland-types.h"
typedef enum _xwl_egl_backend_flags {
XWL_EGL_BACKEND_NO_FLAG = 0,
XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH = (1 << 0),
XWL_EGL_BACKEND_NEEDS_N_BUFFERING = (1 << 1),
} xwl_egl_backend_flags;
struct xwl_egl_backend {
/* Set by the backend if available */
Bool is_available;
/* Features and requirements set by the backend */
xwl_egl_backend_flags backend_flags;
/* Called once for each interface in the global registry. Backends
* should use this to bind to any wayland interfaces they need.
*/
Bool (*init_wl_registry)(struct xwl_screen *xwl_screen,
struct wl_registry *wl_registry,
uint32_t id, const char *name,
uint32_t version);
/* Check that the required Wayland interfaces are available.
*/
Bool (*has_wl_interfaces)(struct xwl_screen *xwl_screen);
/* Called before glamor has been initialized. Backends should setup a
* valid, glamor compatible EGL context in this hook.
*/
Bool (*init_egl)(struct xwl_screen *xwl_screen);
/* Called after glamor has been initialized, and after all of the
* common Xwayland DDX hooks have been connected. Backends should use
* this to setup any required wraps around X server callbacks like
* CreatePixmap.
*/
Bool (*init_screen)(struct xwl_screen *xwl_screen);
/* Called by Xwayland to retrieve a pointer to a valid wl_buffer for
* the given window/pixmap combo so that damage to the pixmap may be
* displayed on-screen. Backends should use this to create a new
* wl_buffer for a currently buffer-less pixmap, or simply return the
* pixmap they've prepared beforehand.
*/
struct wl_buffer *(*get_wl_buffer_for_pixmap)(PixmapPtr pixmap);
/* Called by Xwayland to perform any pre-wl_surface damage routines
* that are required by the backend. If your backend is poorly
* designed and lacks the ability to render directly to a surface,
* you should implement blitting from the glamor pixmap to the wayland
* pixmap here. Otherwise, this callback is optional.
*/
Bool (*post_damage)(struct xwl_window *xwl_window,
PixmapPtr pixmap, RegionPtr region);
/* Called by Xwayland to confirm with the egl backend that the given
* pixmap is completely setup and ready for display on-screen. This
* callback is optional.
*/
Bool (*allow_commits)(struct xwl_window *xwl_window);
/* Called by Xwayland to check whether the given pixmap can be
* presented by xwl_present_flip. If not implemented, assumed TRUE.
*/
Bool (*check_flip)(PixmapPtr pixmap);
};
#ifdef XWL_HAS_GLAMOR
void xwl_glamor_init_backends(struct xwl_screen *xwl_screen,
Bool use_eglstream);
void xwl_glamor_select_backend(struct xwl_screen *xwl_screen,
Bool use_eglstream);
Bool xwl_glamor_init(struct xwl_screen *xwl_screen);
Bool xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
uint32_t id, uint32_t version);
Bool xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
uint32_t id, uint32_t version);
struct wl_buffer *xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap);
void xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
struct wl_registry *registry,
uint32_t id, const char *interface,
uint32_t version);
Bool xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen,
struct xwl_egl_backend *xwl_egl_backend);
Bool xwl_glamor_post_damage(struct xwl_window *xwl_window,
PixmapPtr pixmap, RegionPtr region);
Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window);
void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
Bool xwl_glamor_needs_buffer_flush(struct xwl_screen *xwl_screen);
Bool xwl_glamor_needs_n_buffering(struct xwl_screen *xwl_screen);
Bool xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen,
uint32_t format, uint64_t modifier);
uint32_t wl_drm_format_for_depth(int depth);
Bool xwl_glamor_get_formats(ScreenPtr screen,
CARD32 *num_formats, CARD32 **formats);
Bool xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
uint32_t *num_modifiers, uint64_t **modifiers);
Bool xwl_glamor_check_flip(PixmapPtr pixmap);
#ifdef XV
/* glamor Xv Adaptor */
Bool xwl_glamor_xv_init(ScreenPtr pScreen);
#endif /* XV */
#endif /* XWL_HAS_GLAMOR */
#ifdef GLAMOR_HAS_GBM
void xwl_glamor_init_gbm(struct xwl_screen *xwl_screen);
#else
static inline void xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
{
}
#endif
#ifdef XWL_HAS_EGLSTREAM
void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen);
#else
static inline void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen)
{
}
#endif
#endif /* XWAYLAND_GLAMOR_H */

View File

@ -1,397 +0,0 @@
/*
* Copyright © 2019 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Adam Jackson <ajax@redhat.com>
*/
/*
* Sets up GLX capabilities based on the EGL capabilities of the glamor
* renderer for the screen. Without this you will get whatever swrast
* can do, which often does not include things like multisample visuals.
*/
#include <xwayland-config.h>
#define MESA_EGL_NO_X11_HEADERS
#define EGL_NO_X11
// #include <EGL/egl.h>
#include <epoxy/egl.h>
#include "glxserver.h"
#include "glxutil.h"
#include "compint.h"
#include <X11/extensions/composite.h>
#include "glamor_context.h"
#include "glamor.h"
#include "xwayland-screen.h"
/* Can't get these from <GL/glx.h> since it pulls in client headers */
#define GLX_RGBA_BIT 0x00000001
#define GLX_WINDOW_BIT 0x00000001
#define GLX_PIXMAP_BIT 0x00000002
#define GLX_PBUFFER_BIT 0x00000004
#define GLX_NONE 0x8000
#define GLX_SLOW_CONFIG 0x8001
#define GLX_TRUE_COLOR 0x8002
#define GLX_DIRECT_COLOR 0x8003
#define GLX_NON_CONFORMANT_CONFIG 0x800D
#define GLX_DONT_CARE 0xFFFFFFFF
#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004
#define GLX_SWAP_UNDEFINED_OML 0x8063
struct egl_config {
__GLXconfig base;
EGLConfig config;
};
struct egl_screen {
__GLXscreen base;
EGLDisplay display;
EGLConfig *configs;
};
static void
egl_screen_destroy(__GLXscreen *_screen)
{
struct egl_screen *screen = (struct egl_screen *)_screen;
/* XXX do we leak the fbconfig list? */
free(screen->configs);
__glXScreenDestroy(_screen);
free(_screen);
}
static void
egl_drawable_destroy(__GLXdrawable *draw)
{
free(draw);
}
static GLboolean
egl_drawable_swap_buffers(ClientPtr client, __GLXdrawable *draw)
{
return GL_FALSE;
}
static void
egl_drawable_copy_sub_buffer(__GLXdrawable *draw, int x, int y, int w, int h)
{
}
static void
egl_drawable_wait_x(__GLXdrawable *draw)
{
glamor_block_handler(draw->pDraw->pScreen);
}
static void
egl_drawable_wait_gl(__GLXdrawable *draw)
{
}
static __GLXdrawable *
egl_create_glx_drawable(ClientPtr client, __GLXscreen *screen,
DrawablePtr draw, XID drawid, int type,
XID glxdrawid, __GLXconfig *modes)
{
__GLXdrawable *ret;
ret = calloc(1, sizeof *ret);
if (!ret)
return NULL;
if (!__glXDrawableInit(ret, screen, draw, type, glxdrawid, modes)) {
free(ret);
return NULL;
}
ret->destroy = egl_drawable_destroy;
ret->swapBuffers = egl_drawable_swap_buffers;
ret->copySubBuffer = egl_drawable_copy_sub_buffer;
ret->waitX = egl_drawable_wait_x;
ret->waitGL = egl_drawable_wait_gl;
return ret;
}
/*
* TODO:
*
* - figure out sRGB
* - bindToTextureTargets is suspicious
* - better channel mask setup
* - drawable type masks is suspicious
*/
static struct egl_config *
translate_eglconfig(struct egl_screen *screen, EGLConfig hc,
struct egl_config *chain, Bool direct_color,
Bool double_buffer, Bool duplicate_for_composite)
{
EGLint value;
struct egl_config *c = calloc(1, sizeof *c);
if (!c)
return chain;
/* constants. changing these requires (at least) new EGL extensions */
c->base.stereoMode = GL_FALSE;
c->base.numAuxBuffers = 0;
c->base.level = 0;
c->base.transparentAlpha = 0;
c->base.transparentIndex = 0;
c->base.transparentPixel = GLX_NONE;
c->base.visualSelectGroup = 0;
c->base.indexBits = 0;
c->base.optimalPbufferWidth = 0;
c->base.optimalPbufferHeight = 0;
c->base.bindToMipmapTexture = 0;
c->base.bindToTextureTargets = GLX_DONT_CARE;
c->base.sRGBCapable = 0;
c->base.swapMethod = GLX_SWAP_UNDEFINED_OML;
/* this is... suspect */
c->base.drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
/* hmm */
c->base.bindToTextureRgb = GL_TRUE;
c->base.bindToTextureRgba = GL_TRUE;
/*
* glx conformance failure: there's no such thing as accumulation
* buffers in EGL. they should be emulable with shaders and fbos,
* but i'm pretty sure nobody's using this feature since it's
* entirely software. note that glx conformance merely requires
* that an accum buffer _exist_, not a minimum bitness.
*/
c->base.accumRedBits = 0;
c->base.accumGreenBits = 0;
c->base.accumBlueBits = 0;
c->base.accumAlphaBits = 0;
/* parametric state */
if (direct_color)
c->base.visualType = GLX_DIRECT_COLOR;
else
c->base.visualType = GLX_TRUE_COLOR;
if (double_buffer)
c->base.doubleBufferMode = GL_TRUE;
else
c->base.doubleBufferMode = GL_FALSE;
/* direct-mapped state */
#define GET(attr, slot) \
eglGetConfigAttrib(screen->display, hc, attr, &c->base.slot)
GET(EGL_RED_SIZE, redBits);
GET(EGL_GREEN_SIZE, greenBits);
GET(EGL_BLUE_SIZE, blueBits);
GET(EGL_ALPHA_SIZE, alphaBits);
GET(EGL_BUFFER_SIZE, rgbBits);
GET(EGL_DEPTH_SIZE, depthBits);
GET(EGL_STENCIL_SIZE, stencilBits);
GET(EGL_TRANSPARENT_RED_VALUE, transparentRed);
GET(EGL_TRANSPARENT_GREEN_VALUE, transparentGreen);
GET(EGL_TRANSPARENT_BLUE_VALUE, transparentBlue);
GET(EGL_SAMPLE_BUFFERS, sampleBuffers);
GET(EGL_SAMPLES, samples);
if (c->base.renderType & GLX_PBUFFER_BIT) {
GET(EGL_MAX_PBUFFER_WIDTH, maxPbufferWidth);
GET(EGL_MAX_PBUFFER_HEIGHT, maxPbufferHeight);
GET(EGL_MAX_PBUFFER_PIXELS, maxPbufferPixels);
}
#undef GET
/* derived state: config caveats */
eglGetConfigAttrib(screen->display, hc, EGL_CONFIG_CAVEAT, &value);
if (value == EGL_NONE)
c->base.visualRating = GLX_NONE;
else if (value == EGL_SLOW_CONFIG)
c->base.visualRating = GLX_SLOW_CONFIG;
else if (value == EGL_NON_CONFORMANT_CONFIG)
c->base.visualRating = GLX_NON_CONFORMANT_CONFIG;
/* else panic */
/* derived state: float configs */
c->base.renderType = GLX_RGBA_BIT;
if (eglGetConfigAttrib(screen->display, hc, EGL_COLOR_COMPONENT_TYPE_EXT,
&value) == EGL_TRUE) {
if (value == EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT) {
c->base.renderType = GLX_RGBA_FLOAT_BIT_ARB;
}
/* else panic */
}
/* map to the backend's config */
c->config = hc;
/*
* XXX do something less ugly
*/
if (c->base.renderType == GLX_RGBA_BIT) {
if (c->base.redBits == 5 &&
(c->base.rgbBits == 15 || c->base.rgbBits == 16)) {
c->base.blueMask = 0x0000001f;
if (c->base.alphaBits) {
c->base.greenMask = 0x000003e0;
c->base.redMask = 0x00007c00;
c->base.alphaMask = 0x00008000;
} else {
c->base.greenMask = 0x000007e0;
c->base.redMask = 0x0000f800;
c->base.alphaMask = 0x00000000;
}
}
else if (c->base.redBits == 8 &&
(c->base.rgbBits == 24 || c->base.rgbBits == 32)) {
c->base.blueMask = 0x000000ff;
c->base.greenMask = 0x0000ff00;
c->base.redMask = 0x00ff0000;
if (c->base.alphaBits)
/* assume all remaining bits are alpha */
c->base.alphaMask = 0xff000000;
}
else if (c->base.redBits == 10 &&
(c->base.rgbBits == 30 || c->base.rgbBits == 32)) {
c->base.blueMask = 0x000003ff;
c->base.greenMask = 0x000ffc00;
c->base.redMask = 0x3ff00000;
if (c->base.alphaBits)
/* assume all remaining bits are alpha */
c->base.alphaMask = 0xc000000;
}
}
/*
* Here we decide which fbconfigs will be duplicated for compositing.
* fgbconfigs marked with duplicatedForComp will be reserved for
* compositing visuals.
* It might look strange to do this decision this late when translation
* from an EGLConfig is already done, but using the EGLConfig
* accessor functions becomes worse both with respect to code complexity
* and CPU usage.
*/
if (duplicate_for_composite &&
(c->base.renderType == GLX_RGBA_FLOAT_BIT_ARB ||
c->base.rgbBits != 32 ||
c->base.redBits != 8 ||
c->base.greenBits != 8 ||
c->base.blueBits != 8 ||
c->base.visualRating != GLX_NONE ||
c->base.sampleBuffers != 0)) {
free(c);
return chain;
}
c->base.duplicatedForComp = duplicate_for_composite;
c->base.next = chain ? &chain->base : NULL;
return c;
}
static __GLXconfig *
egl_mirror_configs(ScreenPtr pScreen, struct egl_screen *screen)
{
int i, j, k, nconfigs;
struct egl_config *c = NULL;
EGLConfig *host_configs = NULL;
eglGetConfigs(screen->display, NULL, 0, &nconfigs);
if (!(host_configs = calloc(nconfigs, sizeof *host_configs)))
return NULL;
eglGetConfigs(screen->display, host_configs, nconfigs, &nconfigs);
/* We walk the EGL configs backwards to make building the
* ->next chain easier.
*/
for (i = nconfigs - 1; i > 0; i--)
for (j = 0; j < 3; j++) /* direct_color */
for (k = 0; k < 2; k++) /* double_buffer */
c = translate_eglconfig(screen, host_configs[i], c,
/* direct_color */ j == 1,
/* double_buffer */ k > 0,
/* duplicate_for_composite */ j == 0);
screen->configs = host_configs;
return c ? &c->base : NULL;
}
static __GLXscreen *
egl_screen_probe(ScreenPtr pScreen)
{
struct egl_screen *screen;
struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
__GLXscreen *base;
if (enableIndirectGLX)
return NULL; /* not implemented */
if (!(screen = calloc(1, sizeof *screen)))
return NULL;
base = &screen->base;
base->destroy = egl_screen_destroy;
base->createDrawable = egl_create_glx_drawable;
/* base.swapInterval = NULL; */
screen->display = xwl_screen->glamor_ctx->display;
__glXInitExtensionEnableBits(screen->base.glx_enable_bits);
__glXEnableExtension(base->glx_enable_bits, "GLX_ARB_context_flush_control");
__glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context");
__glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context_no_error");
__glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context_profile");
__glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context_robustness");
__glXEnableExtension(base->glx_enable_bits, "GLX_ARB_fbconfig_float");
__glXEnableExtension(base->glx_enable_bits, "GLX_EXT_create_context_es2_profile");
__glXEnableExtension(base->glx_enable_bits, "GLX_EXT_create_context_es_profile");
__glXEnableExtension(base->glx_enable_bits, "GLX_EXT_fbconfig_packed_float");
__glXEnableExtension(base->glx_enable_bits, "GLX_EXT_framebuffer_sRGB");
__glXEnableExtension(base->glx_enable_bits, "GLX_EXT_no_config_context");
__glXEnableExtension(base->glx_enable_bits, "GLX_EXT_texture_from_pixmap");
__glXEnableExtension(base->glx_enable_bits, "GLX_MESA_copy_sub_buffer");
// __glXEnableExtension(base->glx_enable_bits, "GLX_SGI_swap_control");
base->fbconfigs = egl_mirror_configs(pScreen, screen);
if (!base->fbconfigs) {
free(screen);
return NULL;
}
if (!screen->base.glvnd && xwl_screen->glvnd_vendor)
screen->base.glvnd = strdup(xwl_screen->glvnd_vendor);
if (!screen->base.glvnd)
screen->base.glvnd = strdup("mesa");
__glXScreenInit(base, pScreen);
__glXsetGetProcAddress(eglGetProcAddress);
return base;
}
__GLXprovider glamor_provider = {
egl_screen_probe,
"glamor",
NULL
};

View File

@ -1,37 +0,0 @@
/*
* Copyright © 2019 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Adam Jackson <ajax@redhat.com>
*/
#ifndef XWAYLAND_GLX_H
#define XWAYLAND_GLX_H
#include <xwayland-config.h>
#ifdef GLXEXT
#include "glx_extinit.h"
extern __GLXprovider glamor_provider;
#endif
#endif /* XWAYLAND_GLX_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,197 +0,0 @@
/*
* Copyright © 2014 Intel Corporation
* Copyright © 2008 Kristian Høgsberg
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the
* copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#ifndef XWAYLAND_INPUT_H
#define XWAYLAND_INPUT_H
#include <xwayland-config.h>
#include <wayland-client.h>
#include <dix.h>
#include <input.h>
struct xwl_touch {
struct xwl_window *window;
int32_t id;
int x, y;
struct xorg_list link_touch;
};
struct xwl_pointer_warp_emulator {
struct xwl_seat *xwl_seat;
struct xwl_window *locked_window;
struct zwp_locked_pointer_v1 *locked_pointer;
};
struct xwl_cursor {
void (* update_proc) (struct xwl_cursor *);
struct wl_surface *surface;
struct wl_callback *frame_cb;
Bool needs_update;
};
struct xwl_seat {
DeviceIntPtr pointer;
DeviceIntPtr relative_pointer;
DeviceIntPtr keyboard;
DeviceIntPtr touch;
DeviceIntPtr stylus;
DeviceIntPtr eraser;
DeviceIntPtr puck;
struct xwl_screen *xwl_screen;
struct wl_seat *seat;
struct wl_pointer *wl_pointer;
struct zwp_relative_pointer_v1 *wp_relative_pointer;
struct wl_keyboard *wl_keyboard;
struct wl_touch *wl_touch;
struct zwp_tablet_seat_v2 *tablet_seat;
struct wl_array keys;
struct xwl_window *focus_window;
struct xwl_window *tablet_focus_window;
uint32_t id;
uint32_t pointer_enter_serial;
struct xorg_list link;
CursorPtr x_cursor;
OsTimerPtr x_cursor_timer;
CursorPtr pending_x_cursor;
struct xwl_cursor cursor;
WindowPtr last_xwindow;
struct xorg_list touches;
size_t keymap_size;
char *keymap;
struct wl_surface *keyboard_focus;
struct xorg_list axis_discrete_pending;
struct xorg_list sync_pending;
struct xwl_pointer_warp_emulator *pointer_warp_emulator;
struct xwl_window *cursor_confinement_window;
struct zwp_confined_pointer_v1 *confined_pointer;
struct {
Bool has_absolute;
wl_fixed_t x;
wl_fixed_t y;
Bool has_relative;
double dx;
double dy;
double dx_unaccel;
double dy_unaccel;
} pending_pointer_event;
struct xorg_list tablets;
struct xorg_list tablet_tools;
struct xorg_list tablet_pads;
struct zwp_xwayland_keyboard_grab_v1 *keyboard_grab;
};
struct xwl_tablet {
struct xorg_list link;
struct zwp_tablet_v2 *tablet;
struct xwl_seat *seat;
};
struct xwl_tablet_tool {
struct xorg_list link;
struct zwp_tablet_tool_v2 *tool;
struct xwl_seat *seat;
DeviceIntPtr xdevice;
uint32_t proximity_in_serial;
double x;
double y;
uint32_t pressure;
double tilt_x;
double tilt_y;
double rotation;
double slider;
uint32_t buttons_now,
buttons_prev;
int32_t wheel_clicks;
struct xwl_cursor cursor;
};
struct xwl_tablet_pad_ring {
unsigned int index;
struct xorg_list link;
struct xwl_tablet_pad_group *group;
struct zwp_tablet_pad_ring_v2 *ring;
};
struct xwl_tablet_pad_strip {
unsigned int index;
struct xorg_list link;
struct xwl_tablet_pad_group *group;
struct zwp_tablet_pad_strip_v2 *strip;
};
struct xwl_tablet_pad_group {
struct xorg_list link;
struct xwl_tablet_pad *pad;
struct zwp_tablet_pad_group_v2 *group;
struct xorg_list pad_group_ring_list;
struct xorg_list pad_group_strip_list;
};
struct xwl_tablet_pad {
struct xorg_list link;
struct zwp_tablet_pad_v2 *pad;
struct xwl_seat *seat;
DeviceIntPtr xdevice;
unsigned int nbuttons;
struct xorg_list pad_group_list;
};
void xwl_seat_destroy(struct xwl_seat *xwl_seat);
void xwl_seat_clear_touch(struct xwl_seat *xwl_seat, WindowPtr window);
void xwl_seat_emulate_pointer_warp(struct xwl_seat *xwl_seat,
struct xwl_window *xwl_window,
SpritePtr sprite,
int x, int y);
void xwl_seat_destroy_pointer_warp_emulator(struct xwl_seat *xwl_seat);
void xwl_seat_cursor_visibility_changed(struct xwl_seat *xwl_seat);
void xwl_seat_confine_pointer(struct xwl_seat *xwl_seat,
struct xwl_window *xwl_window);
void xwl_seat_unconfine_pointer(struct xwl_seat *xwl_seat);
void xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen);
#endif /* XWAYLAND_INPUT_H */

View File

@ -1,881 +0,0 @@
/*
* Copyright © 2011-2014 Intel Corporation
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the
* copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#include <xwayland-config.h>
#include <randrstr.h>
#include <X11/Xatom.h>
#include "xwayland-cvt.h"
#include "xwayland-output.h"
#include "xwayland-screen.h"
#include "xwayland-window.h"
#include "xdg-output-unstable-v1-client-protocol.h"
#define ALL_ROTATIONS (RR_Rotate_0 | \
RR_Rotate_90 | \
RR_Rotate_180 | \
RR_Rotate_270 | \
RR_Reflect_X | \
RR_Reflect_Y)
static void xwl_output_get_xdg_output(struct xwl_output *xwl_output);
static Rotation
wl_transform_to_xrandr(enum wl_output_transform transform)
{
switch (transform) {
default:
case WL_OUTPUT_TRANSFORM_NORMAL:
return RR_Rotate_0;
case WL_OUTPUT_TRANSFORM_90:
return RR_Rotate_90;
case WL_OUTPUT_TRANSFORM_180:
return RR_Rotate_180;
case WL_OUTPUT_TRANSFORM_270:
return RR_Rotate_270;
case WL_OUTPUT_TRANSFORM_FLIPPED:
return RR_Reflect_X | RR_Rotate_0;
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
return RR_Reflect_X | RR_Rotate_90;
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
return RR_Reflect_X | RR_Rotate_180;
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
return RR_Reflect_X | RR_Rotate_270;
}
}
static int
wl_subpixel_to_xrandr(int subpixel)
{
switch (subpixel) {
default:
case WL_OUTPUT_SUBPIXEL_UNKNOWN:
return SubPixelUnknown;
case WL_OUTPUT_SUBPIXEL_NONE:
return SubPixelNone;
case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB:
return SubPixelHorizontalRGB;
case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR:
return SubPixelHorizontalBGR;
case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB:
return SubPixelVerticalRGB;
case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR:
return SubPixelVerticalBGR;
}
}
static void
output_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
int physical_width, int physical_height, int subpixel,
const char *make, const char *model, int transform)
{
struct xwl_output *xwl_output = data;
RROutputSetPhysicalSize(xwl_output->randr_output,
physical_width, physical_height);
RROutputSetSubpixelOrder(xwl_output->randr_output,
wl_subpixel_to_xrandr(subpixel));
/* Apply the change from wl_output only if xdg-output is not supported */
if (!xwl_output->xdg_output) {
xwl_output->x = x;
xwl_output->y = y;
}
xwl_output->rotation = wl_transform_to_xrandr(transform);
}
static void
output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags,
int width, int height, int refresh)
{
struct xwl_output *xwl_output = data;
if (!(flags & WL_OUTPUT_MODE_CURRENT))
return;
/* Apply the change from wl_output only if xdg-output is not supported */
if (!xwl_output->xdg_output) {
xwl_output->width = width;
xwl_output->height = height;
}
xwl_output->refresh = refresh;
}
/**
* Decides on the maximum expanse of an output in logical space (i.e. in the
* Wayland compositor plane) respective to some fix width and height values. The
* function sets the provided values to these maxima on return.
*/
static inline void
output_get_new_size(struct xwl_output *xwl_output, int *width, int *height)
{
int output_width, output_height;
/* When we have xdg-output support the stored size is already rotated. */
if (xwl_output->xdg_output
|| (xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180))) {
output_width = xwl_output->width;
output_height = xwl_output->height;
} else {
output_width = xwl_output->height;
output_height = xwl_output->width;
}
if (*width < xwl_output->x + output_width)
*width = xwl_output->x + output_width;
if (*height < xwl_output->y + output_height)
*height = xwl_output->y + output_height;
}
static int
xwl_set_pixmap_visit_window(WindowPtr window, void *data)
{
ScreenPtr screen = window->drawable.pScreen;
if (screen->GetWindowPixmap(window) == data) {
screen->SetWindowPixmap(window, screen->GetScreenPixmap(screen));
return WT_WALKCHILDREN;
}
return WT_DONTWALKCHILDREN;
}
static void
update_backing_pixmaps(struct xwl_screen *xwl_screen, int width, int height)
{
ScreenPtr pScreen = xwl_screen->screen;
WindowPtr pRoot = pScreen->root;
PixmapPtr old_pixmap, new_pixmap;
old_pixmap = pScreen->GetScreenPixmap(pScreen);
new_pixmap = pScreen->CreatePixmap(pScreen, width, height,
pScreen->rootDepth,
CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
pScreen->SetScreenPixmap(new_pixmap);
if (old_pixmap) {
TraverseTree(pRoot, xwl_set_pixmap_visit_window, old_pixmap);
pScreen->DestroyPixmap(old_pixmap);
}
pScreen->ResizeWindow(pRoot, 0, 0, width, height, NULL);
}
static void
update_screen_size(struct xwl_output *xwl_output, int width, int height)
{
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
if (xwl_screen->root_clip_mode == ROOT_CLIP_FULL)
SetRootClip(xwl_screen->screen, ROOT_CLIP_NONE);
if (!xwl_screen->rootless && xwl_screen->screen->root)
update_backing_pixmaps (xwl_screen, width, height);
xwl_screen->width = width;
xwl_screen->height = height;
xwl_screen->screen->width = width;
xwl_screen->screen->height = height;
xwl_screen->screen->mmWidth = (width * 25.4) / monitorResolution;
xwl_screen->screen->mmHeight = (height * 25.4) / monitorResolution;
SetRootClip(xwl_screen->screen, xwl_screen->root_clip_mode);
if (xwl_screen->screen->root) {
BoxRec box = { 0, 0, width, height };
xwl_screen->screen->root->drawable.width = width;
xwl_screen->screen->root->drawable.height = height;
RegionReset(&xwl_screen->screen->root->winSize, &box);
RRScreenSizeNotify(xwl_screen->screen);
}
update_desktop_dimensions();
RRTellChanged(xwl_screen->screen);
}
struct xwl_emulated_mode *
xwl_output_get_emulated_mode_for_client(struct xwl_output *xwl_output,
ClientPtr client)
{
struct xwl_client *xwl_client = xwl_client_get(client);
int i;
if (!xwl_output)
return NULL;
for (i = 0; i < XWL_CLIENT_MAX_EMULATED_MODES; i++) {
if (xwl_client->emulated_modes[i].server_output_id ==
xwl_output->server_output_id)
return &xwl_client->emulated_modes[i];
}
return NULL;
}
static void
xwl_output_add_emulated_mode_for_client(struct xwl_output *xwl_output,
ClientPtr client,
RRModePtr mode,
Bool from_vidmode)
{
struct xwl_client *xwl_client = xwl_client_get(client);
struct xwl_emulated_mode *emulated_mode;
int i;
emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client);
if (!emulated_mode) {
/* Find a free spot in the emulated modes array */
for (i = 0; i < XWL_CLIENT_MAX_EMULATED_MODES; i++) {
if (xwl_client->emulated_modes[i].server_output_id == 0) {
emulated_mode = &xwl_client->emulated_modes[i];
break;
}
}
}
if (!emulated_mode) {
static Bool warned;
if (!warned) {
ErrorF("Ran out of space for emulated-modes, not adding mode");
warned = TRUE;
}
return;
}
emulated_mode->server_output_id = xwl_output->server_output_id;
emulated_mode->width = mode->mode.width;
emulated_mode->height = mode->mode.height;
emulated_mode->from_vidmode = from_vidmode;
}
static void
xwl_output_remove_emulated_mode_for_client(struct xwl_output *xwl_output,
ClientPtr client)
{
struct xwl_emulated_mode *emulated_mode;
emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client);
if (emulated_mode) {
DebugF("XWAYLAND: xwl_output_remove_emulated_mode: %dx%d\n",
emulated_mode->width, emulated_mode->height);
memset(emulated_mode, 0, sizeof(*emulated_mode));
}
}
/* From hw/xfree86/common/xf86DefModeSet.c with some obscure modes dropped */
const int32_t xwl_output_fake_modes[][2] = {
/* 4:3 (1.33) */
{ 2048, 1536 },
{ 1920, 1440 },
{ 1600, 1200 },
{ 1440, 1080 },
{ 1400, 1050 },
{ 1280, 1024 }, /* 5:4 (1.25) */
{ 1280, 960 },
{ 1152, 864 },
{ 1024, 768 },
{ 800, 600 },
{ 640, 480 },
{ 320, 240 },
/* 16:10 (1.6) */
{ 2560, 1600 },
{ 1920, 1200 },
{ 1680, 1050 },
{ 1440, 900 },
{ 1280, 800 },
{ 720, 480 }, /* 3:2 (1.5) */
{ 640, 400 },
{ 320, 200 },
/* 16:9 (1.77) */
{ 5120, 2880 },
{ 4096, 2304 },
{ 3840, 2160 },
{ 3200, 1800 },
{ 2880, 1620 },
{ 2560, 1440 },
{ 2048, 1152 },
{ 1920, 1080 },
{ 1600, 900 },
{ 1368, 768 },
{ 1280, 720 },
{ 1024, 576 },
{ 864, 486 },
{ 720, 400 },
{ 640, 350 },
};
/* Build an array with RRModes the first mode is the actual output mode, the
* rest are fake modes from the xwl_output_fake_modes list. We do this for apps
* which want to change resolution when they go fullscreen.
* When an app requests a mode-change, we fake it using WPviewport.
*/
static RRModePtr *
output_get_rr_modes(struct xwl_output *xwl_output,
int32_t width, int32_t height,
int *count)
{
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
RRModePtr *rr_modes;
int i;
rr_modes = xallocarray(ARRAY_SIZE(xwl_output_fake_modes) + 1, sizeof(RRModePtr));
if (!rr_modes)
goto err;
/* Add actual output mode */
rr_modes[0] = xwayland_cvt(width, height, xwl_output->refresh / 1000.0, 0, 0);
if (!rr_modes[0])
goto err;
*count = 1;
if (!xwl_screen_has_resolution_change_emulation(xwl_screen))
return rr_modes;
/* Add fake modes */
for (i = 0; i < ARRAY_SIZE(xwl_output_fake_modes); i++) {
/* Skip actual output mode, already added */
if (xwl_output_fake_modes[i][0] == width &&
xwl_output_fake_modes[i][1] == height)
continue;
/* Skip modes which are too big, avoid downscaling */
if (xwl_output_fake_modes[i][0] > width ||
xwl_output_fake_modes[i][1] > height)
continue;
rr_modes[*count] = xwayland_cvt(xwl_output_fake_modes[i][0],
xwl_output_fake_modes[i][1],
xwl_output->refresh / 1000.0, 0, 0);
if (!rr_modes[*count])
goto err;
(*count)++;
}
return rr_modes;
err:
FatalError("Failed to allocate memory for list of RR modes");
}
RRModePtr
xwl_output_find_mode(struct xwl_output *xwl_output,
int32_t width, int32_t height)
{
RROutputPtr output = xwl_output->randr_output;
int i;
/* width & height -1 means we want the actual output mode, which is idx 0 */
if (width == -1 && height == -1 && output->modes)
return output->modes[0];
for (i = 0; i < output->numModes; i++) {
if (output->modes[i]->mode.width == width && output->modes[i]->mode.height == height)
return output->modes[i];
}
ErrorF("XWAYLAND: mode %dx%d is not available\n", width, height);
return NULL;
}
struct xwl_output_randr_emu_prop {
Atom atom;
uint32_t rects[XWL_CLIENT_MAX_EMULATED_MODES][4];
int rect_count;
};
static void
xwl_output_randr_emu_prop(struct xwl_screen *xwl_screen, ClientPtr client,
struct xwl_output_randr_emu_prop *prop)
{
static const char atom_name[] = "_XWAYLAND_RANDR_EMU_MONITOR_RECTS";
struct xwl_emulated_mode *emulated_mode;
struct xwl_output *xwl_output;
int index = 0;
prop->atom = MakeAtom(atom_name, strlen(atom_name), TRUE);
xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) {
emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client);
if (!emulated_mode)
continue;
prop->rects[index][0] = xwl_output->x;
prop->rects[index][1] = xwl_output->y;
prop->rects[index][2] = emulated_mode->width;
prop->rects[index][3] = emulated_mode->height;
index++;
}
prop->rect_count = index;
}
static void
xwl_output_set_randr_emu_prop(WindowPtr window,
struct xwl_output_randr_emu_prop *prop)
{
if (prop->rect_count) {
dixChangeWindowProperty(serverClient, window, prop->atom,
XA_CARDINAL, 32, PropModeReplace,
prop->rect_count * 4, prop->rects, TRUE);
} else {
DeleteProperty(serverClient, window, prop->atom);
}
}
static void
xwl_output_set_randr_emu_prop_callback(void *resource, XID id, void *user_data)
{
if (xwl_window_is_toplevel(resource))
xwl_output_set_randr_emu_prop(resource, user_data);
}
static void
xwl_output_set_randr_emu_props(struct xwl_screen *xwl_screen, ClientPtr client)
{
struct xwl_output_randr_emu_prop prop = {};
xwl_output_randr_emu_prop(xwl_screen, client, &prop);
FindClientResourcesByType(client, RT_WINDOW,
xwl_output_set_randr_emu_prop_callback, &prop);
}
void
xwl_output_set_window_randr_emu_props(struct xwl_screen *xwl_screen,
WindowPtr window)
{
struct xwl_output_randr_emu_prop prop = {};
xwl_output_randr_emu_prop(xwl_screen, wClient(window), &prop);
xwl_output_set_randr_emu_prop(window, &prop);
}
void
xwl_output_set_emulated_mode(struct xwl_output *xwl_output, ClientPtr client,
RRModePtr mode, Bool from_vidmode)
{
DebugF("XWAYLAND: xwl_output_set_emulated_mode from %s: %dx%d\n",
from_vidmode ? "vidmode" : "randr",
mode->mode.width, mode->mode.height);
/* modes[0] is the actual (not-emulated) output mode */
if (mode == xwl_output->randr_output->modes[0])
xwl_output_remove_emulated_mode_for_client(xwl_output, client);
else
xwl_output_add_emulated_mode_for_client(xwl_output, client, mode, from_vidmode);
xwl_screen_check_resolution_change_emulation(xwl_output->xwl_screen);
xwl_output_set_randr_emu_props(xwl_output->xwl_screen, client);
}
static void
apply_output_change(struct xwl_output *xwl_output)
{
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
struct xwl_output *it;
int mode_width, mode_height, count;
int width = 0, height = 0, has_this_output = 0;
RRModePtr *randr_modes;
/* Clear out the "done" received flags */
xwl_output->wl_output_done = FALSE;
xwl_output->xdg_output_done = FALSE;
/* When we have received an xdg-output for the mode size we might need to
* rotate back the stored logical size it provided.
*/
if (xwl_output->xdg_output == NULL
|| xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180)) {
mode_width = xwl_output->width;
mode_height = xwl_output->height;
} else {
mode_width = xwl_output->height;
mode_height = xwl_output->width;
}
/* Build a fresh modes array using the current refresh rate */
randr_modes = output_get_rr_modes(xwl_output, mode_width, mode_height, &count);
RROutputSetModes(xwl_output->randr_output, randr_modes, count, 1);
RRCrtcNotify(xwl_output->randr_crtc, randr_modes[0],
xwl_output->x, xwl_output->y,
xwl_output->rotation, NULL, 1, &xwl_output->randr_output);
/* RROutputSetModes takes ownership of the passed in modes, so we only
* have to free the pointer array.
*/
free(randr_modes);
xorg_list_for_each_entry(it, &xwl_screen->output_list, link) {
/* output done event is sent even when some property
* of output is changed. That means that we may already
* have this output. If it is true, we must not add it
* into the output_list otherwise we'll corrupt it */
if (it == xwl_output)
has_this_output = 1;
output_get_new_size(it, &width, &height);
}
if (!has_this_output) {
xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
/* we did not check this output for new screen size, do it now */
output_get_new_size(xwl_output, &width, &height);
--xwl_screen->expecting_event;
}
update_screen_size(xwl_output, width, height);
}
static void
output_handle_done(void *data, struct wl_output *wl_output)
{
struct xwl_output *xwl_output = data;
xwl_output->wl_output_done = TRUE;
/* Apply the changes from wl_output only if both "done" events are received,
* if xdg-output is not supported or if xdg-output version is high enough.
*/
if (xwl_output->xdg_output_done || !xwl_output->xdg_output ||
zxdg_output_v1_get_version(xwl_output->xdg_output) >= 3)
apply_output_change(xwl_output);
}
static void
output_handle_scale(void *data, struct wl_output *wl_output, int32_t factor)
{
}
static const struct wl_output_listener output_listener = {
output_handle_geometry,
output_handle_mode,
output_handle_done,
output_handle_scale
};
static void
xdg_output_handle_logical_position(void *data, struct zxdg_output_v1 *xdg_output,
int32_t x, int32_t y)
{
struct xwl_output *xwl_output = data;
xwl_output->x = x;
xwl_output->y = y;
}
static void
xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output,
int32_t width, int32_t height)
{
struct xwl_output *xwl_output = data;
xwl_output->width = width;
xwl_output->height = height;
}
static void
xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output)
{
struct xwl_output *xwl_output = data;
xwl_output->xdg_output_done = TRUE;
if (xwl_output->wl_output_done &&
zxdg_output_v1_get_version(xdg_output) < 3)
apply_output_change(xwl_output);
}
static void
xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output,
const char *name)
{
}
static void
xdg_output_handle_description(void *data, struct zxdg_output_v1 *xdg_output,
const char *description)
{
}
static const struct zxdg_output_v1_listener xdg_output_listener = {
xdg_output_handle_logical_position,
xdg_output_handle_logical_size,
xdg_output_handle_done,
xdg_output_handle_name,
xdg_output_handle_description,
};
struct xwl_output *
xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id)
{
struct xwl_output *xwl_output;
static int serial;
char name[256];
xwl_output = calloc(1, sizeof *xwl_output);
if (xwl_output == NULL) {
ErrorF("%s ENOMEM\n", __func__);
return NULL;
}
xwl_output->output = wl_registry_bind(xwl_screen->registry, id,
&wl_output_interface, 2);
if (!xwl_output->output) {
ErrorF("Failed binding wl_output\n");
goto err;
}
xwl_output->server_output_id = id;
wl_output_add_listener(xwl_output->output, &output_listener, xwl_output);
snprintf(name, sizeof name, "XWAYLAND%d", serial++);
xwl_output->xwl_screen = xwl_screen;
xwl_output->randr_crtc = RRCrtcCreate(xwl_screen->screen, xwl_output);
if (!xwl_output->randr_crtc) {
ErrorF("Failed creating RandR CRTC\n");
goto err;
}
RRCrtcSetRotations (xwl_output->randr_crtc, ALL_ROTATIONS);
xwl_output->randr_output = RROutputCreate(xwl_screen->screen, name,
strlen(name), xwl_output);
if (!xwl_output->randr_output) {
ErrorF("Failed creating RandR Output\n");
goto err;
}
RRCrtcGammaSetSize(xwl_output->randr_crtc, 256);
RROutputSetCrtcs(xwl_output->randr_output, &xwl_output->randr_crtc, 1);
RROutputSetConnection(xwl_output->randr_output, RR_Connected);
RRTellChanged(xwl_screen->screen);
/* We want the output to be in the list as soon as created so we can
* use it when binding to the xdg-output protocol...
*/
xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
--xwl_screen->expecting_event;
if (xwl_screen->xdg_output_manager)
xwl_output_get_xdg_output(xwl_output);
return xwl_output;
err:
if (xwl_output->randr_crtc)
RRCrtcDestroy(xwl_output->randr_crtc);
if (xwl_output->output)
wl_output_destroy(xwl_output->output);
free(xwl_output);
return NULL;
}
void
xwl_output_destroy(struct xwl_output *xwl_output)
{
if (xwl_output->xdg_output)
zxdg_output_v1_destroy(xwl_output->xdg_output);
wl_output_destroy(xwl_output->output);
free(xwl_output);
}
void
xwl_output_remove(struct xwl_output *xwl_output)
{
struct xwl_output *it;
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
int width = 0, height = 0;
xorg_list_del(&xwl_output->link);
xorg_list_for_each_entry(it, &xwl_screen->output_list, link)
output_get_new_size(it, &width, &height);
update_screen_size(xwl_output, width, height);
RRCrtcDestroy(xwl_output->randr_crtc);
RROutputDestroy(xwl_output->randr_output);
RRTellChanged(xwl_screen->screen);
xwl_output_destroy(xwl_output);
}
static Bool
xwl_randr_get_info(ScreenPtr pScreen, Rotation * rotations)
{
*rotations = ALL_ROTATIONS;
return TRUE;
}
#ifdef RANDR_10_INTERFACE
static Bool
xwl_randr_set_config(ScreenPtr pScreen,
Rotation rotation, int rate, RRScreenSizePtr pSize)
{
return FALSE;
}
#endif
#if RANDR_12_INTERFACE
static Bool
xwl_randr_screen_set_size(ScreenPtr pScreen,
CARD16 width,
CARD16 height,
CARD32 mmWidth, CARD32 mmHeight)
{
return TRUE;
}
static Bool
xwl_randr_crtc_set(ScreenPtr pScreen,
RRCrtcPtr crtc,
RRModePtr new_mode,
int x,
int y,
Rotation rotation,
int numOutputs, RROutputPtr * outputs)
{
struct xwl_output *xwl_output = crtc->devPrivate;
RRModePtr mode;
if (new_mode) {
mode = xwl_output_find_mode(xwl_output,
new_mode->mode.width,
new_mode->mode.height);
} else {
mode = xwl_output_find_mode(xwl_output, -1, -1);
}
if (!mode)
return FALSE;
xwl_output_set_emulated_mode(xwl_output, GetCurrentClient(), mode, FALSE);
/* A real randr implementation would call:
* RRCrtcNotify(xwl_output->randr_crtc, mode, xwl_output->x, xwl_output->y,
* xwl_output->rotation, NULL, 1, &xwl_output->randr_output);
* here to update the mode reported to clients querying the randr settings
* but that influences *all* clients and we do randr mode change emulation
* on a per client basis. So we just return success here.
*/
return TRUE;
}
static Bool
xwl_randr_crtc_set_gamma(ScreenPtr pScreen, RRCrtcPtr crtc)
{
return TRUE;
}
static Bool
xwl_randr_crtc_get_gamma(ScreenPtr pScreen, RRCrtcPtr crtc)
{
return TRUE;
}
static Bool
xwl_randr_output_set_property(ScreenPtr pScreen,
RROutputPtr output,
Atom property,
RRPropertyValuePtr value)
{
return TRUE;
}
static Bool
xwl_output_validate_mode(ScreenPtr pScreen,
RROutputPtr output,
RRModePtr mode)
{
return TRUE;
}
static void
xwl_randr_mode_destroy(ScreenPtr pScreen, RRModePtr mode)
{
return;
}
#endif
Bool
xwl_screen_init_output(struct xwl_screen *xwl_screen)
{
rrScrPrivPtr rp;
if (!RRScreenInit(xwl_screen->screen))
return FALSE;
RRScreenSetSizeRange(xwl_screen->screen, 16, 16, 32767, 32767);
rp = rrGetScrPriv(xwl_screen->screen);
rp->rrGetInfo = xwl_randr_get_info;
#if RANDR_10_INTERFACE
rp->rrSetConfig = xwl_randr_set_config;
#endif
#if RANDR_12_INTERFACE
rp->rrScreenSetSize = xwl_randr_screen_set_size;
rp->rrCrtcSet = xwl_randr_crtc_set;
rp->rrCrtcSetGamma = xwl_randr_crtc_set_gamma;
rp->rrCrtcGetGamma = xwl_randr_crtc_get_gamma;
rp->rrOutputSetProperty = xwl_randr_output_set_property;
rp->rrOutputValidateMode = xwl_output_validate_mode;
rp->rrModeDestroy = xwl_randr_mode_destroy;
#endif
return TRUE;
}
static void
xwl_output_get_xdg_output(struct xwl_output *xwl_output)
{
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
xwl_output->xdg_output =
zxdg_output_manager_v1_get_xdg_output (xwl_screen->xdg_output_manager,
xwl_output->output);
zxdg_output_v1_add_listener(xwl_output->xdg_output,
&xdg_output_listener,
xwl_output);
}
void
xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen)
{
struct xwl_output *it;
assert(xwl_screen->xdg_output_manager);
xorg_list_for_each_entry(it, &xwl_screen->output_list, link)
xwl_output_get_xdg_output(it);
}

View File

@ -1,82 +0,0 @@
/*
* Copyright © 2011-2014 Intel Corporation
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the
* copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#ifndef XWAYLAND_OUTPUT_H
#define XWAYLAND_OUTPUT_H
#include <xwayland-config.h>
#include <wayland-client.h>
#include <dix.h>
#include <input.h>
#include <randrstr.h>
#include "xwayland-types.h"
struct xwl_output {
struct xorg_list link;
struct wl_output *output;
struct zxdg_output_v1 *xdg_output;
uint32_t server_output_id;
struct xwl_screen *xwl_screen;
RROutputPtr randr_output;
RRCrtcPtr randr_crtc;
int32_t x, y, width, height, refresh;
Rotation rotation;
Bool wl_output_done;
Bool xdg_output_done;
};
/* Per client per output emulated randr/vidmode resolution info. */
struct xwl_emulated_mode {
uint32_t server_output_id;
int32_t width;
int32_t height;
Bool from_vidmode;
};
Bool xwl_screen_init_output(struct xwl_screen *xwl_screen);
struct xwl_output *xwl_output_create(struct xwl_screen *xwl_screen,
uint32_t id);
void xwl_output_destroy(struct xwl_output *xwl_output);
void xwl_output_remove(struct xwl_output *xwl_output);
struct xwl_emulated_mode *xwl_output_get_emulated_mode_for_client(
struct xwl_output *xwl_output, ClientPtr client);
RRModePtr xwl_output_find_mode(struct xwl_output *xwl_output,
int32_t width, int32_t height);
void xwl_output_set_emulated_mode(struct xwl_output *xwl_output,
ClientPtr client, RRModePtr mode,
Bool from_vidmode);
void xwl_output_set_window_randr_emu_props(struct xwl_screen *xwl_screen,
WindowPtr window);
void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen);
#endif /* XWAYLAND_OUTPUT_H */

View File

@ -1,123 +0,0 @@
/*
* Copyright © 2014 Intel Corporation
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the
* copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#include <xwayland-config.h>
#include <X11/X.h>
#include "os.h"
#include "privates.h"
#include "dix.h"
#include "fb.h"
#include "pixmapstr.h"
#include "xwayland-types.h"
#include "xwayland-pixmap.h"
#include "xwayland-window-buffers.h"
static DevPrivateKeyRec xwl_pixmap_private_key;
static DevPrivateKeyRec xwl_pixmap_cb_private_key;
struct xwl_pixmap_buffer_release_callback {
xwl_buffer_release_cb callback;
void *data;
};
void
xwl_pixmap_set_private(PixmapPtr pixmap, struct xwl_pixmap *xwl_pixmap)
{
dixSetPrivate(&pixmap->devPrivates, &xwl_pixmap_private_key, xwl_pixmap);
}
struct xwl_pixmap *
xwl_pixmap_get(PixmapPtr pixmap)
{
return dixLookupPrivate(&pixmap->devPrivates, &xwl_pixmap_private_key);
}
Bool
xwl_pixmap_set_buffer_release_cb(PixmapPtr pixmap,
xwl_buffer_release_cb func, void *data)
{
struct xwl_pixmap_buffer_release_callback *xwl_pixmap_buffer_release_callback;
xwl_pixmap_buffer_release_callback = dixLookupPrivate(&pixmap->devPrivates,
&xwl_pixmap_cb_private_key);
if (xwl_pixmap_buffer_release_callback == NULL) {
xwl_pixmap_buffer_release_callback =
calloc(1, sizeof (struct xwl_pixmap_buffer_release_callback));
if (xwl_pixmap_buffer_release_callback == NULL) {
ErrorF("Failed to allocate pixmap callback data\n");
return FALSE;
}
dixSetPrivate(&pixmap->devPrivates, &xwl_pixmap_cb_private_key,
xwl_pixmap_buffer_release_callback);
}
xwl_pixmap_buffer_release_callback->callback = func;
xwl_pixmap_buffer_release_callback->data = data;
return TRUE;
}
void
xwl_pixmap_del_buffer_release_cb(PixmapPtr pixmap)
{
struct xwl_pixmap_buffer_release_callback *xwl_pixmap_buffer_release_callback;
xwl_pixmap_buffer_release_callback = dixLookupPrivate(&pixmap->devPrivates,
&xwl_pixmap_cb_private_key);
if (xwl_pixmap_buffer_release_callback) {
dixSetPrivate(&pixmap->devPrivates, &xwl_pixmap_cb_private_key, NULL);
free(xwl_pixmap_buffer_release_callback);
}
}
void
xwl_pixmap_buffer_release_cb(void *data, struct wl_buffer *wl_buffer)
{
PixmapPtr pixmap = data;
struct xwl_pixmap_buffer_release_callback *xwl_pixmap_buffer_release_callback;
xwl_pixmap_buffer_release_callback = dixLookupPrivate(&pixmap->devPrivates,
&xwl_pixmap_cb_private_key);
if (xwl_pixmap_buffer_release_callback)
(*xwl_pixmap_buffer_release_callback->callback)
(xwl_pixmap_buffer_release_callback->data);
}
Bool
xwl_pixmap_init(void)
{
if (!dixRegisterPrivateKey(&xwl_pixmap_private_key, PRIVATE_PIXMAP, 0))
return FALSE;
if (!dixRegisterPrivateKey(&xwl_pixmap_cb_private_key, PRIVATE_PIXMAP, 0))
return FALSE;
return TRUE;
}

View File

@ -1,47 +0,0 @@
/*
* Copyright © 2014 Intel Corporation
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the
* copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#ifndef XWAYLAND_PIXMAP_H
#define XWAYLAND_PIXMAP_H
#include <xwayland-config.h>
#include <wayland-client.h>
#include "pixmapstr.h"
/* This is an opaque structure implemented in the different backends */
struct xwl_pixmap;
typedef void (*xwl_buffer_release_cb) (void *data);
void xwl_pixmap_set_private(PixmapPtr pixmap, struct xwl_pixmap *xwl_pixmap);
struct xwl_pixmap *xwl_pixmap_get(PixmapPtr pixmap);
Bool xwl_pixmap_set_buffer_release_cb(PixmapPtr pixmap,
xwl_buffer_release_cb func, void *data);
void xwl_pixmap_del_buffer_release_cb(PixmapPtr pixmap);
void xwl_pixmap_buffer_release_cb(void *data, struct wl_buffer *wl_buffer);
Bool xwl_pixmap_init(void);
#endif /* XWAYLAND_PIXMAP_H */

View File

@ -1,965 +0,0 @@
/*
* Copyright © 2018 Roman Gilg
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the
* copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#include <xwayland-config.h>
#include <windowstr.h>
#include <present.h>
#include "xwayland-present.h"
#include "xwayland-screen.h"
#include "xwayland-window.h"
#include "xwayland-pixmap.h"
#include "glamor.h"
#define XWL_PRESENT_CAPS PresentCapabilityAsync
/*
* When not flipping let Present copy with 60fps.
* When flipping wait on frame_callback, otherwise
* the surface is not visible, in this case update
* with long interval.
*/
#define TIMER_LEN_COPY 17 // ~60fps
#define TIMER_LEN_FLIP 1000 // 1fps
static DevPrivateKeyRec xwl_present_window_private_key;
static struct xwl_present_window *
xwl_present_window_priv(WindowPtr window)
{
return dixGetPrivate(&window->devPrivates,
&xwl_present_window_private_key);
}
static struct xwl_present_window *
xwl_present_window_get_priv(WindowPtr window)
{
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
if (xwl_present_window == NULL) {
xwl_present_window = calloc (1, sizeof (struct xwl_present_window));
if (!xwl_present_window)
return NULL;
xwl_present_window->msc = 1;
xwl_present_window->ust = GetTimeInMicros();
xorg_list_init(&xwl_present_window->frame_callback_list);
xorg_list_init(&xwl_present_window->wait_list);
xorg_list_init(&xwl_present_window->flip_queue);
xorg_list_init(&xwl_present_window->idle_queue);
dixSetPrivate(&window->devPrivates,
&xwl_present_window_private_key,
xwl_present_window);
}
return xwl_present_window;
}
static struct xwl_present_event *
xwl_present_event_from_id(uint64_t event_id)
{
return (struct xwl_present_event*)(uintptr_t)event_id;
}
static void
xwl_present_free_timer(struct xwl_present_window *xwl_present_window)
{
TimerFree(xwl_present_window->frame_timer);
xwl_present_window->frame_timer = NULL;
}
static CARD32
xwl_present_timer_callback(OsTimerPtr timer,
CARD32 time,
void *arg);
static present_vblank_ptr
xwl_present_get_pending_flip(struct xwl_present_window *xwl_present_window)
{
present_vblank_ptr flip_pending;
if (xorg_list_is_empty(&xwl_present_window->flip_queue))
return NULL;
flip_pending = xorg_list_first_entry(&xwl_present_window->flip_queue, present_vblank_rec,
event_queue);
if (flip_pending->queued)
return NULL;
return flip_pending;
}
static inline Bool
xwl_present_has_pending_events(struct xwl_present_window *xwl_present_window)
{
present_vblank_ptr flip_pending = xwl_present_get_pending_flip(xwl_present_window);
return (flip_pending && flip_pending->sync_flip) ||
!xorg_list_is_empty(&xwl_present_window->wait_list);
}
static void
xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
{
if (xwl_present_has_pending_events(xwl_present_window)) {
CARD32 timeout;
if (!xorg_list_is_empty(&xwl_present_window->frame_callback_list))
timeout = TIMER_LEN_FLIP;
else
timeout = TIMER_LEN_COPY;
xwl_present_window->frame_timer = TimerSet(xwl_present_window->frame_timer,
0, timeout,
&xwl_present_timer_callback,
xwl_present_window);
} else {
xwl_present_free_timer(xwl_present_window);
}
}
static void
xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc);
static uint32_t
xwl_present_query_capabilities(present_screen_priv_ptr screen_priv)
{
return XWL_PRESENT_CAPS;
}
static int
xwl_present_get_ust_msc(ScreenPtr screen,
WindowPtr present_window,
uint64_t *ust,
uint64_t *msc)
{
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
if (!xwl_present_window)
return BadAlloc;
*ust = xwl_present_window->ust;
*msc = xwl_present_window->msc;
return Success;
}
/*
* When the wait fence or previous flip is completed, it's time
* to re-try the request
*/
static void
xwl_present_re_execute(present_vblank_ptr vblank)
{
uint64_t ust = 0, crtc_msc = 0;
(void) xwl_present_get_ust_msc(vblank->screen, vblank->window, &ust, &crtc_msc);
xwl_present_execute(vblank, ust, crtc_msc);
}
static void
xwl_present_flip_try_ready(struct xwl_present_window *xwl_present_window)
{
present_vblank_ptr vblank;
xorg_list_for_each_entry(vblank, &xwl_present_window->flip_queue, event_queue) {
if (vblank->queued) {
xwl_present_re_execute(vblank);
return;
}
}
}
static void
xwl_present_release_pixmap(struct xwl_present_event *event)
{
if (!event->pixmap)
return;
xwl_pixmap_del_buffer_release_cb(event->pixmap);
dixDestroyPixmap(event->pixmap, event->pixmap->drawable.id);
event->pixmap = NULL;
}
static void
xwl_present_free_event(struct xwl_present_event *event)
{
xwl_present_release_pixmap(event);
xorg_list_del(&event->vblank.event_queue);
present_vblank_destroy(&event->vblank);
}
static void
xwl_present_free_idle_vblank(present_vblank_ptr vblank)
{
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
xwl_present_free_event(xwl_present_event_from_id((uintptr_t)vblank));
}
static WindowPtr
xwl_present_toplvl_pixmap_window(WindowPtr window)
{
ScreenPtr screen = window->drawable.pScreen;
PixmapPtr pixmap = (*screen->GetWindowPixmap)(window);
WindowPtr w = window;
WindowPtr next_w;
while(w->parent) {
next_w = w->parent;
if ( (*screen->GetWindowPixmap)(next_w) != pixmap) {
break;
}
w = next_w;
}
return w;
}
static void
xwl_present_flips_stop(WindowPtr window)
{
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
present_vblank_ptr vblank, tmp;
/* Change back to the fast refresh rate */
xwl_present_reset_timer(xwl_present_window);
/* Free any left over idle vblanks */
xorg_list_for_each_entry_safe(vblank, tmp, &xwl_present_window->idle_queue, event_queue)
xwl_present_free_idle_vblank(vblank);
if (xwl_present_window->flip_active) {
xwl_present_free_idle_vblank(xwl_present_window->flip_active);
xwl_present_window->flip_active = NULL;
}
xwl_present_flip_try_ready(xwl_present_window);
}
static void
xwl_present_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
{
WindowPtr window = vblank->window;
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
DebugPresent(("\tn %" PRIu64 " %p %" PRIu64 " %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
vblank->event_id, vblank, vblank->exec_msc, vblank->target_msc,
vblank->pixmap ? vblank->pixmap->drawable.id : 0,
vblank->window ? vblank->window->drawable.id : 0));
assert (&vblank->event_queue == xwl_present_window->flip_queue.next);
xorg_list_del(&vblank->event_queue);
if (xwl_present_window->flip_active) {
struct xwl_present_event *event =
xwl_present_event_from_id((uintptr_t)xwl_present_window->flip_active);
if (!event->pixmap)
xwl_present_free_event(event);
else
/* Put the previous flip in the idle_queue and wait for further notice from
* the Wayland compositor
*/
xorg_list_append(&xwl_present_window->flip_active->event_queue, &xwl_present_window->idle_queue);
}
xwl_present_window->flip_active = vblank;
present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, ust, crtc_msc);
if (vblank->abort_flip)
xwl_present_flips_stop(window);
xwl_present_flip_try_ready(xwl_present_window);
}
static void
xwl_present_update_window_crtc(present_window_priv_ptr window_priv, RRCrtcPtr crtc, uint64_t new_msc)
{
/* Crtc unchanged, no offset. */
if (crtc == window_priv->crtc)
return;
/* No crtc earlier to offset against, just set the crtc. */
if (window_priv->crtc == PresentCrtcNeverSet) {
window_priv->msc_offset = 0;
window_priv->crtc = crtc;
return;
}
/* In window-mode the last correct msc-offset is always kept
* in window-priv struct because msc is saved per window and
* not per crtc as in screen-mode.
*/
window_priv->msc_offset += new_msc - window_priv->msc;
window_priv->crtc = crtc;
}
void
xwl_present_cleanup(WindowPtr window)
{
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
present_window_priv_ptr window_priv = present_window_priv(window);
struct xwl_present_event *event, *tmp;
if (!xwl_present_window)
return;
xorg_list_del(&xwl_present_window->frame_callback_list);
if (xwl_present_window->sync_callback) {
wl_callback_destroy(xwl_present_window->sync_callback);
xwl_present_window->sync_callback = NULL;
}
/* Clear remaining events */
xorg_list_for_each_entry_safe(event, tmp, &window_priv->vblank, vblank.window_list)
xwl_present_free_event(event);
/* Clear timer */
xwl_present_free_timer(xwl_present_window);
/* Remove from privates so we don't try to access it later */
dixSetPrivate(&window->devPrivates,
&xwl_present_window_private_key,
NULL);
free(xwl_present_window);
}
static void
xwl_present_buffer_release(void *data)
{
struct xwl_present_window *xwl_present_window;
struct xwl_present_event *event = data;
present_vblank_ptr vblank;
if (!event)
return;
vblank = &event->vblank;
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
xwl_present_window = xwl_present_window_priv(vblank->window);
if (xwl_present_window->flip_active == vblank ||
xwl_present_get_pending_flip(xwl_present_window) == vblank)
xwl_present_release_pixmap(event);
else
xwl_present_free_event(event);
}
static void
xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
{
present_vblank_ptr flip_pending = xwl_present_get_pending_flip(xwl_present_window);
uint64_t msc = ++xwl_present_window->msc;
present_vblank_ptr vblank, tmp;
xwl_present_window->ust = GetTimeInMicros();
if (flip_pending && flip_pending->sync_flip)
xwl_present_flip_notify_vblank(flip_pending, xwl_present_window->ust, msc);
xorg_list_for_each_entry_safe(vblank, tmp, &xwl_present_window->wait_list, event_queue) {
if (vblank->exec_msc <= msc) {
DebugPresent(("\te %" PRIu64 " ust %" PRIu64 " msc %" PRIu64 "\n",
vblank->event_id, xwl_present_window->ust, msc));
xwl_present_execute(vblank, xwl_present_window->ust, msc);
}
}
}
static CARD32
xwl_present_timer_callback(OsTimerPtr timer,
CARD32 time,
void *arg)
{
struct xwl_present_window *xwl_present_window = arg;
/* If we were expecting a frame callback for this window, it didn't arrive
* in a second. Stop listening to it to avoid double-bumping the MSC
*/
xorg_list_del(&xwl_present_window->frame_callback_list);
xwl_present_msc_bump(xwl_present_window);
xwl_present_reset_timer(xwl_present_window);
return 0;
}
void
xwl_present_frame_callback(struct xwl_present_window *xwl_present_window)
{
xorg_list_del(&xwl_present_window->frame_callback_list);
xwl_present_msc_bump(xwl_present_window);
/* we do not need the timer anymore for this frame,
* reset it for potentially the next one
*/
xwl_present_reset_timer(xwl_present_window);
}
static void
xwl_present_sync_callback(void *data,
struct wl_callback *callback,
uint32_t time)
{
present_vblank_ptr vblank = data;
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(vblank->window);
wl_callback_destroy(xwl_present_window->sync_callback);
xwl_present_window->sync_callback = NULL;
xwl_present_flip_notify_vblank(vblank, xwl_present_window->ust, xwl_present_window->msc);
}
static const struct wl_callback_listener xwl_present_sync_listener = {
xwl_present_sync_callback
};
static RRCrtcPtr
xwl_present_get_crtc(present_screen_priv_ptr screen_priv,
WindowPtr present_window)
{
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
rrScrPrivPtr rr_private;
if (xwl_present_window == NULL)
return NULL;
rr_private = rrGetScrPriv(present_window->drawable.pScreen);
if (rr_private->numCrtcs == 0)
return NULL;
return rr_private->crtcs[0];
}
/*
* Queue an event to report back to the Present extension when the specified
* MSC has passed
*/
static int
xwl_present_queue_vblank(ScreenPtr screen,
WindowPtr present_window,
RRCrtcPtr crtc,
uint64_t event_id,
uint64_t msc)
{
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
struct xwl_window *xwl_window = xwl_window_from_window(present_window);
struct xwl_present_event *event = xwl_present_event_from_id(event_id);
event->vblank.exec_msc = msc;
xorg_list_del(&event->vblank.event_queue);
xorg_list_append(&event->vblank.event_queue, &xwl_present_window->wait_list);
/* If there's a pending frame callback, use that */
if (xwl_window && xwl_window->frame_callback &&
xorg_list_is_empty(&xwl_present_window->frame_callback_list)) {
xorg_list_add(&xwl_present_window->frame_callback_list,
&xwl_window->frame_callback_list);
}
if ((xwl_window && xwl_window->frame_callback) ||
!xwl_present_window->frame_timer)
xwl_present_reset_timer(xwl_present_window);
return Success;
}
/*
* Remove a pending vblank event so that it is not reported
* to the extension
*/
static void
xwl_present_abort_vblank(ScreenPtr screen,
WindowPtr present_window,
RRCrtcPtr crtc,
uint64_t event_id,
uint64_t msc)
{
static Bool called;
if (called)
return;
/* xwl_present_cleanup should have cleaned up everything,
* present_free_window_vblank shouldn't need to call this.
*/
ErrorF("Unexpected call to %s:\n", __func__);
xorg_backtrace();
}
static void
xwl_present_flush(WindowPtr window)
{
glamor_block_handler(window->drawable.pScreen);
}
static Bool
xwl_present_check_flip(RRCrtcPtr crtc,
WindowPtr present_window,
PixmapPtr pixmap,
Bool sync_flip,
RegionPtr valid,
int16_t x_off,
int16_t y_off,
PresentFlipReason *reason)
{
WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(present_window);
struct xwl_window *xwl_window = xwl_window_from_window(present_window);
ScreenPtr screen = pixmap->drawable.pScreen;
if (reason)
*reason = PRESENT_FLIP_REASON_UNKNOWN;
if (!xwl_window)
return FALSE;
if (!crtc)
return FALSE;
/* Source pixmap must align with window exactly */
if (x_off || y_off)
return FALSE;
/* Valid area must contain window (for simplicity for now just never flip when one is set). */
if (valid)
return FALSE;
/* Flip pixmap must have same dimensions as window */
if (present_window->drawable.width != pixmap->drawable.width ||
present_window->drawable.height != pixmap->drawable.height)
return FALSE;
/* Window must be same region as toplevel window */
if ( !RegionEqual(&present_window->winSize, &toplvl_window->winSize) )
return FALSE;
/* Can't flip if window clipped by children */
if (!RegionEqual(&present_window->clipList, &present_window->winSize))
return FALSE;
if (!xwl_glamor_check_flip(pixmap))
return FALSE;
/* Can't flip if the window pixmap doesn't match the xwl_window parent
* window's, e.g. because a client redirected this window or one of its
* parents.
*/
if (screen->GetWindowPixmap(xwl_window->window) != screen->GetWindowPixmap(present_window))
return FALSE;
/*
* We currently only allow flips of windows, that have the same
* dimensions as their xwl_window parent window. For the case of
* different sizes subsurfaces are presumably the way forward.
*/
if (!RegionEqual(&xwl_window->window->winSize, &present_window->winSize))
return FALSE;
return TRUE;
}
/*
* 'window' is being reconfigured. Check to see if it is involved
* in flipping and clean up as necessary.
*/
static void
xwl_present_check_flip_window (WindowPtr window)
{
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
present_window_priv_ptr window_priv = present_window_priv(window);
present_vblank_ptr flip_pending;
present_vblank_ptr flip_active;
present_vblank_ptr vblank;
PresentFlipReason reason;
/* If this window hasn't ever been used with Present, it can't be
* flipping
*/
if (!xwl_present_window || !window_priv)
return;
flip_pending = xwl_present_get_pending_flip(xwl_present_window);
flip_active = xwl_present_window->flip_active;
if (flip_pending) {
if (!xwl_present_check_flip(flip_pending->crtc, flip_pending->window, flip_pending->pixmap,
flip_pending->sync_flip, flip_pending->valid, 0, 0, NULL))
flip_pending->abort_flip = TRUE;
} else if (flip_active) {
if (!xwl_present_check_flip(flip_active->crtc, flip_active->window, flip_active->pixmap,
flip_active->sync_flip, flip_active->valid, 0, 0, NULL))
xwl_present_flips_stop(window);
}
/* Now check any queued vblanks */
xorg_list_for_each_entry(vblank, &window_priv->vblank, window_list) {
if (vblank->queued && vblank->flip &&
!xwl_present_check_flip(vblank->crtc, window, vblank->pixmap,
vblank->sync_flip, vblank->valid, 0, 0, &reason)) {
vblank->flip = FALSE;
vblank->reason = reason;
}
}
}
/*
* Clean up any pending or current flips for this window
*/
static void
xwl_present_clear_window_flip(WindowPtr window)
{
/* xwl_present_cleanup cleaned up everything */
}
static Bool
xwl_present_flip(WindowPtr present_window,
RRCrtcPtr crtc,
uint64_t event_id,
PixmapPtr pixmap,
Bool sync_flip,
RegionPtr damage)
{
struct xwl_window *xwl_window = xwl_window_from_window(present_window);
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(present_window);
BoxPtr damage_box;
struct wl_buffer *buffer;
struct xwl_present_event *event = xwl_present_event_from_id(event_id);
if (!xwl_window)
return FALSE;
buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap);
if (!buffer) {
ErrorF("present: Error getting buffer\n");
return FALSE;
}
damage_box = RegionExtents(damage);
pixmap->refcnt++;
event->pixmap = pixmap;
xwl_pixmap_set_buffer_release_cb(pixmap, xwl_present_buffer_release, event);
/* We can flip directly to the main surface (full screen window without clips) */
wl_surface_attach(xwl_window->surface, buffer, 0, 0);
if (!xwl_window->frame_callback)
xwl_window_create_frame_callback(xwl_window);
if (xorg_list_is_empty(&xwl_present_window->frame_callback_list)) {
xorg_list_add(&xwl_present_window->frame_callback_list,
&xwl_window->frame_callback_list);
}
/* Realign timer */
xwl_present_reset_timer(xwl_present_window);
xwl_surface_damage(xwl_window->xwl_screen, xwl_window->surface,
damage_box->x1 - present_window->drawable.x,
damage_box->y1 - present_window->drawable.y,
damage_box->x2 - damage_box->x1,
damage_box->y2 - damage_box->y1);
wl_surface_commit(xwl_window->surface);
if (!sync_flip) {
xwl_present_window->sync_callback =
wl_display_sync(xwl_window->xwl_screen->display);
wl_callback_add_listener(xwl_present_window->sync_callback,
&xwl_present_sync_listener,
&event->vblank);
}
wl_display_flush(xwl_window->xwl_screen->display);
xwl_window->present_flipped = TRUE;
return TRUE;
}
/*
* Once the required MSC has been reached, execute the pending request.
*
* For requests to actually present something, either blt contents to
* the window pixmap or queue a window buffer swap on the backend.
*
* For requests to just get the current MSC/UST combo, skip that part and
* go straight to event delivery.
*/
static void
xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
{
WindowPtr window = vblank->window;
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
present_vblank_ptr flip_pending = xwl_present_get_pending_flip(xwl_present_window);
xorg_list_del(&vblank->event_queue);
if (present_execute_wait(vblank, crtc_msc))
return;
if (flip_pending && vblank->flip && vblank->pixmap && vblank->window) {
DebugPresent(("\tr %" PRIu64 " %p (pending %p)\n",
vblank->event_id, vblank, flip_pending));
xorg_list_append(&vblank->event_queue, &xwl_present_window->flip_queue);
vblank->flip_ready = TRUE;
return;
}
vblank->queued = FALSE;
if (vblank->pixmap && vblank->window) {
ScreenPtr screen = window->drawable.pScreen;
if (vblank->flip) {
RegionPtr damage;
DebugPresent(("\tf %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
vblank->event_id, vblank, crtc_msc,
vblank->pixmap->drawable.id, vblank->window->drawable.id));
/* Set update region as damaged */
if (vblank->update) {
damage = RegionDuplicate(vblank->update);
/* Translate update region to screen space */
assert(vblank->x_off == 0 && vblank->y_off == 0);
RegionTranslate(damage, window->drawable.x, window->drawable.y);
RegionIntersect(damage, damage, &window->clipList);
} else
damage = RegionDuplicate(&window->clipList);
if (xwl_present_flip(vblank->window, vblank->crtc, vblank->event_id,
vblank->pixmap, vblank->sync_flip, damage)) {
WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(vblank->window);
PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
/* Replace window pixmap with flip pixmap */
#ifdef COMPOSITE
vblank->pixmap->screen_x = old_pixmap->screen_x;
vblank->pixmap->screen_y = old_pixmap->screen_y;
#endif
present_set_tree_pixmap(toplvl_window, old_pixmap, vblank->pixmap);
vblank->pixmap->refcnt++;
dixDestroyPixmap(old_pixmap, old_pixmap->drawable.id);
/* Report damage */
DamageDamageRegion(&vblank->window->drawable, damage);
RegionDestroy(damage);
/* Put pending flip at the flip queue head */
xorg_list_add(&vblank->event_queue, &xwl_present_window->flip_queue);
return;
}
vblank->flip = FALSE;
}
DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
if (flip_pending)
flip_pending->abort_flip = TRUE;
else if (xwl_present_window->flip_active)
xwl_present_flips_stop(window);
present_execute_copy(vblank, crtc_msc);
assert(!vblank->queued);
if (xwl_present_queue_vblank(screen, window, vblank->crtc,
vblank->event_id, crtc_msc + 1)
== Success) {
/* Clear the pixmap field, so this will fall through to present_execute_post next time */
dixDestroyPixmap(vblank->pixmap, vblank->pixmap->drawable.id);
vblank->pixmap = NULL;
return;
}
}
present_execute_post(vblank, ust, crtc_msc);
}
static int
xwl_present_pixmap(WindowPtr window,
PixmapPtr pixmap,
CARD32 serial,
RegionPtr valid,
RegionPtr update,
int16_t x_off,
int16_t y_off,
RRCrtcPtr target_crtc,
SyncFence *wait_fence,
SyncFence *idle_fence,
uint32_t options,
uint64_t target_window_msc,
uint64_t divisor,
uint64_t remainder,
present_notify_ptr notifies,
int num_notifies)
{
uint64_t ust = 0;
uint64_t target_msc;
uint64_t crtc_msc = 0;
int ret;
present_vblank_ptr vblank, tmp;
ScreenPtr screen = window->drawable.pScreen;
present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE);
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
struct xwl_present_event *event;
if (!window_priv)
return BadAlloc;
target_crtc = xwl_present_get_crtc(screen_priv, window);
ret = xwl_present_get_ust_msc(screen, window, &ust, &crtc_msc);
xwl_present_update_window_crtc(window_priv, target_crtc, crtc_msc);
if (ret == Success) {
/* Stash the current MSC away in case we need it later
*/
window_priv->msc = crtc_msc;
}
target_msc = present_get_target_msc(target_window_msc + window_priv->msc_offset,
crtc_msc,
divisor,
remainder,
options);
/*
* Look for a matching presentation already on the list...
*/
if (!update && pixmap) {
xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->vblank, window_list) {
if (!vblank->pixmap)
continue;
if (!vblank->queued)
continue;
if (vblank->target_msc != target_msc)
continue;
present_vblank_scrap(vblank);
if (vblank->flip_ready)
xwl_present_re_execute(vblank);
}
}
event = calloc(1, sizeof(*event));
if (!event)
return BadAlloc;
vblank = &event->vblank;
if (!present_vblank_init(vblank, window, pixmap, serial, valid, update, x_off, y_off,
target_crtc, wait_fence, idle_fence, options, XWL_PRESENT_CAPS,
notifies, num_notifies, target_msc, crtc_msc)) {
present_vblank_destroy(vblank);
return BadAlloc;
}
vblank->event_id = (uintptr_t)event;
/* Xwayland presentations always complete (at least) one frame after they
* are executed
*/
vblank->exec_msc = vblank->target_msc - 1;
vblank->queued = TRUE;
if (crtc_msc < vblank->exec_msc) {
if (xwl_present_queue_vblank(screen, window, target_crtc, vblank->event_id, vblank->exec_msc) == Success)
return Success;
DebugPresent(("present_queue_vblank failed\n"));
}
xwl_present_execute(vblank, ust, crtc_msc);
return Success;
}
void
xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window)
{
/* The pending frame callback may never be called, so drop it and shorten
* the frame timer interval.
*/
xorg_list_del(&xwl_present_window->frame_callback_list);
xwl_present_reset_timer(xwl_present_window);
}
Bool
xwl_present_init(ScreenPtr screen)
{
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
present_screen_priv_ptr screen_priv;
if (!xwl_screen->glamor || !xwl_screen->egl_backend)
return FALSE;
if (!present_screen_register_priv_keys())
return FALSE;
if (present_screen_priv(screen))
return TRUE;
screen_priv = present_screen_priv_init(screen);
if (!screen_priv)
return FALSE;
if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0))
return FALSE;
screen_priv->query_capabilities = xwl_present_query_capabilities;
screen_priv->get_crtc = xwl_present_get_crtc;
screen_priv->check_flip = xwl_present_check_flip;
screen_priv->check_flip_window = xwl_present_check_flip_window;
screen_priv->clear_window_flip = xwl_present_clear_window_flip;
screen_priv->present_pixmap = xwl_present_pixmap;
screen_priv->queue_vblank = xwl_present_queue_vblank;
screen_priv->flush = xwl_present_flush;
screen_priv->re_execute = xwl_present_re_execute;
screen_priv->abort_vblank = xwl_present_abort_vblank;
return TRUE;
}

View File

@ -1,67 +0,0 @@
/*
* Copyright © 2018 Roman Gilg
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of the
* copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#ifndef XWAYLAND_PRESENT_H
#define XWAYLAND_PRESENT_H
#include <xwayland-config.h>
#include <dix.h>
#include <present_priv.h>
#include "xwayland-types.h"
#ifdef GLAMOR_HAS_GBM
struct xwl_present_window {
struct xorg_list frame_callback_list;
uint64_t msc;
uint64_t ust;
OsTimerPtr frame_timer;
struct wl_callback *sync_callback;
struct xorg_list wait_list;
struct xorg_list flip_queue;
struct xorg_list idle_queue;
present_vblank_ptr flip_active;
};
struct xwl_present_event {
present_vblank_rec vblank;
PixmapPtr pixmap;
};
void xwl_present_frame_callback(struct xwl_present_window *xwl_present_window);
Bool xwl_present_init(ScreenPtr screen);
void xwl_present_cleanup(WindowPtr window);
void xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window);
#endif /* GLAMOR_HAS_GBM */
#endif /* XWAYLAND_PRESENT_H */

Some files were not shown because too many files have changed in this diff Show More