Compare commits

...

92 commits

Author SHA1 Message Date
Adam Jackson
971d418113 xserver 1.20.3
Signed-off-by: Adam Jackson <ajax@redhat.com>
2018-10-25 09:18:06 -04:00
Matthieu Herrb
da15c74139 LogFilePrep: add a comment to the unsafe format string.
CVE-2018-14665 also made it possible to exploit this to access
memory. With -logfile forbidden when running with elevated privileges
this is no longer an issue.

Signed-off-by: Matthieu Herrb <matthieu@herrb.eu>
Reviewed-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit 248d164eae)
2018-10-25 09:18:06 -04:00
Matthieu Herrb
8a59e3b7db Disable -logfile and -modulepath when running with elevated privileges
Could cause privilege elevation and/or arbitrary files overwrite, when
the X server is running with elevated privileges (ie when Xorg is
installed with the setuid bit set and started by a non-root user).

CVE-2018-14665

Issue reported by Narendra Shinde and Red Hat.

Signed-off-by: Matthieu Herrb <matthieu@herrb.eu>
Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit 50c0cf885a)
2018-10-25 09:18:06 -04:00
Peter Hutterer
cfc3dec09e xfree86: fix readlink call
Misplaced parenthesis caused us to compare the sizeof, not the readlink return
value.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit bd5fe7593f)
2018-10-16 10:22:05 -04:00
Adam Jackson
2a0c6c15c3 xserver 1.20.2
Signed-off-by: Adam Jackson <ajax@redhat.com>
2018-10-15 11:17:35 -04:00
Adam Jackson
f5dc787fc9 fbdevhw: Refuse to touch PCI devices on the fallback probe path
Fixes: https://gitlab.freedesktop.org/xorg/driver/xf86-video-fbdev/issues/9
Signed-off-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit fc78bcca21)
2018-10-12 11:35:42 -04:00
Adam Jackson
4795c069a5 glamor/egl: Avoid crashing on broken configurations
0a9415cf apparently can tickle bugs in the GL stack where glGetString
returns NULL, presumably because the eglMakeCurrent() didn't manage to
actually install a dispatch table and you're hitting a stub function.
That's clearly not our bug, but if it happens we should at least not
crash. Notice this case and fail gently.

Signed-off-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit af151895f3)
2018-10-12 11:35:07 -04:00
Adam Jackson
1e3c5d614e glamor_egl: Don't initialize on llvmpipe
Mesa started supporting GL_OES_EGL_image on llvmpipe in 17.3, after this
commit:

    commit bbdeddd5fd0b797e1e281f058338b3da4d98029d
    Author: Gurchetan Singh <gurchetansingh@chromium.org>
    Date:   Tue Aug 1 14:49:33 2017 -0700

        st/dri: add drisw image extension

That's pretty cool, but it means glamor now thinks it can initialize on
llvmpipe. This is almost certainly not what anyone wants, as glamor on
llvmpipe is pretty much uniformly slower than fb.

This fixes both Xorg and Xwayland to refuse glamor in such a setup.
Xephyr is left alone, both because glamor is not the default there and
because Xephyr+glamor+llvmpipe is one of the easier ways to get xts to
exercise glamor.

The (very small) downside of this change is that you lose DRI3 support.
This wouldn't have helped you very much (since an lp glamor blit is
slower than a pixman blit), but it would eliminate the PutImage overhead
for llvmpipe's glXSwapBuffers. A future change should add DRI3 support
for the fb-only case.

Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit 0a9415cf79)
2018-10-12 11:35:00 -04:00
Alexander Volkov
b58aa8ed9b os/xdmcp: Don't create a new socket in XdmcpReset()
xdmcpSocket survives during the reset, there is no
need to create a new one.

This commit restores logic that was broken by
49c0f2413d in Xorg 1.19.

Signed-off-by: Alexander Volkov <a.volkov@rusbitech.ru>
(cherry picked from commit 32677ce03d)
2018-10-05 09:14:18 +02:00
Pierre Ossman
b1215fb075 Switch automatic composite update to WorkQueue
It is currently (ab)using the screen BlockHandler callback to do
this. But this can cause problems with other extension as their
block handlers might have executed before Composite's. And the
operations Composite does might result in them wanting to change
timeouts.

Practically this caused problems for TigerVNC's VNC extension which
failed to send out updates for Composite's screen updates.

(cherry picked from commit 1bd5d0a53c)
2018-10-05 09:14:18 +02:00
Adam Jackson
a41b6ef224 modesetting: Don't free(dst) in drmmode_prop_info_copy
The destination is always either on the stack or in the middle of some
struct.

Signed-off-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit 43a0f9a5db)
2018-10-05 09:14:18 +02:00
Cedric Roux
9403335910 miext/damage: take care of the coordinate mode in damagePolyPoint
The mode (CoordModeOrigin or CoordModePrevious) was not taken into
account when computing the box. The result was a bad drawing of
points in some situations (on my hardware/software configuration,
calling XDrawString followed by XDrawPoints in the mode
CoordModePrevious).

Signed-off-by: Cedric Roux <sed@free.fr>
Signed-off-by: Eric Anholt <eric@anholt.net>
(cherry picked from commit bc36594e0e)
2018-10-04 17:27:15 +02:00
Olivier Fourdan
c26a47b4f2 xwayland: Use double for xwl_tablet_tool
So we do not lose subpixel precision in Xwayland.

Suggested-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Closes: https://gitlab.freedesktop.org/libinput/libinput/issues/138
(cherry picked from commit 734b2d6907)
2018-10-04 17:27:08 +02:00
Adam Jackson
fb01b238c6 xfree86: Fix Option "MaxClients" validation
The old code would not in fact validate the option value, though it
might complain about it in the log. It also didn't let you set some
legal values that the -maxclients command line option would.

Signed-off-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit 7d689f049c)
2018-10-04 17:27:03 +02:00
Dave Airlie
cc4051ad6a devices: break after finding and removing device from lists
Coverity complains about a use after free in here after the
freeing, I can't follow the linked list so well, but whot
says the device can only be on one list once, so break should
fix it.

Signed-off-by: Dave Airlie <airlied@redhat.com>
(cherry picked from commit ba0f5d854f)
2018-10-04 17:26:57 +02:00
Dave Airlie
64a7aac257 mibltblt: free prgnSrcClip on error path.
Pointed out by coverity.

Signed-off-by: Dave Airlie <airlied@redhat.com>
(cherry picked from commit c4591ea171)
2018-10-04 17:26:51 +02:00
Dave Airlie
fcbdb7c8b0 xkb: fix what looks to be a copy-paste error with first vs firstMM
Pointed out by coverity.

Signed-off-by: Dave Airlie <airlied@redhat.com>
(cherry picked from commit 7583939512)
2018-10-04 17:26:44 +02:00
Dave Airlie
83ef02839c posix_tty: free leak of xf86SetStrOption return value.
Pointed out by coverity.

Signed-off-by: Dave Airlie <airlied@redhat.com>
(cherry picked from commit cad3a1a82d)
2018-10-04 17:26:26 +02:00
Dave Airlie
66d36010a3 modesetting: get pEnt after error checks
This saves us having to make sure we clean it up.

Pointed out by coverity.

Signed-off-by: Dave Airlie <airlied@redhat.com>
(cherry picked from commit b6c29a881e)
2018-10-04 17:26:20 +02:00
Dave Airlie
795c58a1fe glamor: fix leak of fs_getcolor_source.
This is created using XNFstrdup, so it needs to be freed.

Pointed out by coverity.
Signed-off-by: Dave Airlie <airlied@redhat.com>
(cherry picked from commit f0a5c0d1fd)
2018-10-04 17:26:15 +02:00
Dave Airlie
bb384d0b11 fboverlay: move bpp checks above malloc
Avoids having to free the malloced object.

Pointed out by coverity.

Signed-off-by: Dave Airlie <airlied@redhat.com>
(cherry picked from commit c7fa6a0a0d)
2018-10-04 17:26:09 +02:00
Dave Airlie
26a83f9833 xi: free modifiers_failed on error path. (v2)
Pointed out by coverity.

v2: set modifies_failed to NULL at start (whot)

Signed-off-by: Dave Airlie <airlied@redhat.com>
(cherry picked from commit 51ae6126dc)
2018-10-04 17:26:04 +02:00
Dave Airlie
bdeab7863e shm: move shmsize verify before allocating the drawable.
Otherwise if the VERIFY_SHMSIZE macro fails we leak the drawables
we allocated earlier.

Noticed by coverity scan.

Signed-off-by: Dave Airlie <airlied@redhat.com>
(cherry picked from commit 3439929c51)
2018-10-04 17:25:59 +02:00
Adam Jackson
8e646ca985 modesetting: Document Option "DoubleShadow" in the man page
Signed-off-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit c4f3e42fe3)
2018-10-04 17:25:52 +02:00
Adam Jackson
fdb80a327c modesetting: Lie less in the man page
We don't support 8bpp, and we do have acceleration.

Signed-off-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit 0dc2c419e1)
2018-10-04 17:25:30 +02:00
Olivier Fourdan
cffac815b9 xwayland: Remove xwl_present_window from privates on cleanup
Xwayland's `xwl_destroy_window()` invokes `xwl_present_cleanup()`
before the common `DestroyWindow()`.

But then `DestroyWindow()` calls `present_destroy_window()` which will
possibly end up in `xwl_present_abort_vblank()` which will try to access
data that was previously freed by `xwl_present_cleanup()`:

  Invalid read of size 8
     at 0x434184: xwl_present_abort_vblank (xwayland-present.c:378)
     by 0x53785B: present_wnmd_abort_vblank (present_wnmd.c:651)
     by 0x53695A: present_free_window_vblank (present_screen.c:87)
     by 0x53695A: present_destroy_window (present_screen.c:152)
     by 0x42A90D: xwl_destroy_window (xwayland.c:653)
     by 0x584298: compDestroyWindow (compwindow.c:613)
     by 0x53CEE3: damageDestroyWindow (damage.c:1570)
     by 0x4F1BB8: DbeDestroyWindow (dbe.c:1326)
     by 0x46F7F6: FreeWindowResources (window.c:1031)
     by 0x472847: DeleteWindow (window.c:1099)
     by 0x46B54C: doFreeResource (resource.c:880)
     by 0x46C706: FreeClientResources (resource.c:1146)
     by 0x446ADE: CloseDownClient (dispatch.c:3473)
   Address 0x182abde0 is 80 bytes inside a block of size 112 free'd
     at 0x4C2FDAC: free (vg_replace_malloc.c:530)
     by 0x42A937: xwl_destroy_window (xwayland.c:647)
     by 0x584298: compDestroyWindow (compwindow.c:613)
     by 0x53CEE3: damageDestroyWindow (damage.c:1570)
     by 0x4F1BB8: DbeDestroyWindow (dbe.c:1326)
     by 0x46F7F6: FreeWindowResources (window.c:1031)
     by 0x472847: DeleteWindow (window.c:1099)
     by 0x46B54C: doFreeResource (resource.c:880)
     by 0x46C706: FreeClientResources (resource.c:1146)
     by 0x446ADE: CloseDownClient (dispatch.c:3473)
     by 0x446DA5: ProcKillClient (dispatch.c:3279)
     by 0x4476AF: Dispatch (dispatch.c:479)
   Block was alloc'd at
     at 0x4C30B06: calloc (vg_replace_malloc.c:711)
     by 0x433F46: xwl_present_window_get_priv (xwayland-present.c:54)
     by 0x434228: xwl_present_get_crtc (xwayland-present.c:302)
     by 0x539728: proc_present_query_capabilities (present_request.c:227)
     by 0x4476AF: Dispatch (dispatch.c:479)
     by 0x44B5B5: dix_main (main.c:276)
     by 0x75F611A: (below main) (libc-start.c:308)

This is because `xwl_present_cleanup()` frees the memory but does not
remove it from the window's privates, and `xwl_present_abort_vblank()`
will still find it and hence try to access that freed memory...

Remove `xwl_present_window` from window's privates on cleanup so that no
other function can find and reuse that data once it's freed.

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1616269
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit 3f31f56929)
2018-10-04 17:25:24 +02:00
Lionel Landwerlin
8dd7173eeb xwayland: fix access to invalid pointer
xwl_output->randr_crtc is used in the update_screen_size() function :

==5331== Invalid read of size 4
==5331==    at 0x15263D: update_screen_size (xwayland-output.c:190)
==5331==    by 0x152C48: xwl_output_remove (xwayland-output.c:413)
==5331==    by 0x6570FCD: ffi_call_unix64 (in /usr/lib/x86_64-linux-gnu/libffi.so.6.0.4)
==5331==    by 0x657093E: ffi_call (in /usr/lib/x86_64-linux-gnu/libffi.so.6.0.4)
==5331==    by 0x4DDB183: ??? (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.3.0)
==5331==    by 0x4DD79D8: ??? (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.3.0)
==5331==    by 0x4DD8EA3: wl_display_dispatch_queue_pending (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.3.0)
==5331==    by 0x14BCCA: xwl_read_events (xwayland.c:814)
==5331==    by 0x2AC0D0: ospoll_wait (ospoll.c:651)
==5331==    by 0x2A5322: WaitForSomething (WaitFor.c:208)
==5331==    by 0x27574B: Dispatch (dispatch.c:421)
==5331==    by 0x279945: dix_main (main.c:276)
==5331==  Address 0x1aacb5f4 is 36 bytes inside a block of size 154 free'd
==5331==    at 0x48369EB: free (vg_replace_malloc.c:530)
==5331==    by 0x1F8AE8: RROutputDestroyResource (rroutput.c:421)
==5331==    by 0x29A2AC: doFreeResource (resource.c:880)
==5331==    by 0x29AE5B: FreeResource (resource.c:910)
==5331==    by 0x152BE0: xwl_output_remove (xwayland-output.c:408)
==5331==    by 0x6570FCD: ffi_call_unix64 (in /usr/lib/x86_64-linux-gnu/libffi.so.6.0.4)
==5331==    by 0x657093E: ffi_call (in /usr/lib/x86_64-linux-gnu/libffi.so.6.0.4)
==5331==    by 0x4DDB183: ??? (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.3.0)
==5331==    by 0x4DD79D8: ??? (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.3.0)
==5331==    by 0x4DD8EA3: wl_display_dispatch_queue_pending (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.3.0)
==5331==    by 0x14BCCA: xwl_read_events (xwayland.c:814)
==5331==    by 0x2AC0D0: ospoll_wait (ospoll.c:651)
==5331==  Block was alloc'd at
==5331==    at 0x48357BF: malloc (vg_replace_malloc.c:299)
==5331==    by 0x1F93E0: RROutputCreate (rroutput.c:83)
==5331==    by 0x152A75: xwl_output_create (xwayland-output.c:361)
==5331==    by 0x14BE59: registry_global (xwayland.c:764)
==5331==    by 0x6570FCD: ffi_call_unix64 (in /usr/lib/x86_64-linux-gnu/libffi.so.6.0.4)
==5331==    by 0x657093E: ffi_call (in /usr/lib/x86_64-linux-gnu/libffi.so.6.0.4)
==5331==    by 0x4DDB183: ??? (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.3.0)
==5331==    by 0x4DD79D8: ??? (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.3.0)
==5331==    by 0x4DD8EA3: wl_display_dispatch_queue_pending (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.3.0)
==5331==    by 0x14BCCA: xwl_read_events (xwayland.c:814)
==5331==    by 0x2AC0D0: ospoll_wait (ospoll.c:651)
==5331==    by 0x2A5322: WaitForSomething (WaitFor.c:208)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
(cherry picked from commit 53ce2ba0a1)
2018-10-04 17:25:19 +02:00
Olivier Fourdan
1191b23f94 glx: check for indirect context in CreateContextAttribsARB()
Commit 99f0365b "Add a command line argument for disabling indirect GLX"
added a test to check if indirect context are enabled in
`DoCreateContext()` but `__glXDisp_CreateContextAttribsARB()` doesn't
use `DoCreateContext()` and doesn't check if indirect context is
enabled.

As a result, clients can still manage to create indirect contexts using
`glXCreateContextAttribsARB()` even if indirect contexts are disabled,
which can possibly crash Xservers such as Xwayland or Xephyr when the
context is destroyed.

To avoid the issue, check for `enableIndirectGLX` in
`__glXDisp_CreateContextAttribsARB()` as well.

Fixes: 99f0365b "Add a command line argument for disabling indirect GLX"
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107508
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit 75448671ab)
2018-10-04 17:25:13 +02:00
Lionel Landwerlin
1b0db2c742 present: fix freed pointer access
When a vblank has been marked as aborted, it's going to be free in the
flip_notify function when stopped. We can't notify it after it's
stopped because the pointer is invalid.

Valgrind backtrace:

==5331== Invalid read of size 8
==5331==    at 0x212B4D: present_vblank_notify (present_vblank.c:34)
==5331==    by 0x21439B: present_wnmd_flip_notify (present_wnmd.c:194)
==5331==    by 0x21439B: present_wnmd_event_notify (present_wnmd.c:228)
==5331==    by 0x156216: xwl_present_sync_callback (xwayland-present.c:282)
==5331==    by 0x6570FCD: ffi_call_unix64 (in /usr/lib/x86_64-linux-gnu/libffi.so.6.0.4)
==5331==    by 0x657093E: ffi_call (in /usr/lib/x86_64-linux-gnu/libffi.so.6.0.4)
==5331==    by 0x4DDB183: ??? (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.3.0)
==5331==    by 0x4DD79D8: ??? (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.3.0)
==5331==    by 0x4DD8EA3: wl_display_dispatch_queue_pending (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.3.0)
==5331==    by 0x14BCCA: xwl_read_events (xwayland.c:814)
==5331==    by 0x2AC0D0: ospoll_wait (ospoll.c:651)
==5331==    by 0x2A5322: WaitForSomething (WaitFor.c:208)
==5331==    by 0x27574B: Dispatch (dispatch.c:421)
==5331==  Address 0x1b44dc98 is 40 bytes inside a block of size 184 free'd
==5331==    at 0x48369EB: free (vg_replace_malloc.c:530)
==5331==    by 0x213B0A: present_wnmd_free_idle_vblanks (present_wnmd.c:118)
==5331==    by 0x213B0A: present_wnmd_flips_stop (present_wnmd.c:161)
==5331==    by 0x2143EF: present_wnmd_flip_notify (present_wnmd.c:192)
==5331==    by 0x2143EF: present_wnmd_event_notify (present_wnmd.c:228)
==5331==    by 0x156216: xwl_present_sync_callback (xwayland-present.c:282)
==5331==    by 0x6570FCD: ffi_call_unix64 (in /usr/lib/x86_64-linux-gnu/libffi.so.6.0.4)
==5331==    by 0x657093E: ffi_call (in /usr/lib/x86_64-linux-gnu/libffi.so.6.0.4)
==5331==    by 0x4DDB183: ??? (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.3.0)
==5331==    by 0x4DD79D8: ??? (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.3.0)
==5331==    by 0x4DD8EA3: wl_display_dispatch_queue_pending (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.3.0)
==5331==    by 0x14BCCA: xwl_read_events (xwayland.c:814)
==5331==    by 0x2AC0D0: ospoll_wait (ospoll.c:651)
==5331==    by 0x2A5322: WaitForSomething (WaitFor.c:208)
==5331==  Block was alloc'd at
==5331==    at 0x48377D5: calloc (vg_replace_malloc.c:711)
==5331==    by 0x212D9F: present_vblank_create (present_vblank.c:69)
==5331==    by 0x214014: present_wnmd_pixmap (present_wnmd.c:610)
==5331==    by 0x21576C: proc_present_pixmap (present_request.c:150)
==5331==    by 0x27599D: Dispatch (dispatch.c:479)
==5331==    by 0x279945: dix_main (main.c:276)
==5331==    by 0x633AB16: (below main) (libc-start.c:310)

v2: Still notify aborted flips (Roman)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107314
Reviewed-by: Roman Gilg <subdiff@gmail.com>
Tested-by: Roman Gilg <subdiff@gmail.com>
(cherry picked from commit ce271535ad)
2018-10-04 17:25:02 +02:00
Scott Anderson
48300a7775 xwayland: use wayland axis_discrete event
This prevents multiple scroll events happening for wayland compositors
which send axis values other than 10. For example, libinput will
typically return 15 for each scroll wheel step, and if a wayland
compositor sends those to xwayland without normalising them, 2 scroll
wheel steps will end up as 3 xorg scroll events. By listening for the
discrete_axis event, this will now correctly send only 2 xorg scroll
events.

The wayland protocol gurantees that there will always be an axis event
following an axis_discrete event. However, it does not gurantee that
other events (including other axis_discrete+axis pairs) will not happen
in between them. So we must keep a list of outstanding axis_discrete
events.

Signed-off-by: Scott Anderson <scott@anderso.nz>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit cd285922cd)
2018-10-04 17:24:50 +02:00
Jim Qu
cd19a752f8 modesetting: code refactor for PRIME sync
The X will be crashed on the system with other DDX driver,
such as amdgpu.

show the log like:

randr: falling back to unsynchronized pixmap sharing
(EE)
(EE) Backtrace:
(EE) 0: /usr/lib/xorg/Xorg (xorg_backtrace+0x4e)
(EE) 1: /usr/lib/xorg/Xorg (0x55cb0151a000+0x1b5ce9)
(EE) 2: /lib/x86_64-linux-gnu/libpthread.so.0 (0x7f1587a1d000+0x11390)
(EE)
(EE) Segmentation fault at address 0x0
(EE)

The issue is that modesetting as the master, and amdgpu as the slave.
Thus, when the master attempts to access pSlavePixPriv in ms_dirty_update(),
problems result due to the fact that it's accessing AMD's 'ppriv' using the
modesetting structure definition.

Apart from fixing crash issue, the patch fix other issue in master interface
in which driver should refer to master pixmap.

Signed-off-by: Jim Qu <Jim.Qu@amd.com>
Reviewed-by: Alex Goins <agoins@nvidia.com>
(cherry picked from commit f79e536851)
2018-10-04 17:24:42 +02:00
Alex Goins
5396a4aa08 randr: rrCheckPixmapBounding should only increase screen size
The purpose of rrCheckPixmapBounding() is to make sure that the fb is large
enough to accommodate the region scanned out by a GPU screen. Currently, however,
it will actually shrink the fb if it's larger than it needs to be.

This is a problem when combining PRIME output slaving with arbitrary transforms
with xrandr.

Although arbitrary transforms are not supposed to constrain the size of the fb
(https://lists.freedesktop.org/archives/xorg-devel/2018-January/055563.html),
xrandr will use RRSetScreenSize to resize the desktop to accommodate scaling
transforms, e.g. scaling a 1920x1080 display to 3840x2160 will result in a
desktop size of 3840x2160.

In the case of PRIME, rrCheckPixmapBounding() will be called after
RRSetScreenSize() and it will resize the fb back down to what it would be
without the scaling transform, e.g. 1920x1080. This represents divergence in
behavior between PRIME and non-PRIME outputs.

I had originally made rrCheckPixmapBounding() account for arbitrary transforms,
but realized that the fb being large enough to accommodate arbitrary transforms
is not a hard requirement enforced in the server. Instead, this change simply
makes it so that rrCheckPixmapBounding() will only resize the fb to be larger
than it already is, preventing it from stepping on prior requests to increase
the size of the fb.

Signed-off-by: Alex Goins <agoins@nvidia.com>
Reviewed-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
(cherry picked from commit a90f33721e)
2018-10-04 17:23:57 +02:00
Peter Hutterer
051a0efc5c dix: check_modmap_change() returns Success, not true
Not sure what if anything calls XSetDeviceModifierMapping() but this would've
failed all the time. check_modmap_change() returns Success but we were
treating it like a boolean. Fix this.

Reported-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Keith Packard <keithp@keithp.com>
(cherry picked from commit 4fe02b8da3)
2018-10-04 17:23:48 +02:00
Adam Jackson
1508ea6806 xserver 1.20.1
Signed-off-by: Adam Jackson <ajax@redhat.com>
2018-08-07 12:26:05 -04:00
Keith Packard
101d15c763 During reset/shutdown, clean up leases in DIX instead of each driver
Instead of having every video driver loop over any pending leases to
free them during CloseScreen, do this up in the DIX layer by
terminating leases when a leased CRTC or Output is destroyed and
(just to make sure), also terminating leases in RRCloseScreen. The
latter should "never" get invoked as any lease should be associated
with a resource which was destroyed.

This is required as by the time the driver's CloseScreen function is
invoked, we've already freed all of the DIX randr structures and no
longer have any way to reference the leases

Signed-off-by: Keith Packard <keithp@keithp.com>
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=106960
Cc: Thomas Hellstrom <thellstrom@vmware.com>
(cherry picked from commit 1ef7aed3e2)
2018-08-07 12:08:01 -04:00
Peter Hutterer
9347326d28 Xext: dynamically allocate the PanoramiXDepths[j].vids array
Control flow is:
   PanoramiXMaybeAddDepth() allocates an array size 240 (pDepth->numVisuals)
   PanoramiXMaybeAddVisual() finds up to 270 matches (pScreen->numVisuals)
   and writes those into the previously allocated array.

This caused invalid reads/writes followed by eventually a double-free abort.

Reproduced with xorg-integration-tests server test
XineramaTest.ScreenCrossing/* (and a bunch of others).

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Keith Packard <keithp@keithp.com>
(cherry picked from commit 93cafb0828)
2018-08-02 10:04:10 -04:00
emersion
cbf1ca2dba xwayland: rotate logical size for RRMode
The logical size is the size of the output in the global compositor
space. The mode width/height should be scaled as in the logical
size, but shouldn't be transformed. Thus we need to rotate back
the logical size to be able to use it as the mode width/height.

This fixes issues with pointer input on transformed outputs.

Signed-Off-By: Simon Ser <contact@emersion.fr>
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit ce2dde9ed0)
2018-08-02 10:04:10 -04:00
Olivier Fourdan
18a52a8e16 xwayland: Enable DRI3 for glamor
glamor_fds_from_pixmap() will bail out early if DRI3 is not enabled,
unfortunately Xwayland's glamor code would not set it as enabled which
would lead to blank pixmaps when using texture from pixmap.

Make sure to mark DRI3 as enabled from glamor_egl_screen_init() in
Xwayland.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107287
Fixes: c8c276c956 ("glamor: Implement PixmapFromBuffers and BuffersFromPixmap")
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
(cherry picked from commit cdec2b3c19)
2018-08-02 10:04:10 -04:00
Takashi Iwai
c256e31a9e modesetting: Fix cirrus 24bpp breakage
The recent rewrite of modesetting driver broke the 24bpp support.
As typically found on cirrus KMS, it leads to a blank screen, spewing
the error like:
  failed to add fb -22
  (EE) modeset(0): failed to set mode: Invalid argument

The culript is that the wrong bpp value of the front buffer is passed
to drmModeAddFB().  Fix it by replacing with the back buffer bpp,
drmmode->kbpp.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Tested-by: Stefan Dirsch <sndirsch@suse.de>
Reviewed-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit d625e16918)
2018-08-02 10:04:10 -04:00
Matt Turner
2da0bde449 xfree86: Inline xf86{Read,Write}Mmio{8,16,32} on alpha
In commit 9db2af6f75 (xfree86: Remove xf86{Map,Unmap}VidMem) we
somehow stopped exporting xf86{Read,Write}Mmio{8,16,32}. Since the
function pointer indirection was intended to support dense vs sparse and
sparse support is now gone, we can just make the functions static inline
in compiler.h and avoid all of this.

Bugzilla: https://bugs.gentoo.org/548906
Tested-by: Christopher May-Townsend <chris@maytownsend.co.uk>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Matt Turner <mattst88@gmail.com>
(cherry picked from commit 166ac294ae)
2018-08-01 15:27:21 -04:00
Stefan Agner
b9e9eda08b modesetting: Fix 16 bit depth/bpp mode
When setting DefaultDepth to 16 in the Screen section, the current
code requests a 32 bpp framebuffer, however the X-Server seems to
assumes 16 bpp.

Fixes commit 21217d0216 ("modesetting: Implement 32->24 bpp
conversion in shadow update")

Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Stefan Agner <stefan@agner.ch>
(cherry picked from commit 1c7f34e99f)
2018-08-01 11:01:37 -04:00
Lyude Paul
5c0662d448 meson: ensure the libc has RPC functions when secure-rpc is enabled
Currently our meson.build just makes the assumption that the libc is
going to provide RPC functions. This doesn't actually seem to be the
case on Fedora, which causes compilation to fail unexpectedly:

../../Projects/xserver/os/rpcauth.c:47:10: fatal error: rpc/rpc.h: No such file or directory
 #include <rpc/rpc.h>
          ^~~~~~~~~~~
compilation terminated.

So, in the event that we can't use libtirpc ensure that we actually
check whether or not the libc provides rpc/rpc.h. If it doesn't, raise
an error.

Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
(cherry picked from commit d95a1310ef)
2018-08-01 11:01:37 -04:00
Keith Packard
10285bc36b xf86-video-modesetting: Lease planes as well if using atomic
If we're using atomic modesetting, then we're also using universal
planes, and so the lease we create needs to include the plane.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
(cherry picked from commit d83efc47b7)
2018-08-01 11:01:37 -04:00
Keith Packard
a530198ac0 xf86-video-modesetting: Don't enable UNIVERSAL_PLANES separately
We don't want universal_planes unless we're using atomic APIs for
modesetting, and the kernel already enables universal_planes
automatically when atomic is enabled.

If we enable universal_planes when we're not using atomic, then we
won't have selected a plane for each crtc, and this will break lease
creation which requires planes for each output when universal_planes
is enabled.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
(cherry picked from commit 4a11f66e46)
2018-08-01 11:01:37 -04:00
Keith Packard
cd7680adcc xfree86: Wrap RRCrtcIsLeased and RROutputIsLeased to check for DIX structures
Before DIX structures are allocated for crtcs and outputs, we don't
want to call DIX randr code with NULL pointers. This can happen if the
driver sets video modes early in server initialization, which Nouveau
does in zaphod mode.

Cc: thellstrom@vmware.com
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=106772
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=106960
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
(cherry picked from commit 2faf4cef8b)
2018-08-01 11:01:37 -04:00
Keith Packard
ebd4cd71f4 xfree86: Reset randr_crtc and randr_output early in xf86CrtcCloseScreen
The DIX crtc and output structures are freed when their resources are
destroyed, which happens before CloseScreen is called. As a result, we
know these pointers are invalid and referencing them during any of the
remaining CloseScreen sequence will be bad.

Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
Cc: thellstrom@vmware.com
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=106960
(cherry picked from commit c55a44a9a8)
2018-08-01 11:01:37 -04:00
Jon Turney
1f169d5b38 meson: use absolute paths in manpage substitutions
paths returned by get_option('foodir') are potentially relative to prefix

Noticed when comparing manpages generated by a meson build with those
generated by an autotools build

Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 49283e238a)
2018-08-01 11:01:37 -04:00
Keith Packard
bc1882aa23 modesetting: Allow a DRM fd to be passed on command line with -masterfd [v2]
This lets an application open a suitable DRM device and pass the file
descriptor to the mode setting driver through an X server command line
option, '-masterfd'.

There's a companion application, xlease, which creates a DRM master by
leasing an output from another X server. That is available at

	git clone git://people.freedesktop.org/~keithp/xlease

v2:
	Always print usage, but note that it can't be used if
	setuid/gid

	Suggested-by: Lyude Paul <lyude@redhat.com>

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
(cherry picked from commit 38ff29ec8e)
2018-08-01 11:01:37 -04:00
Laurent Carlier
d60ce5b01f meson: Add configuration of listening on tcp, unix and local
bugzilla: https://bugs.kde.org/show_bug.cgi?id=395419
bugzilla: https://bugs.archlinux.org/task/59025

Signed-off-by: Laurent Carlier <lordheavym@gmail.com>
Reviewed-by: Aaron Plattner <aplattner@nvidia.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 2f39b2a078)
2018-08-01 11:01:37 -04:00
Lyude Paul
79795bf9df modesetting: Fix uninitialized memory usage in drmmode_crtc_get_fb_id()
This really sucked to find out :(

Signed-off-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Karol Herbst <kherbst@redhat.com>
(cherry picked from commit c41d4ff48f)
2018-08-01 11:01:37 -04:00
Thomas Hellstrom
820ce7cb8b glamor: Work around GEM usage v2
KMS drivers are not required to support GEM. In particular, vmwgfx
doesn't support flink and handles and names are identical.
Getting a bo name should really be part of a lower level API, if needed,
but in the mean time work around this by setting the name identical to
the handle if GEM isn't supported.

This fixes modesetting driver dri2 on vmwgfx.

Reviewed-by: Deepak Rawat <drawat@vmware.com>
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
(cherry picked from commit 9f02855e7a)
2018-08-01 11:01:37 -04:00
Lyude Paul
ba6a928381 randr: Scream when creating a shared pixmap fails
This seems like a problem worth screaming about.

Signed-off-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
(cherry picked from commit dc90b1c3c3)
2018-08-01 11:01:37 -04:00
Lyude Paul
91ec6245d6 glamor: Unbreak glamor_fd_from_pixmap()
When support for allocating GBM BOs with modifiers was added,
glamor_fd_from_pixmap() was changed so that it would return an error if
it got a bo with modifiers set from glamor_fds_from_pixmap(). The
problem is that on systems that support BOs with modifiers,
glamor_fds_from_pixmap() will always return BOs with modifiers.

This means that glamor_fd_from_pixmap() was broken entirely, which broke
a number of other things including glamor_shareable_fd_from_pixmap(),
which meant that modesetting using multiple GPUs with the modesetting
DDX was also broken. Easy reproducer:

- Find a laptop with DRI prime that has outputs connected to the
  dedicated GPU and integrated GPU
- Try to enable one display on each using the modesetting DDX
- Fail

Since there isn't a way to ask for no modifiers from
glamor_fds_from_pixmap, we create a shared _glamor_fds_from_pixmap()
function used by both glamor_fds_from_pixmap() and
glamor_fd_from_pixmap() that calls down to the appropriate
glamor_egl_fd*_from_pixmap() function.

Signed-off-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
Cc: Louis-Francis Ratté-Boulianne <lfrb@collabora.com>
Fixes: c8c276c956 ("glamor: Implement PixmapFromBuffers and BuffersFromPixmap")
(cherry picked from commit 186a21c4ba)
2018-08-01 11:01:37 -04:00
Lyude Paul
821f38fa56 modesetting: Also disable CRTC in drmmode_output_disable()
So, this did actually work on older kernels at one point in time,
however it seems that this working was a result of some of the Linux
kernel's atomic modesetting helpers not preserving the CRTC's enabled
state in the right spots. This was fixed in:

846c7dfc1193 ("drm/atomic: Try to preserve the crtc enabled state in drm_atomic_remove_fb, v2")

As a result, atomic commits which simply disassociate a DRM connector
with it's CRTC while leaving the CRTC in an enabled state aren't enough
to disable the CRTC, and result in the atomic commit failing. This
currently can cause issues with MST hotplugging where X will end up
failing to disable the MST outputs after they've left the system. A
simple reproducer:

- Start up Xorg
- Connect an MST hub with displays connected to it
- Remove the hub
- Now there should be CRTCs stuck on the orphaned MST connectors, and X
  won't be able to reclaim them.

Signed-off-by: Lyude Paul <lyude@redhat.com>
Cc: Louis-Francis Ratté-Boulianne <lfrb@collabora.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
(cherry picked from commit c12f1bd4b7)
2018-08-01 11:01:37 -04:00
Olivier Fourdan
2f4d0d8426 modesetting: use drmmode_bo_import() for rotate_fb
drmmode_shadow_allocate() still uses drmModeAddFB() which may fail if
the format is not as expected, preventing from using a rotated output.

Change it to use the new function drmmode_bo_import() which takes care
of calling the drmModeAddFB2() API.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=106715
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Tested-by: Tomas Pelka <tpelka@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
(cherry picked from commit a85e94a50c)
2018-08-01 11:01:37 -04:00
John Lumby
394ed02f87 Change the DPMS initialization to be conditional on not set from config
Any DPMS timeout values set in ServerFlags section of the xorg.conf
are being overwritten by DPMS extension initialization.  Therefore
change the DPMS initialization of timeout values to be conditional on
not set from config.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=106963
Signed-off-by: John Lumby <johnlumby@hotmail.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
(cherry picked from commit f5aace7a27)
2018-08-01 11:01:37 -04:00
Damien Leone
8c2f0f8cbd os: Recompute whether any clients are ready after check_timers()
If a driver calls AttendClient() from within a timer callback we
need to re-compute the local 'are_ready' to prevent the attended
client from waiting until WaitForSomething() times out.

This is a fix similar to commit 9ed5b263.

Signed-off-by: Damien Leone <dleone@nvidia.com>
Reviewed-by: Keith Packard <keithp@keithp.com>
(cherry picked from commit f33cb42643)
2018-08-01 11:01:37 -04:00
Olivier Fourdan
180ab06d45 xwayland: mandatory EGL backend API
The API init_wl_registry() and has_wl_interfaces() are marked as being
optional, but both GBM And EGLStream backends implement them so there is
point in keeping those optional.

Suggested-by: Emil Velikov <emil.velikov@collabora.com>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit 92daeb31fa)
2018-08-01 11:01:37 -04:00
Olivier Fourdan
c641d10ef0 xwayland: simplify xwl_glamor_pixmap_get_wl_buffer()
When retrieving the Wayland buffer from a pixmap, if the buffer already
exists, the GBM backend will return that existing buffer.

However, as seen with the Present issues, if the call had previously
passed a wrong size, that buffer will remain at the wrong size for as
long as the buffer exists, which is error prone.

Considering that the width/height passed to get_wl_buffer() is always the
actual pixmap  drawable size, and considering that the EGLStream backend
makes no use of the size either, there is really no point in passing the
width/height around.

Simplify the xwl_glamor_pixmap_get_wl_buffer() and EGL backends API by
removing the pixmap size, and use the drawable size instead.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit 792359057b)
2018-08-01 11:01:37 -04:00
Olivier Fourdan
79ebd7f689 xwayland: EGL_IMG_context_priority required by EGLStream
xwl_glamor_eglstream_init_egl() uses "EGL_IMG_context_priority"
extension, make sure it's actually available before using it.

Suggested-by: Emil Velikov <emil.velikov@collabora.com>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit bdadaa25f5)
2018-08-01 11:01:37 -04:00
Olivier Fourdan
81969ab773 xwayland: check for EGLStream backend explicitly
Now that we have separate backends for EGLStream and GBM, we can
explicitly check for the EGLStream backend to disable present support
in that case.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit 5d843f6947)
2018-08-01 11:01:37 -04:00
Olivier Fourdan
60020989b9 xwayland: refactor EGL backends for wayland registry
To be able to check for availability of the Wayland interfaces required
to run a given EGL backend (either GBM or EGLStream for now), we need
to have each backend structures and vfuncs in place before we enter the
Wayland registry dance.

That basically means that we should init all backends at first, connect
to the Wayland compositor and query the available interfaces and then
decide which backend is available and should be used (or none if either
the Wayland interfaces or the EGL extensions are not available).

For this purpose, hold an egl_backend struct for each backend we are to
consider prior to connect to the Wayland display so that, when we get to
query the Wayland interfaces, everything is in place for each backend to
handle the various Wayland interfaces.

Eventually, when we need to chose which EGL backend to use for glamor,
the available Wayland interfaces and EGL extensions available are all
known to Xwayland.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit d7185a84b6)
2018-08-01 11:01:37 -04:00
Olivier Fourdan
cb698ec2ba xwayland: move EGL backend init to glamor
Move EGL backends initialization to its own function in
xwayland-glamor.c

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit 48f037a27c)
2018-08-01 11:01:37 -04:00
Olivier Fourdan
8ffee3a6bd xwayland: Add Wayland interfaces check
Introduces a new egl_backend function to let the EGL backend check for
the presence of the required Wayland interfaces.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit f2fcb4877e)
2018-08-01 11:01:37 -04:00
Olivier Fourdan
aad1525180 xwayland: move egl_backend to its own struct
EGL backend availability requires both EGL extensions and Wayland
interfaces to be present, so we will need to consider multiple backends
during initialization.

As a preliminary work, move the egl_backend to its own struct so that we
can have more than one backend at any given time.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit b74b0f18b8)
2018-08-01 11:01:37 -04:00
Olivier Fourdan
831f7194b7 xwayland: skip drm authentication with render node
If using a render node, we can skip DRM authentication.

Suggested-by: Emil Velikov <emil.velikov@collabora.com>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit de004eefc6)
2018-08-01 11:01:37 -04:00
Olivier Fourdan
60eda2af0a xwayland: GBM should fail w/out "GL_OES_EGL_image"
Surely, we should fail to init GBM backend if "GL_OES_EGL_image" is
missing.

This seems to have been lost with commit 1545e2dba ("xwayland: Decouple
GBM from glamor").

Suggested-by: Emil Velikov <emil.velikov@collabora.com>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit b823b43dca)
2018-08-01 11:01:37 -04:00
Olivier Fourdan
f8e96b22bf xwayland: swap "name" and "id" in init_wl_registry()
Both xwl_glamor_init_wl_registry() and the Wayland global registry
handler use the interface id/name in that order, using name/id in the
egl_backend vfunc makes things confusing and error prone.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit 78ce4aa979)
2018-08-01 11:01:37 -04:00
Olivier Fourdan
443e3348bb xwayland: move glamor specific routines
Functions such as:

  xwl_glamor_egl_supports_device_probing()
  xwl_glamor_egl_get_devices()
  xwl_glamor_egl_device_has_egl_extensions()

Are of no use outside of EGLStream support, move them to the relevant
source file.

Similarly, the other glamor functions such as:

  xwl_glamor_init()
  xwl_screen_set_drm_interface()
  xwl_screen_set_dmabuf_interface()
  xwl_glamor_pixmap_get_wl_buffer()
  xwl_glamor_init_wl_registry()
  xwl_glamor_post_damage()
  xwl_glamor_allow_commits()
  xwl_glamor_egl_make_current()

Are useless without glamor support enabled, move those within a
a "#ifdef XWL_HAS_GLAMOR" in xwayland.h

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit f6b2109c1b)
2018-08-01 11:01:37 -04:00
Olivier Fourdan
dea40be935 xwayland: make xwl_output_get_xdg_output() static
Make xwl_output_get_xdg_output() private, it doesn't need to be
available elsewhere.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit d31a7be15e)
2018-08-01 11:01:37 -04:00
Olivier Fourdan
04a19291c9 xwayland: do not disable glamor if EGLStream failed
EGLStream requires glamor, but the opposite is not true. So if someone
passes "-eglstream" with a GPU which does not support EGLStream, we
could maybe still try GBM and be lucky.

That allows Wayland compositors to pass "-eglstream" regardless of the
actual hardware, if they want to enable EGLStream on GPU which support
it.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit e16a6da79d)
2018-08-01 11:01:37 -04:00
Olivier Fourdan
de40a55235 xwayland: process Wayland events after adding screen
When we're done adding a new screen, we need to process any pending
Wayland events again.

Hence we don't end up processing xdg_output events unexpectedly when
glamor is disabled. Be that because "-shm" was passed or "-eglstream"
has failed.

Failing to do that could lead to a crash at startup:

    Xwayland: dixGetPrivateAddr: Assertion `key->initialized' failed.
    (EE)
    (EE) Backtrace:
    (EE) 0: Xwayland (OsSigHandler)
    (EE) 1: libpthread.so.0 (funlockfile)
    (EE) 2: libc.so.6 (gsignal)
    (EE) 3: libc.so.6 (abort)
    (EE) 4: libc.so.6 (?+0x0)
    (EE) 5: libc.so.6 (__assert_fail)
    (EE) 6: Xwayland (dixGetPrivateAddr)
    (EE) 7: Xwayland (_fbGetWindowPixmap)
    (EE) 8: Xwayland (getDrawableDamageRef)
    (EE) 9: Xwayland (damageRegionProcessPending)
    (EE) 10: Xwayland (damagePolyFillRect)
    (EE) 11: Xwayland (miPaintWindow)
    (EE) 12: Xwayland (miWindowExposures)
    (EE) 13: Xwayland (miHandleValidateExposures)
    (EE) 14: Xwayland (SetRootClip)
    (EE) 15: Xwayland (update_screen_size)
    (EE) 16: Xwayland (apply_output_change)
    (EE) 17: libffi.so.6 (ffi_call_unix64)
    (EE) 18: libffi.so.6 (ffi_call)
    (EE) 19: libwayland-client.so.0 (wl_log_set_handler_client)
    (EE) 20: libwayland-client.so.0 (_init)
    (EE) 21: libwayland-client.so.0 (wl_display_dispatch_queue_pending)
    (EE) 22: libwayland-client.so.0 (wl_display_roundtrip_queue)
    (EE) 23: Xwayland (InitInput)
    (EE) 24: Xwayland (dix_main)
    (EE) 25: libc.so.6 (__libc_start_main)
    (EE) 26: Xwayland (_start)
    (EE)
    (EE)
    Fatal server error:
    (EE) Caught signal 6 (Aborted). Server aborting
    (EE)
    Aborted (core dumped)

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit 44560af028)
2018-08-01 11:01:37 -04:00
Olivier Fourdan
2d31a40db5 xwayland: "EGL_EXT_device_base" required for EGLStream
eglQueryDevicesEXT() would abort if the required extensions are not
available, meaning that enabling “-eglstream” on a non-EGLStream
capable hardware would lead to an abort().

Check that "EGL_EXT_device_base" extension is available and bail out
early if not, so we don't abort() later in eglQueryDevicesEXT().

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit dbde3fec32)
2018-08-01 11:01:37 -04:00
Olivier Fourdan
65d46b2dfd xwayland: allow "-eglstream" option
The command line option "-eglstream" used to enable EGLStream support
for NVidia GPU was made available only when Xwayland was built with
EGLStream support enabled.

Wayland compositors who spawn Xwayland have no easy way to tell whether
or not Xwayland was built with EGLStream support enabled, and adding
"-eglstream" command line option to Xwayland when it wasn't built with
EGLStream support would prevent Xwayland from starting (“Unrecognized
option” error).

Make sure we support the command line option "-eglstream" regardless of
EGLStream support in Xwayland. Obviously, if Xwayland was built without
EGLStream support, this has no effect.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit 06c31e782e)
2018-08-01 11:01:37 -04:00
Vladimir Panteleev
38835d1d8f glx/vndcmds: Fix vendor hash table key size
The keySize parameter of the hashing/comparison functions was
incorrectly specified to be sizeof(void*), even though the keys of
this hashtable are CARD32.

Fixes address sanitizer failure on 64-bit builds.

Reviewed-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit 707d0f912b)
2018-08-01 11:01:37 -04:00
Alexander Volkov
d7220428da Xext/shm: Refuse to work for remote clients
Avoid access to System V shared memory segment on the X server side
for clients forwarded via SSH. Also prevent them from hanging while
waiting for the reply from the ShmCreateSegment request.

v2: Allow ShmQueryVersion request even for remote clients

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=11080
Signed-off-by: Alexander Volkov <a.volkov@rusbitech.ru>
Reviewed-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit ec7e2b54c5)
2018-06-19 09:52:53 -04:00
Michał Górny
9e417072bc xfree86: Makefile shouldn't rely on superuser being named 'root'
Change the 'chown' statement in Makefile.am to use the numeric UID
of superuser instead of relying on the name 'root'.

Bugzilla: https://bugs.freedesktop.org/27726
Signed-off-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Michał Górny <gentoo@mgorny.alt.pl>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 5c95be38e5)
2018-06-19 09:52:45 -04:00
Olivier Fourdan
2e66ed066e xwayland: use pixmap size on present flip
If the pixmap size does not match the present box size, flickering
occurs.

This can happen when the client changes its size (e.g. switching to
fullscreen), and since the buffer is kept as long as the pixmap is
valid, once the buffer is created, it remains at the wrong (old) size
and causes continuous flickering.

Use the actual pixmap's drawable size instead of the present box to
create the buffer so that it's sized appropriately.

Bugzilla: https://bugs.freedesktop.org/106841
Fixes: 0fb2cca193 "xwayland: Preliminary support for Present's new
                     window flip mode"
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Roman Gilg <subdiff@gmail.com>
(cherry picked from commit 1993f147d0)
2018-06-19 09:52:40 -04:00
Michel Dänzer
883d4d00b4 present/wnmd: Preserve window pixmap's screen_x/y on flip
The incorrect values could result in the new pixmap's contents
getting corrupted down the line.

v2:
* Guard screen_x/y lines by #ifdef COMPOSITE

Bugzilla: https://bugs.freedesktop.org/106841
Fixes: 029608dd80 "present: Add window flip mode"
Reviewed-by: Adam Jackson <ajax@redhat.com> # v1
Reviewed-by: Keith Packard <keithp@keithp.com> # v1
Reviewed-by: Roman Gilg <subdiff@gmail.com>
Tested-by: Olivier Fourdan <ofourdan@redhat.com> # v1
(cherry picked from commit 10eec2ccb1)
2018-06-19 09:52:35 -04:00
Dave Airlie
55171d738a xwayland: fix typo in non-modifier fallback path
Pointed out on irc by q66.
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>

(cherry picked from commit 6300049a9a)
2018-06-19 09:52:30 -04:00
Roman Kapl
64bf285729 Xi: add forgotten byte-swaps for Valuator fields
This has caused nonsensical values in xinput output.

Signed-off-by: Roman Kapl <code@rkapl.cz>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 40586cc4f8)
2018-06-19 09:52:17 -04:00
Roman Kapl
273115a012 Xi: fix byte-swapping of button labels
The byte-swapping code forgot that the xXIButtonInfo is followed by a
button mask, not directly by the button labels. This resulted in client
crashes in cross-endian setups, for example in `xinput list --long`,
since the client got an invalid atom.

A new function was introduced to get the right positions for the label
and mask data.

Signed-off-by: Roman Kapl <code@rkapl.cz>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit cefbc6a935)
2018-06-19 09:52:17 -04:00
Michel Dänzer
69980e4e5a exa: Use PictureMatchFormat for source-only picture format description
Their pFormat member is NULL, which resulted in a crash in
miRenderColorToPixel.

Fixes: 8171d4c2d6 "render: Store and use all 16bpc of precision for
                     solid pixels (v2.1)"
Reviewed-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit 3ebef6ab85)
2018-06-19 09:52:17 -04:00
Michel Dänzer
33f20c38fc glamor: Propagate glamor_fds_from_pixmap error in glamor_fd_from_pixmap
glamor_fds_from_pixmap returns 0 on error, but we were treating that as
success, continuing with uninitialized stride and fd values.

Also bail if the offset isn't 0, same as in dri3_fd_from_pixmap.

v2:
* Reduce to a simple one-liner fix (Emil Velikov)

Fixes: c8c276c956 "glamor: Implement PixmapFromBuffers and
                     BuffersFromPixmap"
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
(cherry picked from commit 4d5950ce14)
2018-06-19 09:52:17 -04:00
Michel Dänzer
544caffae1 glamor: Always return 0 from glamor_fds_from_pixmap on error
This matches what glamor_egl_fds_from_pixmap and dri3_fds_from_pixmap do
and what proc_dri3_buffers_from_pixmap expects.

Fixes: c8c276c956 "glamor: Implement PixmapFromBuffers and
                     BuffersFromPixmap"
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
(cherry picked from commit 3da999a039)
2018-06-19 09:52:17 -04:00
Michel Dänzer
a9a17581ce modesetting: Pass O_CLOEXEC when opening a DRM device
We don't want DRM file descriptors to leak to child processes.

Reviewed-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
(cherry picked from commit 315c63c41d)
2018-06-19 09:52:17 -04:00
Michel Dänzer
c3a06e330b xfree86: Fix O_CLOEXEC usage in lnx_platform
It was passing O_CLOEXEC as permission bits instead of as a flag.

Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Keith Packard <keithp@keithp.com>
(cherry picked from commit ab53e2859f)
2018-06-19 09:52:17 -04:00
Lukas F. Hartmann
662273397c glamor_init: clamp GLSL to 120 if platform doesn't have instanced arrays
Hi,

I upgraded Xwayland and the assorted libraries from git masters today,
and noticed that glamor wouldn't work anymore on i.MX6/etnaviv. The
error was:

No provider of glVertexAttribDivisor found.  Requires one of:
    Desktop OpenGL 3.3
    OpenGL ES 3.0
    GL extension "GL_ANGLE_instanced_arrays"
    GL extension "GL_ARB_instanced_arrays"
    GL extension "GL_EXT_instanced_arrays"
    GL extension "GL_NV_instanced_arrays"

The problem is that etnaviv offers GLSL 140 on GL 2.1 and glamor
rendering assumes that glVertexAttribDivisor() is always available on
GLSL>=130, which is not the case here. Forcing GLSL 120 makes glamor
work fine again on this platform. After chatting with ajax in
#xorg-devel, the following solution was proposed.

This is my first time of submitting a patch, so please excuse me and
advise if I'm doing it wrong ;)

Cheers
Lukas (mntmn)
Reviewed-by: Eric Anholt <eric@anholt.net>

(cherry picked from commit 7437b6dbde)
2018-06-19 09:52:17 -04:00
Bas Nieuwenhuizen
590374bd92 DRI2: Sync radeonsi_pci_ids.h from Mesa
Fixes DRI2 client driver name mapping for newer AMD GPUs with the
modesetting driver, allowing the DRI2 extension to initialize.

Fixes using GL with the modesetting driver for me.

Seems we were way behind on this one, time to look into something
more scalable?

Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 3ab32a5378)
2018-06-19 09:52:17 -04:00
Jon Turney
5407be2c51 meson: don't put literal 'PACKAGE_STRING' and 'XORG_MAN_PAGE' in man pages
Instead, substitute the same values as autotools does

Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk>
(cherry picked from commit 27eff10bfa)
2018-06-19 09:52:17 -04:00
Jon Turney
acd881e271 meson: don't install xorg wrapper manpages if suid-wrapper isn't being used
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk>
(cherry picked from commit 47321bb455)
2018-06-19 09:52:17 -04:00
Jon Turney
c09c78298c meson: install xwinclip and Xwinrc man pages
Omitted from a1e8dc05

Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk>
(cherry picked from commit 08a3583b5b)
2018-06-19 09:52:17 -04:00
68 changed files with 1077 additions and 558 deletions

View file

@ -45,9 +45,9 @@ Equipment Corporation.
CARD16 DPMSPowerLevel = 0; CARD16 DPMSPowerLevel = 0;
Bool DPMSDisabledSwitch = FALSE; Bool DPMSDisabledSwitch = FALSE;
CARD32 DPMSStandbyTime; CARD32 DPMSStandbyTime = -1;
CARD32 DPMSSuspendTime; CARD32 DPMSSuspendTime = -1;
CARD32 DPMSOffTime; CARD32 DPMSOffTime = -1;
Bool DPMSEnabled; Bool DPMSEnabled;
Bool Bool
@ -432,7 +432,15 @@ DPMSCloseDownExtension(ExtensionEntry *e)
void void
DPMSExtensionInit(void) DPMSExtensionInit(void)
{ {
DPMSStandbyTime = DPMSSuspendTime = DPMSOffTime = ScreenSaverTime; #define CONDITIONALLY_SET_DPMS_TIMEOUT(_timeout_value_) \
if (_timeout_value_ == -1) { /* not yet set from config */ \
_timeout_value_ = ScreenSaverTime; \
}
CONDITIONALLY_SET_DPMS_TIMEOUT(DPMSStandbyTime)
CONDITIONALLY_SET_DPMS_TIMEOUT(DPMSSuspendTime)
CONDITIONALLY_SET_DPMS_TIMEOUT(DPMSOffTime)
DPMSPowerLevel = DPMSModeOn; DPMSPowerLevel = DPMSModeOn;
DPMSEnabled = DPMSSupported(); DPMSEnabled = DPMSSupported();

View file

@ -751,11 +751,7 @@ PanoramiXMaybeAddDepth(DepthPtr pDepth)
PanoramiXNumDepths, sizeof(DepthRec)); PanoramiXNumDepths, sizeof(DepthRec));
PanoramiXDepths[j].depth = pDepth->depth; PanoramiXDepths[j].depth = pDepth->depth;
PanoramiXDepths[j].numVids = 0; PanoramiXDepths[j].numVids = 0;
/* XXX suboptimal, should grow these dynamically */ PanoramiXDepths[j].vids = NULL;
if (pDepth->numVids)
PanoramiXDepths[j].vids = xallocarray(pDepth->numVids, sizeof(VisualID));
else
PanoramiXDepths[j].vids = NULL;
} }
static void static void
@ -796,6 +792,9 @@ PanoramiXMaybeAddVisual(VisualPtr pVisual)
for (k = 0; k < PanoramiXNumDepths; k++) { for (k = 0; k < PanoramiXNumDepths; k++) {
if (PanoramiXDepths[k].depth == pVisual->nplanes) { if (PanoramiXDepths[k].depth == pVisual->nplanes) {
PanoramiXDepths[k].vids = reallocarray(PanoramiXDepths[k].vids,
PanoramiXDepths[k].numVids + 1,
sizeof(VisualID));
PanoramiXDepths[k].vids[PanoramiXDepths[k].numVids] = pVisual->vid; PanoramiXDepths[k].vids[PanoramiXDepths[k].numVids] = pVisual->vid;
PanoramiXDepths[k].numVids++; PanoramiXDepths[k].numVids++;
break; break;

View file

@ -834,6 +834,19 @@ ProcPanoramiXShmGetImage(ClientPtr client)
return BadMatch; return BadMatch;
} }
if (format == ZPixmap) {
widthBytesLine = PixmapBytePad(w, pDraw->depth);
length = widthBytesLine * h;
}
else {
widthBytesLine = PixmapBytePad(w, 1);
lenPer = widthBytesLine * h;
plane = ((Mask) 1) << (pDraw->depth - 1);
length = lenPer * Ones(planemask & (plane | (plane - 1)));
}
VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
drawables = calloc(PanoramiXNumScreens, sizeof(DrawablePtr)); drawables = calloc(PanoramiXNumScreens, sizeof(DrawablePtr));
if (!drawables) if (!drawables)
return BadAlloc; return BadAlloc;
@ -856,18 +869,6 @@ ProcPanoramiXShmGetImage(ClientPtr client)
.depth = pDraw->depth .depth = pDraw->depth
}; };
if (format == ZPixmap) {
widthBytesLine = PixmapBytePad(w, pDraw->depth);
length = widthBytesLine * h;
}
else {
widthBytesLine = PixmapBytePad(w, 1);
lenPer = widthBytesLine * h;
plane = ((Mask) 1) << (pDraw->depth - 1);
length = lenPer * Ones(planemask & (plane | (plane - 1)));
}
VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
xgi.size = length; xgi.size = length;
if (length == 0) { /* nothing to do */ if (length == 0) { /* nothing to do */
@ -1302,9 +1303,14 @@ static int
ProcShmDispatch(ClientPtr client) ProcShmDispatch(ClientPtr client)
{ {
REQUEST(xReq); REQUEST(xReq);
switch (stuff->data) {
case X_ShmQueryVersion: if (stuff->data == X_ShmQueryVersion)
return ProcShmQueryVersion(client); return ProcShmQueryVersion(client);
if (!client->local)
return BadRequest;
switch (stuff->data) {
case X_ShmAttach: case X_ShmAttach:
return ProcShmAttach(client); return ProcShmAttach(client);
case X_ShmDetach: case X_ShmDetach:
@ -1461,9 +1467,14 @@ static int _X_COLD
SProcShmDispatch(ClientPtr client) SProcShmDispatch(ClientPtr client)
{ {
REQUEST(xReq); REQUEST(xReq);
switch (stuff->data) {
case X_ShmQueryVersion: if (stuff->data == X_ShmQueryVersion)
return SProcShmQueryVersion(client); return SProcShmQueryVersion(client);
if (!client->local)
return BadRequest;
switch (stuff->data) {
case X_ShmAttach: case X_ShmAttach:
return SProcShmAttach(client); return SProcShmAttach(client);
case X_ShmDetach: case X_ShmDetach:

View file

@ -88,7 +88,7 @@ ProcXIPassiveGrabDevice(ClientPtr client)
}; };
int i, ret = Success; int i, ret = Success;
uint32_t *modifiers; uint32_t *modifiers;
xXIGrabModifierInfo *modifiers_failed; xXIGrabModifierInfo *modifiers_failed = NULL;
GrabMask mask = { 0 }; GrabMask mask = { 0 };
GrabParameters param; GrabParameters param;
void *tmp; void *tmp;
@ -232,8 +232,8 @@ ProcXIPassiveGrabDevice(ClientPtr client)
if (rep.num_modifiers) if (rep.num_modifiers)
WriteToClient(client, rep.length * 4, modifiers_failed); WriteToClient(client, rep.length * 4, modifiers_failed);
free(modifiers_failed);
out: out:
free(modifiers_failed);
xi2mask_free(&mask.xi2mask); xi2mask_free(&mask.xi2mask);
return ret; return ret;
} }

View file

@ -237,6 +237,18 @@ SizeDeviceClasses(DeviceIntPtr dev)
return len; return len;
} }
/**
* Get pointers to button information areas holding button mask and labels.
*/
static void
ButtonInfoData(xXIButtonInfo *info, int *mask_words, unsigned char **mask,
Atom **atoms)
{
*mask_words = bytes_to_int32(bits_to_bytes(info->num_buttons));
*mask = (unsigned char*) &info[1];
*atoms = (Atom*) ((*mask) + (*mask_words) * 4);
}
/** /**
* Write button information into info. * Write button information into info.
* @return Number of bytes written into info. * @return Number of bytes written into info.
@ -245,21 +257,20 @@ int
ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info, Bool reportState) ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info, Bool reportState)
{ {
unsigned char *bits; unsigned char *bits;
Atom *labels;
int mask_len; int mask_len;
int i; int i;
if (!dev || !dev->button) if (!dev || !dev->button)
return 0; return 0;
mask_len = bytes_to_int32(bits_to_bytes(dev->button->numButtons));
info->type = ButtonClass; info->type = ButtonClass;
info->num_buttons = dev->button->numButtons; info->num_buttons = dev->button->numButtons;
ButtonInfoData(info, &mask_len, &bits, &labels);
info->length = bytes_to_int32(sizeof(xXIButtonInfo)) + info->length = bytes_to_int32(sizeof(xXIButtonInfo)) +
info->num_buttons + mask_len; info->num_buttons + mask_len;
info->sourceid = dev->button->sourceid; info->sourceid = dev->button->sourceid;
bits = (unsigned char *) &info[1];
memset(bits, 0, mask_len * 4); memset(bits, 0, mask_len * 4);
if (reportState) if (reportState)
@ -267,8 +278,7 @@ ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info, Bool reportState)
if (BitIsOn(dev->button->down, i)) if (BitIsOn(dev->button->down, i))
SetBit(bits, i); SetBit(bits, i);
bits += mask_len * 4; memcpy(labels, dev->button->labels, dev->button->numButtons * sizeof(Atom));
memcpy(bits, dev->button->labels, dev->button->numButtons * sizeof(Atom));
return info->length * 4; return info->length * 4;
} }
@ -277,13 +287,17 @@ static void
SwapButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info) SwapButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info)
{ {
Atom *btn; Atom *btn;
int mask_len;
unsigned char *mask;
int i; int i;
ButtonInfoData(info, &mask_len, &mask, &btn);
swaps(&info->type); swaps(&info->type);
swaps(&info->length); swaps(&info->length);
swaps(&info->sourceid); swaps(&info->sourceid);
for (i = 0, btn = (Atom *) &info[1]; i < info->num_buttons; i++, btn++) for (i = 0 ; i < info->num_buttons; i++, btn++)
swapl(btn); swapl(btn);
swaps(&info->num_buttons); swaps(&info->num_buttons);
@ -369,6 +383,9 @@ SwapValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo * info)
swapl(&info->min.frac); swapl(&info->min.frac);
swapl(&info->max.integral); swapl(&info->max.integral);
swapl(&info->max.frac); swapl(&info->max.frac);
swapl(&info->value.integral);
swapl(&info->value.frac);
swapl(&info->resolution);
swaps(&info->number); swaps(&info->number);
swaps(&info->sourceid); swaps(&info->sourceid);
} }

View file

@ -47,24 +47,18 @@
#include "compint.h" #include "compint.h"
static void static Bool
compScreenUpdate(ScreenPtr pScreen) compScreenUpdate(ClientPtr pClient, void *closure)
{
compCheckTree(pScreen);
compPaintChildrenToWindow(pScreen->root);
}
static void
compBlockHandler(ScreenPtr pScreen, void *pTimeout)
{ {
ScreenPtr pScreen = closure;
CompScreenPtr cs = GetCompScreen(pScreen); CompScreenPtr cs = GetCompScreen(pScreen);
pScreen->BlockHandler = cs->BlockHandler; compCheckTree(pScreen);
compScreenUpdate(pScreen); compPaintChildrenToWindow(pScreen->root);
(*pScreen->BlockHandler) (pScreen, pTimeout);
/* Next damage will restore the block handler */ /* Next damage will restore the worker */
cs->BlockHandler = NULL; cs->pendingScreenUpdate = FALSE;
return TRUE;
} }
void void
@ -87,9 +81,9 @@ compReportDamage(DamagePtr pDamage, RegionPtr pRegion, void *closure)
CompScreenPtr cs = GetCompScreen(pScreen); CompScreenPtr cs = GetCompScreen(pScreen);
CompWindowPtr cw = GetCompWindow(pWin); CompWindowPtr cw = GetCompWindow(pWin);
if (!cs->BlockHandler) { if (!cs->pendingScreenUpdate) {
cs->BlockHandler = pScreen->BlockHandler; QueueWorkProc(compScreenUpdate, serverClient, pScreen);
pScreen->BlockHandler = compBlockHandler; cs->pendingScreenUpdate = TRUE;
} }
cw->damaged = TRUE; cw->damaged = TRUE;

View file

@ -387,6 +387,8 @@ compScreenInit(ScreenPtr pScreen)
cs->pOverlayWin = NULL; cs->pOverlayWin = NULL;
cs->pOverlayClients = NULL; cs->pOverlayClients = NULL;
cs->pendingScreenUpdate = FALSE;
cs->numAlternateVisuals = 0; cs->numAlternateVisuals = 0;
cs->alternateVisuals = NULL; cs->alternateVisuals = NULL;
cs->numImplicitRedirectExceptions = 0; cs->numImplicitRedirectExceptions = 0;
@ -442,8 +444,6 @@ compScreenInit(ScreenPtr pScreen)
cs->ChangeWindowAttributes = pScreen->ChangeWindowAttributes; cs->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
pScreen->ChangeWindowAttributes = compChangeWindowAttributes; pScreen->ChangeWindowAttributes = compChangeWindowAttributes;
cs->BlockHandler = NULL;
cs->CloseScreen = pScreen->CloseScreen; cs->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = compCloseScreen; pScreen->CloseScreen = compCloseScreen;

View file

@ -156,7 +156,8 @@ typedef struct _CompScreen {
*/ */
ChangeWindowAttributesProcPtr ChangeWindowAttributes; ChangeWindowAttributesProcPtr ChangeWindowAttributes;
ScreenBlockHandlerProcPtr BlockHandler; Bool pendingScreenUpdate;
CloseScreenProcPtr CloseScreen; CloseScreenProcPtr CloseScreen;
int numAlternateVisuals; int numAlternateVisuals;
VisualID *alternateVisuals; VisualID *alternateVisuals;

View file

@ -26,9 +26,9 @@ dnl
dnl Process this file with autoconf to create configure. dnl Process this file with autoconf to create configure.
AC_PREREQ(2.60) AC_PREREQ(2.60)
AC_INIT([xorg-server], 1.20.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) AC_INIT([xorg-server], 1.20.3, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
RELEASE_DATE="2018-05-10" RELEASE_DATE="2018-10-25"
RELEASE_NAME="Avocado Toast" RELEASE_NAME="Harissa Roasted Carrots"
AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_INIT_AUTOMAKE([foreign dist-bzip2])
@ -1908,9 +1908,6 @@ if test "x$XORG" = xyes; then
XORG_OS_SUBDIR="linux" XORG_OS_SUBDIR="linux"
linux_acpi="no" linux_acpi="no"
case $host_cpu in case $host_cpu in
alpha*)
linux_alpha=yes
;;
i*86|amd64*|x86_64*|ia64*) i*86|amd64*|x86_64*|ia64*)
linux_acpi=$enable_linux_acpi linux_acpi=$enable_linux_acpi
;; ;;
@ -2075,7 +2072,6 @@ AM_CONDITIONAL([XORG], [test "x$XORG" = xyes])
AM_CONDITIONAL([XORG_BUS_PCI], [test "x$PCI" = xyes]) AM_CONDITIONAL([XORG_BUS_PCI], [test "x$PCI" = xyes])
AM_CONDITIONAL([XORG_BUS_BSDPCI], [test "x$xorg_bus_bsdpci" = xyes]) AM_CONDITIONAL([XORG_BUS_BSDPCI], [test "x$xorg_bus_bsdpci" = xyes])
AM_CONDITIONAL([XORG_BUS_SPARC], [test "x$xorg_bus_sparc" = xyes]) AM_CONDITIONAL([XORG_BUS_SPARC], [test "x$xorg_bus_sparc" = xyes])
AM_CONDITIONAL([LINUX_ALPHA], [test "x$linux_alpha" = xyes])
AM_CONDITIONAL([LNXACPI], [test "x$linux_acpi" = xyes]) AM_CONDITIONAL([LNXACPI], [test "x$linux_acpi" = xyes])
AM_CONDITIONAL([LNXAPM], [test "x$linux_apm" = xyes]) AM_CONDITIONAL([LNXAPM], [test "x$linux_apm" = xyes])
AM_CONDITIONAL([SOLARIS_VT], [test "x$solaris_vt" = xyes]) AM_CONDITIONAL([SOLARIS_VT], [test "x$solaris_vt" = xyes])

View file

@ -1177,6 +1177,7 @@ RemoveDevice(DeviceIntPtr dev, BOOL sendevent)
flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved; flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved;
CloseDevice(tmp); CloseDevice(tmp);
ret = Success; ret = Success;
break;
} }
} }
@ -1193,6 +1194,7 @@ RemoveDevice(DeviceIntPtr dev, BOOL sendevent)
prev->next = next; prev->next = next;
ret = Success; ret = Success;
break;
} }
} }

View file

@ -282,7 +282,7 @@ change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *modkeymap,
else if (!IsFloating(dev) && else if (!IsFloating(dev) &&
GetMaster(dev, MASTER_KEYBOARD)->lastSlave == dev) { GetMaster(dev, MASTER_KEYBOARD)->lastSlave == dev) {
/* If this fails, expect the results to be weird. */ /* If this fails, expect the results to be weird. */
if (check_modmap_change(client, dev->master, modmap)) if (check_modmap_change(client, dev->master, modmap) == Success)
do_modmap_change(client, dev->master, modmap); do_modmap_change(client, dev->master, modmap);
} }

View file

@ -291,7 +291,8 @@ exaTryDriverSolidFill(PicturePtr pSrc,
pixel = exaGetPixmapFirstPixel(pSrcPix); pixel = exaGetPixmapFirstPixel(pSrcPix);
} }
else else
miRenderColorToPixel(pSrc->pFormat, miRenderColorToPixel(PictureMatchFormat(pDst->pDrawable->pScreen, 32,
pSrc->format),
&pSrc->pSourcePict->solidFill.fullcolor, &pSrc->pSourcePict->solidFill.fullcolor,
&pixel); &pixel);

View file

@ -279,11 +279,11 @@ fbOverlayFinishScreenInit(ScreenPtr pScreen,
(&fbOverlayScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) (&fbOverlayScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
return FALSE; return FALSE;
pScrPriv = malloc(sizeof(FbOverlayScrPrivRec)); if (bpp1 == 24 || bpp2 == 24)
if (!pScrPriv)
return FALSE; return FALSE;
if (bpp1 == 24 || bpp2 == 24) pScrPriv = malloc(sizeof(FbOverlayScrPrivRec));
if (!pScrPriv)
return FALSE; return FALSE;
if (!fbInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &depth1, if (!fbInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &depth1,

View file

@ -563,6 +563,14 @@ glamor_init(ScreenPtr screen, unsigned int flags)
if (!glamor_check_instruction_count(gl_version)) if (!glamor_check_instruction_count(gl_version))
goto fail; goto fail;
/* Glamor rendering assumes that platforms with GLSL 130+
* have instanced arrays, but this is not always the case.
* etnaviv offers GLSL 140 with OpenGL 2.1.
*/
if (glamor_priv->glsl_version >= 130 &&
!epoxy_has_gl_extension("GL_ARB_instanced_arrays"))
glamor_priv->glsl_version = 120;
} else { } else {
if (gl_version < 20) { if (gl_version < 20) {
ErrorF("Require Open GLES2.0 or later.\n"); ErrorF("Require Open GLES2.0 or later.\n");
@ -818,56 +826,66 @@ glamor_get_drawable_modifiers(DrawablePtr draw, uint32_t format,
return TRUE; return TRUE;
} }
_X_EXPORT int static int
glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, _glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
uint32_t *strides, uint32_t *offsets, uint32_t *strides, uint32_t *offsets,
uint64_t *modifier) CARD32 *size, uint64_t *modifier)
{ {
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_screen_private *glamor_priv = glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen); glamor_get_screen_private(pixmap->drawable.pScreen);
if (!glamor_priv->dri3_enabled) if (!glamor_priv->dri3_enabled)
return -1; return 0;
switch (pixmap_priv->type) { switch (pixmap_priv->type) {
case GLAMOR_TEXTURE_DRM: case GLAMOR_TEXTURE_DRM:
case GLAMOR_TEXTURE_ONLY: case GLAMOR_TEXTURE_ONLY:
if (!glamor_pixmap_ensure_fbo(pixmap, pixmap->drawable.depth == 30 ? if (!glamor_pixmap_ensure_fbo(pixmap, pixmap->drawable.depth == 30 ?
GL_RGB10_A2 : GL_RGBA, 0)) GL_RGB10_A2 : GL_RGBA, 0))
return -1; return 0;
return glamor_egl_fds_from_pixmap(screen, pixmap, fds,
strides, offsets, if (modifier) {
modifier); return glamor_egl_fds_from_pixmap(screen, pixmap, fds,
strides, offsets,
modifier);
} else {
CARD16 stride;
fds[0] = glamor_egl_fd_from_pixmap(screen, pixmap, &stride, size);
strides[0] = stride;
return fds[0] >= 0;
}
default: default:
break; break;
} }
return -1; return 0;
}
_X_EXPORT int
glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
uint32_t *strides, uint32_t *offsets,
uint64_t *modifier)
{
return _glamor_fds_from_pixmap(screen, pixmap, fds, strides, offsets,
NULL, modifier);
} }
_X_EXPORT int _X_EXPORT int
glamor_fd_from_pixmap(ScreenPtr screen, glamor_fd_from_pixmap(ScreenPtr screen,
PixmapPtr pixmap, CARD16 *stride, CARD32 *size) PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
{ {
int fd;
int ret; int ret;
int fds[4]; uint32_t stride32;
uint32_t strides[4], offsets[4];
uint64_t modifier;
ret = glamor_fds_from_pixmap(screen, pixmap, fds, strides, offsets, ret = _glamor_fds_from_pixmap(screen, pixmap, &fd, &stride32, NULL, size,
&modifier); NULL);
if (ret != 1)
/* Pixmaps with multi-planes/modifier are not supported in this interface */
if (ret > 1) {
while (ret > 0)
close(fds[--ret]);
return -1; return -1;
}
ret = fds[0]; *stride = stride32;
*stride = strides[0]; return fd;
*size = pixmap->drawable.height * *stride;
return ret;
} }
_X_EXPORT int _X_EXPORT int

View file

@ -141,7 +141,7 @@ extern _X_EXPORT void glamor_egl_exchange_buffers(PixmapPtr front,
extern _X_EXPORT void glamor_pixmap_exchange_fbos(PixmapPtr front, extern _X_EXPORT void glamor_pixmap_exchange_fbos(PixmapPtr front,
PixmapPtr back); PixmapPtr back);
/* The DDX is not supposed to call these three functions */ /* The DDX is not supposed to call these four functions */
extern _X_EXPORT void glamor_enable_dri3(ScreenPtr screen); extern _X_EXPORT void glamor_enable_dri3(ScreenPtr screen);
extern _X_EXPORT int glamor_egl_fds_from_pixmap(ScreenPtr, PixmapPtr, int *, extern _X_EXPORT int glamor_egl_fds_from_pixmap(ScreenPtr, PixmapPtr, int *,
uint32_t *, uint32_t *, uint32_t *, uint32_t *,
@ -150,6 +150,7 @@ extern _X_EXPORT int glamor_egl_fd_name_from_pixmap(ScreenPtr, PixmapPtr,
CARD16 *, CARD32 *); CARD16 *, CARD32 *);
extern _X_EXPORT struct gbm_device *glamor_egl_get_gbm_device(ScreenPtr screen); extern _X_EXPORT struct gbm_device *glamor_egl_get_gbm_device(ScreenPtr screen);
extern _X_EXPORT int glamor_egl_fd_from_pixmap(ScreenPtr, PixmapPtr, CARD16 *, CARD32 *);
/* @glamor_supports_pixmap_import_export: Returns whether /* @glamor_supports_pixmap_import_export: Returns whether
* glamor_fds_from_pixmap(), glamor_name_from_pixmap(), and * glamor_fds_from_pixmap(), glamor_name_from_pixmap(), and

View file

@ -99,8 +99,18 @@ glamor_get_flink_name(int fd, int handle, int *name)
struct drm_gem_flink flink; struct drm_gem_flink flink;
flink.handle = handle; flink.handle = handle;
if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) {
return FALSE;
/*
* Assume non-GEM kernels have names identical to the handle
*/
if (errno == ENODEV) {
*name = handle;
return TRUE;
} else {
return FALSE;
}
}
*name = flink.name; *name = flink.name;
return TRUE; return TRUE;
} }
@ -402,7 +412,7 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
#endif #endif
} }
static int _X_EXPORT int
glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap,
CARD16 *stride, CARD32 *size) CARD16 *stride, CARD32 *size)
{ {
@ -882,6 +892,7 @@ Bool
glamor_egl_init(ScrnInfoPtr scrn, int fd) glamor_egl_init(ScrnInfoPtr scrn, int fd)
{ {
struct glamor_egl_screen_private *glamor_egl; struct glamor_egl_screen_private *glamor_egl;
const GLubyte *renderer;
glamor_egl = calloc(sizeof(*glamor_egl), 1); glamor_egl = calloc(sizeof(*glamor_egl), 1);
if (glamor_egl == NULL) if (glamor_egl == NULL)
@ -976,6 +987,19 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
"Failed to make EGL context current\n"); "Failed to make EGL context current\n");
goto error; goto error;
} }
renderer = glGetString(GL_RENDERER);
if (!renderer) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"glGetString() returned NULL, your GL is broken\n");
goto error;
}
if (strstr((const char *)renderer, "llvmpipe")) {
xf86DrvMsg(scrn->scrnIndex, X_INFO,
"Refusing to try glamor on llvmpipe\n");
goto error;
}
/* /*
* Force the next glamor_make_current call to set the right context * Force the next glamor_make_current call to set the right context
* (in case of multiple GPUs using glamor) * (in case of multiple GPUs using glamor)
@ -989,7 +1013,7 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
} }
xf86DrvMsg(scrn->scrnIndex, X_INFO, "glamor X acceleration enabled on %s\n", xf86DrvMsg(scrn->scrnIndex, X_INFO, "glamor X acceleration enabled on %s\n",
glGetString(GL_RENDERER)); renderer);
#ifdef GBM_BO_WITH_MODIFIERS #ifdef GBM_BO_WITH_MODIFIERS
if (epoxy_has_egl_extension(glamor_egl->display, if (epoxy_has_egl_extension(glamor_egl->display,

View file

@ -51,3 +51,10 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
{ {
return 0; return 0;
} }
int
glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap,
CARD16 *stride, CARD32 *size)
{
return -1;
}

View file

@ -38,7 +38,7 @@
#define RADIAL_SMALL_STOPS (6 + 2) #define RADIAL_SMALL_STOPS (6 + 2)
#define RADIAL_LARGE_STOPS (16 + 2) #define RADIAL_LARGE_STOPS (16 + 2)
static const char * static char *
_glamor_create_getcolor_fs_source(ScreenPtr screen, int stops_count, _glamor_create_getcolor_fs_source(ScreenPtr screen, int stops_count,
int use_array) int use_array)
{ {
@ -310,7 +310,7 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
"}\n"\ "}\n"\
"\n"\ "\n"\
"%s\n" /* fs_getcolor_source */ "%s\n" /* fs_getcolor_source */
const char *fs_getcolor_source; char *fs_getcolor_source;
glamor_priv = glamor_get_screen_private(screen); glamor_priv = glamor_get_screen_private(screen);
@ -343,6 +343,7 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, gradient_fs); fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, gradient_fs);
free(gradient_fs); free(gradient_fs);
free(fs_getcolor_source);
glAttachShader(gradient_prog, vs_prog); glAttachShader(gradient_prog, vs_prog);
glAttachShader(gradient_prog, fs_prog); glAttachShader(gradient_prog, fs_prog);
@ -493,7 +494,7 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
"}\n"\ "}\n"\
"\n"\ "\n"\
"%s" /* fs_getcolor_source */ "%s" /* fs_getcolor_source */
const char *fs_getcolor_source; char *fs_getcolor_source;
glamor_priv = glamor_get_screen_private(screen); glamor_priv = glamor_get_screen_private(screen);
@ -522,6 +523,7 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, gradient_fs); fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, gradient_fs);
free(gradient_fs); free(gradient_fs);
free(fs_getcolor_source);
glAttachShader(gradient_prog, vs_prog); glAttachShader(gradient_prog, vs_prog);
glAttachShader(gradient_prog, fs_prog); glAttachShader(gradient_prog, fs_prog);

View file

@ -28,6 +28,7 @@
#include "glxserver.h" #include "glxserver.h"
#include "glxext.h" #include "glxext.h"
#include "indirect_dispatch.h" #include "indirect_dispatch.h"
#include "opaque.h"
#define ALL_VALID_FLAGS \ #define ALL_VALID_FLAGS \
(GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB \ (GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB \
@ -320,6 +321,17 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
err = BadAlloc; err = BadAlloc;
} }
else { else {
/* Only allow creating indirect GLX contexts if allowed by
* server command line. Indirect GLX is of limited use (since
* it's only GL 1.4), it's slower than direct contexts, and
* it's a massive attack surface for buffer overflow type
* errors.
*/
if (!enableIndirectGLX) {
client->errorValue = req->isDirect;
return BadValue;
}
ctx = glxScreen->createContext(glxScreen, config, shareCtx, ctx = glxScreen->createContext(glxScreen, config, shareCtx,
req->numAttribs, (uint32_t *) attribs, req->numAttribs, (uint32_t *) attribs,
&err); &err);

View file

@ -50,7 +50,7 @@ typedef struct GlxVendorPrivDispatchRec {
static GlxServerDispatchProc dispatchFuncs[OPCODE_ARRAY_LEN] = {}; static GlxServerDispatchProc dispatchFuncs[OPCODE_ARRAY_LEN] = {};
static HashTable vendorPrivHash = NULL; static HashTable vendorPrivHash = NULL;
static HtGenericHashSetupRec vendorPrivSetup = { static HtGenericHashSetupRec vendorPrivSetup = {
.keySize = sizeof(void*) .keySize = sizeof(CARD32)
}; };
static int DispatchBadRequest(ClientPtr client) static int DispatchBadRequest(ClientPtr client)

View file

@ -108,14 +108,14 @@ endif
install-exec-hook: install-exec-hook:
(cd $(DESTDIR)$(bindir) && rm -f X && $(LN_S) Xorg$(EXEEXT) X) (cd $(DESTDIR)$(bindir) && rm -f X && $(LN_S) Xorg$(EXEEXT) X)
if INSTALL_SETUID if INSTALL_SETUID
chown root $(DESTDIR)$(bindir)/Xorg chown 0 $(DESTDIR)$(bindir)/Xorg
chmod u+s $(DESTDIR)$(bindir)/Xorg chmod u+s $(DESTDIR)$(bindir)/Xorg
endif endif
if SUID_WRAPPER if SUID_WRAPPER
$(MKDIR_P) $(DESTDIR)$(SUID_WRAPPER_DIR) $(MKDIR_P) $(DESTDIR)$(SUID_WRAPPER_DIR)
mv $(DESTDIR)$(bindir)/Xorg $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg mv $(DESTDIR)$(bindir)/Xorg $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg
${INSTALL} -m 755 Xorg.sh $(DESTDIR)$(bindir)/Xorg ${INSTALL} -m 755 Xorg.sh $(DESTDIR)$(bindir)/Xorg
-chown root $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap && chmod u+s $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap -chown 0 $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap && chmod u+s $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap
endif endif
uninstall-local: uninstall-local:

View file

@ -986,33 +986,64 @@ inl(unsigned PORT_SIZE port)
#endif #endif
#ifdef __alpha__ #ifdef __alpha__
/* entry points for Mmio memory access routines */ static inline int
extern _X_EXPORT int (*xf86ReadMmio8) (void *, unsigned long); xf86ReadMmio8(void *Base, unsigned long Offset)
extern _X_EXPORT int (*xf86ReadMmio16) (void *, unsigned long); {
extern _X_EXPORT int (*xf86ReadMmio32) (void *, unsigned long); mem_barrier();
extern _X_EXPORT void (*xf86WriteMmio8) (int, void *, unsigned long); return *(CARD8 *) ((unsigned long) Base + (Offset));
extern _X_EXPORT void (*xf86WriteMmio16) (int, void *, unsigned long); }
extern _X_EXPORT void (*xf86WriteMmio32) (int, void *, unsigned long);
static inline int
xf86ReadMmio16(void *Base, unsigned long Offset)
{
mem_barrier();
return *(CARD16 *) ((unsigned long) Base + (Offset));
}
static inline int
xf86ReadMmio32(void *Base, unsigned long Offset)
{
mem_barrier();
return *(CARD32 *) ((unsigned long) Base + (Offset));
}
static inline void
xf86WriteMmio8(int Value, void *Base, unsigned long Offset)
{
write_mem_barrier();
*(CARD8 *) ((unsigned long) Base + (Offset)) = Value;
}
static inline void
xf86WriteMmio16(int Value, void *Base, unsigned long Offset)
{
write_mem_barrier();
*(CARD16 *) ((unsigned long) Base + (Offset)) = Value;
}
static inline void
xf86WriteMmio32(int Value, void *Base, unsigned long Offset)
{
write_mem_barrier();
*(CARD32 *) ((unsigned long) Base + (Offset)) = Value;
}
extern _X_EXPORT void xf86SlowBCopyFromBus(unsigned char *, unsigned char *, extern _X_EXPORT void xf86SlowBCopyFromBus(unsigned char *, unsigned char *,
int); int);
extern _X_EXPORT void xf86SlowBCopyToBus(unsigned char *, unsigned char *, int); extern _X_EXPORT void xf86SlowBCopyToBus(unsigned char *, unsigned char *, int);
/* Some macros to hide the system dependencies for MMIO accesses */ /* Some macros to hide the system dependencies for MMIO accesses */
/* Changed to kill noise generated by gcc's -Wcast-align */ /* Changed to kill noise generated by gcc's -Wcast-align */
#define MMIO_IN8(base, offset) (*xf86ReadMmio8)(base, offset) #define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset)
#define MMIO_IN16(base, offset) (*xf86ReadMmio16)(base, offset) #define MMIO_IN16(base, offset) xf86ReadMmio16(base, offset)
#define MMIO_IN32(base, offset) (*xf86ReadMmio32)(base, offset) #define MMIO_IN32(base, offset) xf86ReadMmio32(base, offset)
#define MMIO_OUT32(base, offset, val) \
do { \
write_mem_barrier(); \
*(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val); \
} while (0)
#define MMIO_OUT8(base, offset, val) \ #define MMIO_OUT8(base, offset, val) \
(*xf86WriteMmio8)((CARD8)(val), base, offset) xf86WriteMmio8((CARD8)(val), base, offset)
#define MMIO_OUT16(base, offset, val) \ #define MMIO_OUT16(base, offset, val) \
(*xf86WriteMmio16)((CARD16)(val), base, offset) xf86WriteMmio16((CARD16)(val), base, offset)
#define MMIO_OUT32(base, offset, val) \
xf86WriteMmio32((CARD32)(val), base, offset)
#elif defined(__powerpc__) || defined(__sparc__) #elif defined(__powerpc__) || defined(__sparc__)
/* /*

View file

@ -939,10 +939,12 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
from = X_CMDLINE; from = X_CMDLINE;
i = -1; i = -1;
if (xf86GetOptValInteger(FlagOptions, FLAG_MAX_CLIENTS, &i)) { if (xf86GetOptValInteger(FlagOptions, FLAG_MAX_CLIENTS, &i)) {
if (i != 64 && i != 128 && i != 256 && i != 512) if (Ones(i) != 1 || i < 64 || i > 2048) {
ErrorF("MaxClients must be one of 64, 128, 256 or 512\n"); ErrorF("MaxClients must be one of 64, 128, 256, 512, 1024, or 2048\n");
from = X_CONFIG; } else {
LimitClients = i; from = X_CONFIG;
LimitClients = i;
}
} }
xf86Msg(from, "Max clients allowed: %i, resource mask: 0x%x\n", xf86Msg(from, "Max clients allowed: %i, resource mask: 0x%x\n",
LimitClients, RESOURCE_ID_MASK); LimitClients, RESOURCE_ID_MASK);

View file

@ -53,6 +53,8 @@ DevPrivateKeyRec xf86ScreenKeyRec;
ScrnInfoPtr *xf86Screens = NULL; /* List of ScrnInfos */ ScrnInfoPtr *xf86Screens = NULL; /* List of ScrnInfos */
ScrnInfoPtr *xf86GPUScreens = NULL; /* List of ScrnInfos */ ScrnInfoPtr *xf86GPUScreens = NULL; /* List of ScrnInfos */
int xf86DRMMasterFd = -1; /* Command line argument for DRM master file descriptor */
const unsigned char byte_reversed[256] = { const unsigned char byte_reversed[256] = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,

View file

@ -1027,14 +1027,18 @@ ddxProcessArgument(int argc, char **argv, int i)
/* First the options that are not allowed with elevated privileges */ /* First the options that are not allowed with elevated privileges */
if (!strcmp(argv[i], "-modulepath")) { if (!strcmp(argv[i], "-modulepath")) {
CHECK_FOR_REQUIRED_ARGUMENT(); CHECK_FOR_REQUIRED_ARGUMENT();
xf86CheckPrivs(argv[i], argv[i + 1]); if (xf86PrivsElevated())
FatalError("\nInvalid argument -modulepath "
"with elevated privileges\n");
xf86ModulePath = argv[i + 1]; xf86ModulePath = argv[i + 1];
xf86ModPathFrom = X_CMDLINE; xf86ModPathFrom = X_CMDLINE;
return 2; return 2;
} }
if (!strcmp(argv[i], "-logfile")) { if (!strcmp(argv[i], "-logfile")) {
CHECK_FOR_REQUIRED_ARGUMENT(); CHECK_FOR_REQUIRED_ARGUMENT();
xf86CheckPrivs(argv[i], argv[i + 1]); if (xf86PrivsElevated())
FatalError("\nInvalid argument -logfile "
"with elevated privileges\n");
xf86LogFile = argv[i + 1]; xf86LogFile = argv[i + 1];
xf86LogFileFrom = X_CMDLINE; xf86LogFileFrom = X_CMDLINE;
return 2; return 2;

View file

@ -93,6 +93,7 @@ extern _X_EXPORT int xf86LogVerbose; /* log file verbosity level */
extern ScrnInfoPtr *xf86GPUScreens; /* List of pointers to ScrnInfoRecs */ extern ScrnInfoPtr *xf86GPUScreens; /* List of pointers to ScrnInfoRecs */
extern int xf86NumGPUScreens; extern int xf86NumGPUScreens;
extern _X_EXPORT int xf86DRMMasterFd; /* Command line argument for DRM master file descriptor */
#ifndef DEFAULT_VERBOSE #ifndef DEFAULT_VERBOSE
#define DEFAULT_VERBOSE 0 #define DEFAULT_VERBOSE 0
#endif #endif

View file

@ -205,3 +205,33 @@ CHIPSET(0x67CF, POLARIS10_, POLARIS10)
CHIPSET(0x67DF, POLARIS10_, POLARIS10) CHIPSET(0x67DF, POLARIS10_, POLARIS10)
CHIPSET(0x98E4, STONEY_, STONEY) CHIPSET(0x98E4, STONEY_, STONEY)
CHIPSET(0x6980, POLARIS12_, POLARIS12)
CHIPSET(0x6981, POLARIS12_, POLARIS12)
CHIPSET(0x6985, POLARIS12_, POLARIS12)
CHIPSET(0x6986, POLARIS12_, POLARIS12)
CHIPSET(0x6987, POLARIS12_, POLARIS12)
CHIPSET(0x6995, POLARIS12_, POLARIS12)
CHIPSET(0x6997, POLARIS12_, POLARIS12)
CHIPSET(0x699F, POLARIS12_, POLARIS12)
CHIPSET(0x694C, VEGAM_, VEGAM)
CHIPSET(0x694E, VEGAM_, VEGAM)
CHIPSET(0x6860, VEGA10_, VEGA10)
CHIPSET(0x6861, VEGA10_, VEGA10)
CHIPSET(0x6862, VEGA10_, VEGA10)
CHIPSET(0x6863, VEGA10_, VEGA10)
CHIPSET(0x6864, VEGA10_, VEGA10)
CHIPSET(0x6867, VEGA10_, VEGA10)
CHIPSET(0x6868, VEGA10_, VEGA10)
CHIPSET(0x687F, VEGA10_, VEGA10)
CHIPSET(0x686C, VEGA10_, VEGA10)
CHIPSET(0x69A0, VEGA12_, VEGA12)
CHIPSET(0x69A1, VEGA12_, VEGA12)
CHIPSET(0x69A2, VEGA12_, VEGA12)
CHIPSET(0x69A3, VEGA12_, VEGA12)
CHIPSET(0x69AF, VEGA12_, VEGA12)
CHIPSET(0x15DD, RAVEN_, RAVEN)

View file

@ -36,6 +36,7 @@
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include "xf86.h" #include "xf86.h"
#include "xf86Priv.h"
#include "xf86_OSproc.h" #include "xf86_OSproc.h"
#include "compiler.h" #include "compiler.h"
#include "xf86Pci.h" #include "xf86Pci.h"
@ -194,18 +195,31 @@ modesettingEntPtr ms_ent_priv(ScrnInfoPtr scrn)
return pPriv->ptr; return pPriv->ptr;
} }
static int
get_passed_fd(void)
{
if (xf86DRMMasterFd >= 0) {
xf86DrvMsg(-1, X_INFO, "Using passed DRM master file descriptor %d\n", xf86DRMMasterFd);
return dup(xf86DRMMasterFd);
}
return -1;
}
static int static int
open_hw(const char *dev) open_hw(const char *dev)
{ {
int fd; int fd;
if ((fd = get_passed_fd()) != -1)
return fd;
if (dev) if (dev)
fd = open(dev, O_RDWR, 0); fd = open(dev, O_RDWR | O_CLOEXEC, 0);
else { else {
dev = getenv("KMSDEVICE"); dev = getenv("KMSDEVICE");
if ((NULL == dev) || ((fd = open(dev, O_RDWR, 0)) == -1)) { if ((NULL == dev) || ((fd = open(dev, O_RDWR | O_CLOEXEC, 0)) == -1)) {
dev = "/dev/dri/card0"; dev = "/dev/dri/card0";
fd = open(dev, O_RDWR, 0); fd = open(dev, O_RDWR | O_CLOEXEC, 0);
} }
} }
if (fd == -1) if (fd == -1)
@ -626,20 +640,22 @@ ms_dirty_update(ScreenPtr screen, int *timeout)
xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) { xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) {
region = DamageRegion(ent->damage); region = DamageRegion(ent->damage);
if (RegionNotEmpty(region)) { if (RegionNotEmpty(region)) {
msPixmapPrivPtr ppriv = if (!screen->isGPU) {
msGetPixmapPriv(&ms->drmmode, ent->slave_dst); msPixmapPrivPtr ppriv =
msGetPixmapPriv(&ms->drmmode, ent->slave_dst->master_pixmap);
if (ppriv->notify_on_damage) { if (ppriv->notify_on_damage) {
ppriv->notify_on_damage = FALSE; ppriv->notify_on_damage = FALSE;
ent->slave_dst->drawable.pScreen-> ent->slave_dst->drawable.pScreen->
SharedPixmapNotifyDamage(ent->slave_dst); SharedPixmapNotifyDamage(ent->slave_dst);
}
/* Requested manual updating */
if (ppriv->defer_dirty_update)
continue;
} }
/* Requested manual updating */
if (ppriv->defer_dirty_update)
continue;
redisplay_dirty(screen, ent, timeout); redisplay_dirty(screen, ent, timeout);
DamageEmpty(ent->damage); DamageEmpty(ent->damage);
} }
@ -818,6 +834,12 @@ ms_get_drm_master_fd(ScrnInfoPtr pScrn)
return TRUE; return TRUE;
} }
ms->fd_passed = FALSE;
if ((ms->fd = get_passed_fd()) >= 0) {
ms->fd_passed = TRUE;
return TRUE;
}
#ifdef XSERVER_PLATFORM_BUS #ifdef XSERVER_PLATFORM_BUS
if (pEnt->location.type == BUS_PLATFORM) { if (pEnt->location.type == BUS_PLATFORM) {
#ifdef XF86_PDEV_SERVER_FD #ifdef XF86_PDEV_SERVER_FD
@ -878,8 +900,6 @@ PreInit(ScrnInfoPtr pScrn, int flags)
if (pScrn->numEntities != 1) if (pScrn->numEntities != 1)
return FALSE; return FALSE;
pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
if (flags & PROBE_DETECT) { if (flags & PROBE_DETECT) {
return FALSE; return FALSE;
} }
@ -888,6 +908,8 @@ PreInit(ScrnInfoPtr pScrn, int flags)
if (!GetRec(pScrn)) if (!GetRec(pScrn))
return FALSE; return FALSE;
pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
ms = modesettingPTR(pScrn); ms = modesettingPTR(pScrn);
ms->SaveGeneration = -1; ms->SaveGeneration = -1;
ms->pEnt = pEnt; ms->pEnt = pEnt;
@ -920,7 +942,7 @@ PreInit(ScrnInfoPtr pScrn, int flags)
"Using 24bpp hw front buffer with 32bpp shadow\n"); "Using 24bpp hw front buffer with 32bpp shadow\n");
defaultbpp = 32; defaultbpp = 32;
} else { } else {
ms->drmmode.kbpp = defaultbpp; ms->drmmode.kbpp = 0;
} }
bppflags = PreferConvert24to32 | SupportConvert24to32 | Support32bppFb; bppflags = PreferConvert24to32 | SupportConvert24to32 | Support32bppFb;
@ -941,6 +963,8 @@ PreInit(ScrnInfoPtr pScrn, int flags)
return FALSE; return FALSE;
} }
xf86PrintDepthBpp(pScrn); xf86PrintDepthBpp(pScrn);
if (!ms->drmmode.kbpp)
ms->drmmode.kbpp = pScrn->bitsPerPixel;
/* Process the options */ /* Process the options */
xf86CollectOptions(pScrn, NULL); xf86CollectOptions(pScrn, NULL);
@ -1014,8 +1038,7 @@ PreInit(ScrnInfoPtr pScrn, int flags)
#endif #endif
} }
ret = drmSetClientCap(ms->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); ret = drmSetClientCap(ms->fd, DRM_CLIENT_CAP_ATOMIC, 1);
ret |= drmSetClientCap(ms->fd, DRM_CLIENT_CAP_ATOMIC, 1);
ms->atomic_modeset = (ret == 0); ms->atomic_modeset = (ret == 0);
ms->kms_has_modifiers = FALSE; ms->kms_has_modifiers = FALSE;
@ -1230,8 +1253,8 @@ msStartFlippingPixmapTracking(RRCrtcPtr crtc, DrawablePtr src,
ScreenPtr pScreen = src->pScreen; ScreenPtr pScreen = src->pScreen;
modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(pScreen)); modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(pScreen));
msPixmapPrivPtr ppriv1 = msGetPixmapPriv(&ms->drmmode, slave_dst1), msPixmapPrivPtr ppriv1 = msGetPixmapPriv(&ms->drmmode, slave_dst1->master_pixmap),
ppriv2 = msGetPixmapPriv(&ms->drmmode, slave_dst2); ppriv2 = msGetPixmapPriv(&ms->drmmode, slave_dst2->master_pixmap);
if (!PixmapStartDirtyTracking(src, slave_dst1, x, y, if (!PixmapStartDirtyTracking(src, slave_dst1, x, y,
dst_x, dst_y, rotation)) { dst_x, dst_y, rotation)) {
@ -1259,10 +1282,10 @@ msStartFlippingPixmapTracking(RRCrtcPtr crtc, DrawablePtr src,
static Bool static Bool
msPresentSharedPixmap(PixmapPtr slave_dst) msPresentSharedPixmap(PixmapPtr slave_dst)
{ {
ScreenPtr pScreen = slave_dst->drawable.pScreen; ScreenPtr pScreen = slave_dst->master_pixmap->drawable.pScreen;
modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(pScreen)); modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(pScreen));
msPixmapPrivPtr ppriv = msGetPixmapPriv(&ms->drmmode, slave_dst); msPixmapPrivPtr ppriv = msGetPixmapPriv(&ms->drmmode, slave_dst->master_pixmap);
RegionPtr region = DamageRegion(ppriv->dirty->damage); RegionPtr region = DamageRegion(ppriv->dirty->damage);
@ -1283,8 +1306,8 @@ msStopFlippingPixmapTracking(DrawablePtr src,
ScreenPtr pScreen = src->pScreen; ScreenPtr pScreen = src->pScreen;
modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(pScreen)); modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(pScreen));
msPixmapPrivPtr ppriv1 = msGetPixmapPriv(&ms->drmmode, slave_dst1), msPixmapPrivPtr ppriv1 = msGetPixmapPriv(&ms->drmmode, slave_dst1->master_pixmap),
ppriv2 = msGetPixmapPriv(&ms->drmmode, slave_dst2); ppriv2 = msGetPixmapPriv(&ms->drmmode, slave_dst2->master_pixmap);
Bool ret = TRUE; Bool ret = TRUE;
@ -1450,7 +1473,7 @@ msRequestSharedPixmapNotifyDamage(PixmapPtr ppix)
ScrnInfoPtr scrn = xf86ScreenToScrn(screen); ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
modesettingPtr ms = modesettingPTR(scrn); modesettingPtr ms = modesettingPTR(scrn);
msPixmapPrivPtr ppriv = msGetPixmapPriv(&ms->drmmode, ppix); msPixmapPrivPtr ppriv = msGetPixmapPriv(&ms->drmmode, ppix->master_pixmap);
ppriv->notify_on_damage = TRUE; ppriv->notify_on_damage = TRUE;
@ -1502,6 +1525,9 @@ SetMaster(ScrnInfoPtr pScrn)
return TRUE; return TRUE;
#endif #endif
if (ms->fd_passed)
return TRUE;
ret = drmSetMaster(ms->fd); ret = drmSetMaster(ms->fd);
if (ret) if (ret)
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "drmSetMaster failed: %s\n", xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "drmSetMaster failed: %s\n",
@ -1754,7 +1780,8 @@ LeaveVT(ScrnInfoPtr pScrn)
return; return;
#endif #endif
drmDropMaster(ms->fd); if (!ms->fd_passed)
drmDropMaster(ms->fd);
} }
/* /*
@ -1813,8 +1840,6 @@ CloseScreen(ScreenPtr pScreen)
ms->drmmode.shadow_fb2 = NULL; ms->drmmode.shadow_fb2 = NULL;
} }
drmmode_terminate_leases(pScrn, &ms->drmmode);
drmmode_uevent_fini(pScrn, &ms->drmmode); drmmode_uevent_fini(pScrn, &ms->drmmode);
drmmode_free_bos(pScrn, &ms->drmmode); drmmode_free_bos(pScrn, &ms->drmmode);

View file

@ -84,6 +84,7 @@ struct ms_drm_queue {
typedef struct _modesettingRec { typedef struct _modesettingRec {
int fd; int fd;
Bool fd_passed;
int Chipset; int Chipset;
EntityInfoPtr pEnt; EntityInfoPtr pEnt;

View file

@ -398,7 +398,6 @@ drmmode_prop_info_copy(drmmode_prop_info_ptr dst,
err: err:
while (i--) while (i--)
free(dst[i].enum_values); free(dst[i].enum_values);
free(dst);
return FALSE; return FALSE;
} }
@ -604,6 +603,8 @@ drmmode_crtc_get_fb_id(xf86CrtcPtr crtc, uint32_t *fb_id, int *x, int *y)
drmmode_ptr drmmode = drmmode_crtc->drmmode; drmmode_ptr drmmode = drmmode_crtc->drmmode;
int ret; int ret;
*fb_id = 0;
if (drmmode_crtc->prime_pixmap) { if (drmmode_crtc->prime_pixmap) {
if (!drmmode->reverse_prime_offload_mode) { if (!drmmode->reverse_prime_offload_mode) {
msPixmapPrivPtr ppriv = msPixmapPrivPtr ppriv =
@ -695,18 +696,21 @@ drmmode_output_disable(xf86OutputPtr output)
{ {
modesettingPtr ms = modesettingPTR(output->scrn); modesettingPtr ms = modesettingPTR(output->scrn);
drmmode_output_private_ptr drmmode_output = output->driver_private; drmmode_output_private_ptr drmmode_output = output->driver_private;
xf86CrtcPtr crtc = drmmode_output->current_crtc;
drmModeAtomicReq *req = drmModeAtomicAlloc(); drmModeAtomicReq *req = drmModeAtomicAlloc();
uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET; uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
int ret; int ret = 0;
assert(ms->atomic_modeset); assert(ms->atomic_modeset);
if (!req) if (!req)
return 1; return 1;
/* XXX Can we disable all outputs without disabling CRTC right away? */ ret |= connector_add_prop(req, drmmode_output,
ret = connector_add_prop(req, drmmode_output, DRMMODE_CONNECTOR_CRTC_ID, 0);
DRMMODE_CONNECTOR_CRTC_ID, 0); if (crtc)
ret |= crtc_add_dpms_props(req, crtc, DPMSModeOff, NULL);
if (ret == 0) if (ret == 0)
ret = drmModeAtomicCommit(ms->fd, req, flags, NULL); ret = drmModeAtomicCommit(ms->fd, req, flags, NULL);
@ -990,7 +994,7 @@ drmmode_bo_import(drmmode_ptr drmmode, drmmode_bo *bo,
} }
#endif #endif
return drmModeAddFB(drmmode->fd, bo->width, bo->height, return drmModeAddFB(drmmode->fd, bo->width, bo->height,
drmmode->scrn->depth, drmmode->scrn->bitsPerPixel, drmmode->scrn->depth, drmmode->kbpp,
drmmode_bo_get_pitch(bo), drmmode_bo_get_pitch(bo),
drmmode_bo_get_handle(bo), fb_id); drmmode_bo_get_handle(bo), fb_id);
} }
@ -1794,11 +1798,8 @@ drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
return NULL; return NULL;
} }
ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth, ret = drmmode_bo_import(drmmode, &drmmode_crtc->rotate_bo,
drmmode->kbpp, &drmmode_crtc->rotate_fb_id);
drmmode_bo_get_pitch(&drmmode_crtc->rotate_bo),
drmmode_bo_get_handle(&drmmode_crtc->rotate_bo),
&drmmode_crtc->rotate_fb_id);
if (ret) { if (ret) {
ErrorF("failed to add rotate fb\n"); ErrorF("failed to add rotate fb\n");
@ -3251,6 +3252,9 @@ drmmode_create_lease(RRLeasePtr lease, int *fd)
nobjects = ncrtc + noutput; nobjects = ncrtc + noutput;
if (ms->atomic_modeset)
nobjects += ncrtc; /* account for planes as well */
if (nobjects == 0) if (nobjects == 0)
return BadValue; return BadValue;
@ -3267,12 +3271,14 @@ drmmode_create_lease(RRLeasePtr lease, int *fd)
i = 0; i = 0;
/* Add CRTC ids */ /* Add CRTC and plane ids */
for (c = 0; c < ncrtc; c++) { for (c = 0; c < ncrtc; c++) {
xf86CrtcPtr crtc = lease->crtcs[c]->devPrivate; xf86CrtcPtr crtc = lease->crtcs[c]->devPrivate;
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
objects[i++] = drmmode_crtc->mode_crtc->crtc_id; objects[i++] = drmmode_crtc->mode_crtc->crtc_id;
if (ms->atomic_modeset)
objects[i++] = drmmode_crtc->plane_id;
} }
/* Add connector ids */ /* Add connector ids */
@ -3320,23 +3326,6 @@ drmmode_terminate_lease(RRLeasePtr lease)
} }
} }
void
drmmode_terminate_leases(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
{
ScreenPtr screen = xf86ScrnToScreen(pScrn);
rrScrPrivPtr scr_priv = rrGetScrPriv(screen);
RRLeasePtr lease, next;
xorg_list_for_each_entry_safe(lease, next, &scr_priv->leases, list) {
drmmode_lease_private_ptr lease_private = lease->devPrivate;
drmModeRevokeLease(drmmode->fd, lease_private->lessee_id);
free(lease_private);
lease->devPrivate = NULL;
RRLeaseTerminated(lease);
RRLeaseFree(lease);
}
}
static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = { static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
.resize = drmmode_xf86crtc_resize, .resize = drmmode_xf86crtc_resize,
.create_lease = drmmode_create_lease, .create_lease = drmmode_create_lease,

View file

@ -272,8 +272,6 @@ extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn);
extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode); extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode);
extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode); extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode);
extern void drmmode_terminate_leases(ScrnInfoPtr scrn, drmmode_ptr drmmode);
Bool drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode); Bool drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
void *drmmode_map_front_bo(drmmode_ptr drmmode); void *drmmode_map_front_bo(drmmode_ptr drmmode);
Bool drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode); Bool drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);

View file

@ -14,10 +14,13 @@ modesetting \- video driver for framebuffer device
.fi .fi
.SH DESCRIPTION .SH DESCRIPTION
.B modesetting .B modesetting
is an @xservername@ driver for KMS devices. This is a non-accelerated is an @xservername@ driver for KMS devices. This driver supports
driver, the following framebuffer depths are supported: 8, 15, 16, 24. TrueColor visuals at framebuffer depths of 15, 16, 24, and 30. RandR
All visual types are supported for depth 8, and TrueColor visual is 1.2 is supported for multi-head configurations. Acceleration is available
supported for the other depths. RandR 1.2 is supported. through glamor for devices supporting at least OpenGL ES 2.0 or OpenGL 2.1.
If glamor is not enabled, a shadow framebuffer is configured based on the
KMS drivers' preference (unless the framebuffer is 24 bits per pixel, in
which case the shadow framebuffer is always used).
.SH SUPPORTED HARDWARE .SH SUPPORTED HARDWARE
The The
.B modesetting .B modesetting
@ -51,8 +54,18 @@ The framebuffer device to use. Default: /dev/dri/card0.
.BI "Option \*qShadowFB\*q \*q" boolean \*q .BI "Option \*qShadowFB\*q \*q" boolean \*q
Enable or disable use of the shadow framebuffer layer. Default: on. Enable or disable use of the shadow framebuffer layer. Default: on.
.TP .TP
.BI "Option \*qDoubleShadow\*q \*q" boolean \*q
Double-buffer shadow updates. When enabled, the driver will keep two copies of
the shadow framebuffer. When the shadow framebuffer is flushed, the old and new
versions of the shadow are compared, and only tiles that have actually changed
are uploaded to the device. This is an optimization for server-class GPUs with
a remote display function (typically VNC), where remote updates are triggered
by any framebuffer write, so minimizing the amount of data uploaded is crucial.
This defaults to enabled for ASPEED and Matrox G200 devices, and disabled
otherwise.
.TP
.BI "Option \*qAccelMethod\*q \*q" string \*q .BI "Option \*qAccelMethod\*q \*q" string \*q
One of \*qglamor\*q or \*qnone\*q. Default: glamor One of \*qglamor\*q or \*qnone\*q. Default: glamor.
.TP .TP
.BI "Option \*qPageFlip\*q \*q" boolean \*q .BI "Option \*qPageFlip\*q \*q" boolean \*q
Enable DRI3 page flipping. The default is Enable DRI3 page flipping. The default is

View file

@ -329,6 +329,22 @@ fbdev_open(int scrnIndex, const char *dev, char **namep)
return -1; return -1;
} }
/* only touch non-PCI devices on this path */
{
char buf[PATH_MAX];
char *sysfs_path = NULL;
char *node = strrchr(dev, '/') + 1;
if (asprintf(&sysfs_path, "/sys/class/graphics/%s", node) < 0 ||
readlink(sysfs_path, buf, sizeof(buf)) < 0 ||
strstr(buf, "devices/pci")) {
free(sysfs_path);
close(fd);
return -1;
}
free(sysfs_path);
}
if (namep) { if (namep) {
if (-1 == ioctl(fd, FBIOGET_FSCREENINFO, (void *) (&fix))) { if (-1 == ioctl(fd, FBIOGET_FSCREENINFO, (void *) (&fix))) {
*namep = NULL; *namep = NULL;

View file

@ -190,17 +190,19 @@ install_man(configure_file(
configuration: manpage_config, configuration: manpage_config,
)) ))
install_man(configure_file( if get_option('suid_wrapper')
input: 'man/Xorg.wrap.man', install_man(configure_file(
output: 'Xorg.wrap.1', input: 'man/Xorg.wrap.man',
configuration: manpage_config, output: 'Xorg.wrap.1',
)) configuration: manpage_config,
))
install_man(configure_file( install_man(configure_file(
input: 'man/Xwrapper.config.man', input: 'man/Xwrapper.config.man',
output: 'Xwrapper.config.5', output: 'Xwrapper.config.5',
configuration: manpage_config, configuration: manpage_config,
)) ))
endif
install_man(configure_file( install_man(configure_file(
input: 'man/xorg.conf.man', input: 'man/xorg.conf.man',

View file

@ -174,6 +174,32 @@ xf86CrtcInUse(xf86CrtcPtr crtc)
return FALSE; return FALSE;
} }
/**
* Return whether the crtc is leased by a client
*/
static Bool
xf86CrtcIsLeased(xf86CrtcPtr crtc)
{
/* If the DIX structure hasn't been created, it can't have been leased */
if (!crtc->randr_crtc)
return FALSE;
return RRCrtcIsLeased(crtc->randr_crtc);
}
/**
* Return whether the output is leased by a client
*/
static Bool
xf86OutputIsLeased(xf86OutputPtr output)
{
/* If the DIX structure hasn't been created, it can't have been leased */
if (!output->randr_output)
return FALSE;
return RROutputIsLeased(output->randr_output);
}
void void
xf86CrtcSetScreenSubpixelOrder(ScreenPtr pScreen) xf86CrtcSetScreenSubpixelOrder(ScreenPtr pScreen)
{ {
@ -254,7 +280,7 @@ xf86CrtcSetModeTransform(xf86CrtcPtr crtc, DisplayModePtr mode,
RRTransformRec saved_transform; RRTransformRec saved_transform;
Bool saved_transform_present; Bool saved_transform_present;
crtc->enabled = xf86CrtcInUse(crtc) && !RRCrtcIsLeased(crtc->randr_crtc);; crtc->enabled = xf86CrtcInUse(crtc) && !xf86CrtcIsLeased(crtc);
/* We only hit this if someone explicitly sends a "disabled" modeset. */ /* We only hit this if someone explicitly sends a "disabled" modeset. */
if (!crtc->enabled) { if (!crtc->enabled) {
@ -412,7 +438,7 @@ xf86CrtcSetOrigin(xf86CrtcPtr crtc, int x, int y)
crtc->x = x; crtc->x = x;
crtc->y = y; crtc->y = y;
if (RRCrtcIsLeased(crtc->randr_crtc)) if (xf86CrtcIsLeased(crtc))
return; return;
if (crtc->funcs->set_origin) { if (crtc->funcs->set_origin) {
@ -734,14 +760,11 @@ xf86CrtcCloseScreen(ScreenPtr screen)
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int o, c; int o, c;
screen->CloseScreen = config->CloseScreen; /* The randr_output and randr_crtc pointers are already invalid as
* the DIX resources were freed when the associated resources were
xf86RotateCloseScreen(screen); * freed. Clear them now; referencing through them during the rest
* of the CloseScreen sequence will not end well.
xf86RandR12CloseScreen(screen); */
screen->CloseScreen(screen);
for (o = 0; o < config->num_output; o++) { for (o = 0; o < config->num_output; o++) {
xf86OutputPtr output = config->output[o]; xf86OutputPtr output = config->output[o];
@ -752,6 +775,15 @@ xf86CrtcCloseScreen(ScreenPtr screen)
crtc->randr_crtc = NULL; crtc->randr_crtc = NULL;
} }
screen->CloseScreen = config->CloseScreen;
xf86RotateCloseScreen(screen);
xf86RandR12CloseScreen(screen);
screen->CloseScreen(screen);
/* detach any providers */ /* detach any providers */
if (config->randr_provider) { if (config->randr_provider) {
RRProviderDestroy(config->randr_provider); RRProviderDestroy(config->randr_provider);
@ -2656,7 +2688,7 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
static void static void
xf86DisableCrtc(xf86CrtcPtr crtc) xf86DisableCrtc(xf86CrtcPtr crtc)
{ {
if (RRCrtcIsLeased(crtc->randr_crtc)) if (xf86CrtcIsLeased(crtc))
return; return;
crtc->funcs->dpms(crtc, DPMSModeOff); crtc->funcs->dpms(crtc, DPMSModeOff);
@ -2677,7 +2709,7 @@ xf86PrepareOutputs(ScrnInfoPtr scrn)
for (o = 0; o < config->num_output; o++) { for (o = 0; o < config->num_output; o++) {
xf86OutputPtr output = config->output[o]; xf86OutputPtr output = config->output[o];
if (RROutputIsLeased(output->randr_output)) if (xf86OutputIsLeased(output))
continue; continue;
#if RANDR_GET_CRTC_INTERFACE #if RANDR_GET_CRTC_INTERFACE
@ -2703,7 +2735,7 @@ xf86PrepareCrtcs(ScrnInfoPtr scrn)
uint32_t desired_outputs = 0, current_outputs = 0; uint32_t desired_outputs = 0, current_outputs = 0;
int o; int o;
if (RRCrtcIsLeased(crtc->randr_crtc)) if (xf86CrtcIsLeased(crtc))
continue; continue;
for (o = 0; o < config->num_output; o++) { for (o = 0; o < config->num_output; o++) {
@ -2726,7 +2758,7 @@ xf86PrepareCrtcs(ScrnInfoPtr scrn)
if (desired_outputs != current_outputs || !desired_outputs) if (desired_outputs != current_outputs || !desired_outputs)
xf86DisableCrtc(crtc); xf86DisableCrtc(crtc);
#else #else
if (RRCrtcIsLeased(crtc->randr_crtc)) if (xf86CrtcIsLeased(crtc))
continue; continue;
xf86DisableCrtc(crtc); xf86DisableCrtc(crtc);
@ -2964,7 +2996,7 @@ xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags)
for (i = 0; i < config->num_output; i++) { for (i = 0; i < config->num_output; i++) {
xf86OutputPtr output = config->output[i]; xf86OutputPtr output = config->output[i];
if (!RROutputIsLeased(output->randr_output) && output->crtc != NULL) if (!xf86OutputIsLeased(output) && output->crtc != NULL)
(*output->funcs->dpms) (output, mode); (*output->funcs->dpms) (output, mode);
} }
} }
@ -2980,7 +3012,7 @@ xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags)
for (i = 0; i < config->num_output; i++) { for (i = 0; i < config->num_output; i++) {
xf86OutputPtr output = config->output[i]; xf86OutputPtr output = config->output[i];
if (!RROutputIsLeased(output->randr_output) && output->crtc != NULL) if (!xf86OutputIsLeased(output) && output->crtc != NULL)
(*output->funcs->dpms) (output, mode); (*output->funcs->dpms) (output, mode);
} }
} }

View file

@ -26,8 +26,7 @@ endif
if ALPHA_VIDEO if ALPHA_VIDEO
# Cheat here and piggyback other alpha bits on ALPHA_VIDEO. # Cheat here and piggyback other alpha bits on ALPHA_VIDEO.
ARCH_SOURCES = \ ARCH_SOURCES = \
alpha_video.c \ alpha_video.c
bsd_ev56.c
endif endif
if ARM_VIDEO if ARM_VIDEO

View file

@ -1,13 +1,5 @@
noinst_LTLIBRARIES = liblinux.la noinst_LTLIBRARIES = liblinux.la
if LINUX_ALPHA
noinst_LTLIBRARIES += liblinuxev56.la
liblinuxev56_la_CFLAGS = $(AM_CFLAGS) -mcpu=ev56
liblinuxev56_la_SOURCES = lnx_ev56.c
endif
if LNXACPI if LNXACPI
ACPI_SRCS = lnx_acpi.c ACPI_SRCS = lnx_acpi.c
if !LNXAPM if !LNXAPM
@ -39,7 +31,3 @@ liblinux_la_SOURCES = linux.h lnx_init.c lnx_video.c \
AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(DIX_CFLAGS) $(XORG_CFLAGS) $(PLATFORM_DEFINES) AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(DIX_CFLAGS) $(XORG_CFLAGS) $(PLATFORM_DEFINES)
AM_CPPFLAGS = $(XORG_INCS) $(PLATFORM_INCLUDES) $(LIBDRM_CFLAGS) AM_CPPFLAGS = $(XORG_INCS) $(PLATFORM_INCLUDES) $(LIBDRM_CFLAGS)
if LINUX_ALPHA
liblinux_la_LIBADD = liblinuxev56.la
endif

View file

@ -346,6 +346,13 @@ xf86CloseConsole(void)
close(xf86Info.consoleFd); /* make the vt-manager happy */ close(xf86Info.consoleFd); /* make the vt-manager happy */
} }
#define CHECK_FOR_REQUIRED_ARGUMENT() \
if (((i + 1) >= argc) || (!argv[i + 1])) { \
ErrorF("Required argument to %s not specified\n", argv[i]); \
UseMsg(); \
FatalError("Required argument to %s not specified\n", argv[i]); \
}
int int
xf86ProcessArgument(int argc, char *argv[], int i) xf86ProcessArgument(int argc, char *argv[], int i)
{ {
@ -366,6 +373,19 @@ xf86ProcessArgument(int argc, char *argv[], int i)
} }
return 1; return 1;
} }
if (!strcmp(argv[i], "-masterfd")) {
CHECK_FOR_REQUIRED_ARGUMENT();
if (xf86PrivsElevated())
FatalError("\nCannot specify -masterfd when server is setuid/setgid\n");
if (sscanf(argv[++i], "%d", &xf86DRMMasterFd) != 1) {
UseMsg();
xf86DRMMasterFd = -1;
return 0;
}
return 2;
}
return 0; return 0;
} }
@ -375,4 +395,5 @@ xf86UseMsg(void)
ErrorF("vtXX use the specified VT number\n"); ErrorF("vtXX use the specified VT number\n");
ErrorF("-keeptty "); ErrorF("-keeptty ");
ErrorF("don't detach controlling tty (for debugging only)\n"); ErrorF("don't detach controlling tty (for debugging only)\n");
ErrorF("-masterfd <fd> use the specified fd as the DRM master fd (not if setuid/gid)\n");
} }

View file

@ -43,7 +43,7 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
} }
if (fd == -1) if (fd == -1)
fd = open(path, O_RDWR, O_CLOEXEC); fd = open(path, O_RDWR | O_CLOEXEC, 0);
if (fd == -1) if (fd == -1)
return FALSE; return FALSE;

View file

@ -166,30 +166,3 @@ xf86DisableIO(void)
ExtendedEnabled = FALSE; ExtendedEnabled = FALSE;
} }
#if defined (__alpha__)
extern int readDense8(void *Base, register unsigned long Offset);
extern int readDense16(void *Base, register unsigned long Offset);
extern int readDense32(void *Base, register unsigned long Offset);
extern void
writeDense8(int Value, void *Base, register unsigned long Offset);
extern void
writeDense16(int Value, void *Base, register unsigned long Offset);
extern void
writeDense32(int Value, void *Base, register unsigned long Offset);
void (*xf86WriteMmio8) (int Value, void *Base, unsigned long Offset)
= writeDense8;
void (*xf86WriteMmio16) (int Value, void *Base, unsigned long Offset)
= writeDense16;
void (*xf86WriteMmio32) (int Value, void *Base, unsigned long Offset)
= writeDense32;
int (*xf86ReadMmio8) (void *Base, unsigned long Offset)
= readDense8;
int (*xf86ReadMmio16) (void *Base, unsigned long Offset)
= readDense16;
int (*xf86ReadMmio32) (void *Base, unsigned long Offset)
= readDense32;
#endif /* __alpha__ */

View file

@ -100,7 +100,6 @@ elif host_machine.system().endswith('bsd')
srcs_xorg_os_support += 'shared/ioperm_noop.c' srcs_xorg_os_support += 'shared/ioperm_noop.c'
elif host_machine.cpu_family() == 'alpha' elif host_machine.cpu_family() == 'alpha'
srcs_xorg_os_support += 'bsd/alpha_video.c' srcs_xorg_os_support += 'bsd/alpha_video.c'
srcs_xorg_os_support += 'bsd/bsd_ev56.c'
endif endif
if host_machine.system() == 'freebsd' if host_machine.system() == 'freebsd'

View file

@ -188,7 +188,7 @@ xf86SetSerial(int fd, XF86OptionPtr options)
{ {
struct termios t; struct termios t;
int val; int val;
const char *s; char *s;
int baud, r; int baud, r;
if (fd < 0) if (fd < 0)
@ -264,8 +264,10 @@ xf86SetSerial(int fd, XF86OptionPtr options)
} }
else { else {
xf86Msg(X_ERROR, "Invalid Option Parity value: %s\n", s); xf86Msg(X_ERROR, "Invalid Option Parity value: %s\n", s);
free(s);
return -1; return -1;
} }
free(s);
} }
if ((val = xf86SetIntOption(options, "Vmin", -1)) != -1) { if ((val = xf86SetIntOption(options, "Vmin", -1)) != -1) {
@ -291,8 +293,10 @@ xf86SetSerial(int fd, XF86OptionPtr options)
} }
else { else {
xf86Msg(X_ERROR, "Invalid Option FlowControl value: %s\n", s); xf86Msg(X_ERROR, "Invalid Option FlowControl value: %s\n", s);
free(s);
return -1; return -1;
} }
free(s);
} }
if ((xf86SetBoolOption(options, "ClearDTR", FALSE))) { if ((xf86SetBoolOption(options, "ClearDTR", FALSE))) {

View file

@ -187,6 +187,85 @@ xwl_eglstream_cleanup(struct xwl_screen *xwl_screen)
free(xwl_eglstream); free(xwl_eglstream);
} }
static Bool
xwl_glamor_egl_supports_device_probing(void)
{
return epoxy_has_egl_extension(NULL, "EGL_EXT_device_base");
}
static void **
xwl_glamor_egl_get_devices(int *num_devices)
{
EGLDeviceEXT *devices;
Bool ret;
int drm_dev_count = 0;
int i;
if (!xwl_glamor_egl_supports_device_probing())
return NULL;
/* Get the number of devices */
ret = eglQueryDevicesEXT(0, NULL, num_devices);
if (!ret || *num_devices < 1)
return NULL;
devices = calloc(*num_devices, sizeof(EGLDeviceEXT));
if (!devices)
return NULL;
ret = eglQueryDevicesEXT(*num_devices, devices, num_devices);
if (!ret)
goto error;
/* We're only ever going to care about devices that support
* EGL_EXT_device_drm, so filter out the ones that don't
*/
for (i = 0; i < *num_devices; i++) {
const char *extension_str =
eglQueryDeviceStringEXT(devices[i], EGL_EXTENSIONS);
if (!epoxy_extension_in_string(extension_str, "EGL_EXT_device_drm"))
continue;
devices[drm_dev_count++] = devices[i];
}
if (!drm_dev_count)
goto error;
*num_devices = drm_dev_count;
devices = realloc(devices, sizeof(EGLDeviceEXT) * drm_dev_count);
return devices;
error:
free(devices);
return NULL;
}
static Bool
xwl_glamor_egl_device_has_egl_extensions(void *device,
const char **ext_list, size_t size)
{
EGLDisplay egl_display;
int i;
Bool has_exts = TRUE;
egl_display = glamor_egl_get_display(EGL_PLATFORM_DEVICE_EXT, device);
if (!egl_display || !eglInitialize(egl_display, NULL, NULL))
return FALSE;
for (i = 0; i < size; i++) {
if (!epoxy_has_egl_extension(egl_display, ext_list[i])) {
has_exts = FALSE;
break;
}
}
eglTerminate(egl_display);
return has_exts;
}
static void static void
xwl_eglstream_unref_pixmap_stream(struct xwl_pixmap *xwl_pixmap) xwl_eglstream_unref_pixmap_stream(struct xwl_pixmap *xwl_pixmap)
{ {
@ -229,8 +308,6 @@ xwl_glamor_eglstream_destroy_pixmap(PixmapPtr pixmap)
static struct wl_buffer * static struct wl_buffer *
xwl_glamor_eglstream_get_wl_buffer_for_pixmap(PixmapPtr pixmap, xwl_glamor_eglstream_get_wl_buffer_for_pixmap(PixmapPtr pixmap,
unsigned short width,
unsigned short height,
Bool *created) Bool *created)
{ {
/* XXX created? */ /* XXX created? */
@ -559,11 +636,11 @@ const struct wl_eglstream_display_listener eglstream_display_listener = {
.swapinterval_override = xwl_eglstream_display_handle_swapinterval_override, .swapinterval_override = xwl_eglstream_display_handle_swapinterval_override,
}; };
static void static Bool
xwl_glamor_eglstream_init_wl_registry(struct xwl_screen *xwl_screen, xwl_glamor_eglstream_init_wl_registry(struct xwl_screen *xwl_screen,
struct wl_registry *wl_registry, struct wl_registry *wl_registry,
const char *name, uint32_t id, const char *name,
uint32_t id, uint32_t version) uint32_t version)
{ {
struct xwl_eglstream_private *xwl_eglstream = struct xwl_eglstream_private *xwl_eglstream =
xwl_eglstream_get(xwl_screen); xwl_eglstream_get(xwl_screen);
@ -575,10 +652,34 @@ xwl_glamor_eglstream_init_wl_registry(struct xwl_screen *xwl_screen,
wl_eglstream_display_add_listener(xwl_eglstream->display, wl_eglstream_display_add_listener(xwl_eglstream->display,
&eglstream_display_listener, &eglstream_display_listener,
xwl_screen); xwl_screen);
return TRUE;
} else if (strcmp(name, "wl_eglstream_controller") == 0) { } else if (strcmp(name, "wl_eglstream_controller") == 0) {
xwl_eglstream->controller = wl_registry_bind( xwl_eglstream->controller = wl_registry_bind(
wl_registry, id, &wl_eglstream_controller_interface, version); wl_registry, id, &wl_eglstream_controller_interface, version);
return TRUE;
} }
/* no match */
return FALSE;
}
static Bool
xwl_glamor_eglstream_has_wl_interfaces(struct xwl_screen *xwl_screen)
{
struct xwl_eglstream_private *xwl_eglstream =
xwl_eglstream_get(xwl_screen);
if (xwl_eglstream->display == NULL) {
ErrorF("glamor: 'wl_eglstream_display' not supported\n");
return FALSE;
}
if (xwl_eglstream->controller == NULL) {
ErrorF("glamor: 'wl_eglstream_controller' not supported\n");
return FALSE;
}
return TRUE;
} }
static inline void static inline void
@ -691,6 +792,12 @@ xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen)
goto error; goto error;
} }
if (!epoxy_has_egl_extension(xwl_screen->egl_display,
"EGL_IMG_context_priority")) {
ErrorF("EGL_IMG_context_priority not available\n");
goto error;
}
eglChooseConfig(xwl_screen->egl_display, config_attribs, &config, 1, &n); eglChooseConfig(xwl_screen->egl_display, config_attribs, &config, 1, &n);
if (!n) { if (!n) {
ErrorF("No acceptable EGL configs found\n"); ErrorF("No acceptable EGL configs found\n");
@ -740,14 +847,6 @@ xwl_glamor_eglstream_init_screen(struct xwl_screen *xwl_screen)
xwl_eglstream_get(xwl_screen); xwl_eglstream_get(xwl_screen);
ScreenPtr screen = xwl_screen->screen; ScreenPtr screen = xwl_screen->screen;
if (!xwl_eglstream->controller) {
ErrorF("No eglstream controller was exposed in the wayland registry. "
"This means your version of nvidia's EGL wayland libraries "
"are too old, as we require support for this.\n");
xwl_eglstream_cleanup(xwl_screen);
return FALSE;
}
/* We can just let glamor handle CreatePixmap */ /* We can just let glamor handle CreatePixmap */
screen->DestroyPixmap = xwl_glamor_eglstream_destroy_pixmap; screen->DestroyPixmap = xwl_glamor_eglstream_destroy_pixmap;
@ -792,23 +891,24 @@ out:
return device; return device;
} }
Bool void
xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen) xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen)
{ {
struct xwl_eglstream_private *xwl_eglstream; struct xwl_eglstream_private *xwl_eglstream;
EGLDeviceEXT egl_device; EGLDeviceEXT egl_device;
xwl_screen->eglstream_backend.is_available = FALSE;
egl_device = xwl_eglstream_get_device(xwl_screen); egl_device = xwl_eglstream_get_device(xwl_screen);
if (egl_device == EGL_NO_DEVICE_EXT) if (egl_device == EGL_NO_DEVICE_EXT)
return FALSE; return;
if (!dixRegisterPrivateKey(&xwl_eglstream_private_key, PRIVATE_SCREEN, 0)) if (!dixRegisterPrivateKey(&xwl_eglstream_private_key, PRIVATE_SCREEN, 0))
return FALSE; return;
xwl_eglstream = calloc(sizeof(*xwl_eglstream), 1); xwl_eglstream = calloc(sizeof(*xwl_eglstream), 1);
if (!xwl_eglstream) { if (!xwl_eglstream) {
ErrorF("Failed to allocate memory required to init eglstream support\n"); ErrorF("Failed to allocate memory required to init EGLStream support\n");
return FALSE; return;
} }
dixSetPrivate(&xwl_screen->screen->devPrivates, dixSetPrivate(&xwl_screen->screen->devPrivates,
@ -817,14 +917,12 @@ xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen)
xwl_eglstream->egl_device = egl_device; xwl_eglstream->egl_device = egl_device;
xorg_list_init(&xwl_eglstream->pending_streams); xorg_list_init(&xwl_eglstream->pending_streams);
xwl_screen->egl_backend.init_egl = xwl_glamor_eglstream_init_egl; xwl_screen->eglstream_backend.init_egl = xwl_glamor_eglstream_init_egl;
xwl_screen->egl_backend.init_wl_registry = xwl_glamor_eglstream_init_wl_registry; xwl_screen->eglstream_backend.init_wl_registry = xwl_glamor_eglstream_init_wl_registry;
xwl_screen->egl_backend.init_screen = xwl_glamor_eglstream_init_screen; xwl_screen->eglstream_backend.has_wl_interfaces = xwl_glamor_eglstream_has_wl_interfaces;
xwl_screen->egl_backend.get_wl_buffer_for_pixmap = xwl_glamor_eglstream_get_wl_buffer_for_pixmap; xwl_screen->eglstream_backend.init_screen = xwl_glamor_eglstream_init_screen;
xwl_screen->egl_backend.post_damage = xwl_glamor_eglstream_post_damage; xwl_screen->eglstream_backend.get_wl_buffer_for_pixmap = xwl_glamor_eglstream_get_wl_buffer_for_pixmap;
xwl_screen->egl_backend.allow_commits = xwl_glamor_eglstream_allow_commits; xwl_screen->eglstream_backend.post_damage = xwl_glamor_eglstream_post_damage;
xwl_screen->eglstream_backend.allow_commits = xwl_glamor_eglstream_allow_commits;
ErrorF("glamor: Using nvidia's eglstream interface, direct rendering impossible.\n"); xwl_screen->eglstream_backend.is_available = TRUE;
ErrorF("glamor: Performance may be affected. Ask your vendor to support GBM!\n");
return TRUE;
} }

View file

@ -230,13 +230,13 @@ xwl_glamor_gbm_destroy_pixmap(PixmapPtr pixmap)
static struct wl_buffer * static struct wl_buffer *
xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap, xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap,
unsigned short width,
unsigned short height,
Bool *created) Bool *created)
{ {
struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen); struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap); struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen); struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
unsigned short width = pixmap->drawable.width;
unsigned short height = pixmap->drawable.height;
int prime_fd; int prime_fd;
int num_planes; int num_planes;
uint32_t strides[4]; uint32_t strides[4];
@ -272,7 +272,7 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap,
#else #else
num_planes = 1; num_planes = 1;
modifier = DRM_FORMAT_MOD_INVALID; modifier = DRM_FORMAT_MOD_INVALID;
strides[0] = gbm_go_get_stride(xwl_pixmap->bo); strides[0] = gbm_bo_get_stride(xwl_pixmap->bo);
offsets[0] = 0; offsets[0] = 0;
#endif #endif
@ -517,6 +517,16 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
#endif #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;
}
_X_EXPORT Bool _X_EXPORT Bool
glamor_get_formats(ScreenPtr screen, glamor_get_formats(ScreenPtr screen,
CARD32 *num_formats, CARD32 **formats) CARD32 *num_formats, CARD32 **formats)
@ -734,16 +744,42 @@ xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
return TRUE; return TRUE;
} }
static void static Bool
xwl_glamor_gbm_init_wl_registry(struct xwl_screen *xwl_screen, xwl_glamor_gbm_init_wl_registry(struct xwl_screen *xwl_screen,
struct wl_registry *wl_registry, struct wl_registry *wl_registry,
const char *name, uint32_t id, const char *name,
uint32_t id, uint32_t version) uint32_t version)
{ {
if (strcmp(name, "wl_drm") == 0) if (strcmp(name, "wl_drm") == 0) {
xwl_screen_set_drm_interface(xwl_screen, id, version); xwl_screen_set_drm_interface(xwl_screen, id, version);
else if (strcmp(name, "zwp_linux_dmabuf_v1") == 0) return TRUE;
} else if (strcmp(name, "zwp_linux_dmabuf_v1") == 0) {
xwl_screen_set_dmabuf_interface(xwl_screen, id, version); 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 static Bool
@ -761,6 +797,7 @@ xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen)
GLAMOR_GL_CORE_VER_MINOR, GLAMOR_GL_CORE_VER_MINOR,
EGL_NONE EGL_NONE
}; };
const GLubyte *renderer;
if (!xwl_gbm->fd_render_node && !xwl_gbm->drm_authenticated) { if (!xwl_gbm->fd_render_node && !xwl_gbm->drm_authenticated) {
ErrorF("Failed to get wl_drm, disabling Glamor and DRI3\n"); ErrorF("Failed to get wl_drm, disabling Glamor and DRI3\n");
@ -807,8 +844,20 @@ xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen)
goto error; goto error;
} }
if (!epoxy_has_gl_extension("GL_OES_EGL_image")) 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"); ErrorF("GL_OES_EGL_image not available\n");
goto error;
}
if (epoxy_has_egl_extension(xwl_screen->egl_display, if (epoxy_has_egl_extension(xwl_screen->egl_display,
"EXT_image_dma_buf_import") && "EXT_image_dma_buf_import") &&
@ -835,11 +884,16 @@ error:
static Bool static Bool
xwl_glamor_gbm_init_screen(struct xwl_screen *xwl_screen) 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)) { if (!dri3_screen_init(xwl_screen->screen, &xwl_dri3_info)) {
ErrorF("Failed to initialize dri3\n"); ErrorF("Failed to initialize dri3\n");
goto error; goto error;
} }
if (xwl_gbm->fd_render_node)
goto skip_drm_auth;
if (!dixRegisterPrivateKey(&xwl_auth_state_private_key, PRIVATE_CLIENT, if (!dixRegisterPrivateKey(&xwl_auth_state_private_key, PRIVATE_CLIENT,
0)) { 0)) {
ErrorF("Failed to register private key\n"); ErrorF("Failed to register private key\n");
@ -852,6 +906,7 @@ xwl_glamor_gbm_init_screen(struct xwl_screen *xwl_screen)
goto error; goto error;
} }
skip_drm_auth:
xwl_screen->screen->CreatePixmap = xwl_glamor_gbm_create_pixmap; xwl_screen->screen->CreatePixmap = xwl_glamor_gbm_create_pixmap;
xwl_screen->screen->DestroyPixmap = xwl_glamor_gbm_destroy_pixmap; xwl_screen->screen->DestroyPixmap = xwl_glamor_gbm_destroy_pixmap;
@ -861,27 +916,32 @@ error:
return FALSE; return FALSE;
} }
Bool void
xwl_glamor_init_gbm(struct xwl_screen *xwl_screen) xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
{ {
struct xwl_gbm_private *xwl_gbm; 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)) if (!dixRegisterPrivateKey(&xwl_gbm_private_key, PRIVATE_SCREEN, 0))
return FALSE; return;
xwl_gbm = calloc(sizeof(*xwl_gbm), 1); xwl_gbm = calloc(sizeof(*xwl_gbm), 1);
if (!xwl_gbm) { if (!xwl_gbm) {
ErrorF("glamor: Not enough memory to setup GBM, disabling\n"); ErrorF("glamor: Not enough memory to setup GBM, disabling\n");
return FALSE; return;
} }
dixSetPrivate(&xwl_screen->screen->devPrivates, &xwl_gbm_private_key, dixSetPrivate(&xwl_screen->screen->devPrivates, &xwl_gbm_private_key,
xwl_gbm); xwl_gbm);
xwl_screen->egl_backend.init_wl_registry = xwl_glamor_gbm_init_wl_registry; xwl_screen->gbm_backend.init_wl_registry = xwl_glamor_gbm_init_wl_registry;
xwl_screen->egl_backend.init_egl = xwl_glamor_gbm_init_egl; xwl_screen->gbm_backend.has_wl_interfaces = xwl_glamor_gbm_has_wl_interfaces;
xwl_screen->egl_backend.init_screen = xwl_glamor_gbm_init_screen; xwl_screen->gbm_backend.init_egl = xwl_glamor_gbm_init_egl;
xwl_screen->egl_backend.get_wl_buffer_for_pixmap = xwl_glamor_gbm_get_wl_buffer_for_pixmap; 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;
return TRUE; xwl_screen->gbm_backend.is_available = TRUE;
} }

View file

@ -52,88 +52,12 @@ xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen)
xwl_screen->glamor_ctx->make_current(xwl_screen->glamor_ctx); xwl_screen->glamor_ctx->make_current(xwl_screen->glamor_ctx);
} }
Bool
xwl_glamor_egl_supports_device_probing(void)
{
return epoxy_has_egl_extension(NULL, "EGL_EXT_device_base");
}
void **
xwl_glamor_egl_get_devices(int *num_devices)
{
#ifdef XWL_HAS_EGLSTREAM
EGLDeviceEXT *devices;
Bool ret;
int drm_dev_count = 0;
int i;
/* Get the number of devices */
ret = eglQueryDevicesEXT(0, NULL, num_devices);
if (!ret || *num_devices < 1)
return NULL;
devices = calloc(*num_devices, sizeof(EGLDeviceEXT));
if (!devices)
return NULL;
ret = eglQueryDevicesEXT(*num_devices, devices, num_devices);
if (!ret)
goto error;
/* We're only ever going to care about devices that support
* EGL_EXT_device_drm, so filter out the ones that don't
*/
for (i = 0; i < *num_devices; i++) {
const char *extension_str =
eglQueryDeviceStringEXT(devices[i], EGL_EXTENSIONS);
if (!epoxy_extension_in_string(extension_str, "EGL_EXT_device_drm"))
continue;
devices[drm_dev_count++] = devices[i];
}
if (!drm_dev_count)
goto error;
*num_devices = drm_dev_count;
devices = realloc(devices, sizeof(EGLDeviceEXT) * drm_dev_count);
return devices;
error:
free(devices);
#endif
return NULL;
}
Bool
xwl_glamor_egl_device_has_egl_extensions(void *device,
const char **ext_list, size_t size)
{
EGLDisplay egl_display;
int i;
Bool has_exts = TRUE;
egl_display = glamor_egl_get_display(EGL_PLATFORM_DEVICE_EXT, device);
if (!egl_display || !eglInitialize(egl_display, NULL, NULL))
return FALSE;
for (i = 0; i < size; i++) {
if (!epoxy_has_egl_extension(egl_display, ext_list[i])) {
has_exts = FALSE;
break;
}
}
eglTerminate(egl_display);
return has_exts;
}
void void
glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx) glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
{ {
struct xwl_screen *xwl_screen = xwl_screen_get(screen); struct xwl_screen *xwl_screen = xwl_screen_get(screen);
glamor_enable_dri3(screen);
glamor_ctx->ctx = xwl_screen->egl_context; glamor_ctx->ctx = xwl_screen->egl_context;
glamor_ctx->display = xwl_screen->egl_display; glamor_ctx->display = xwl_screen->egl_display;
@ -148,24 +72,36 @@ xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
uint32_t id, const char *interface, uint32_t id, const char *interface,
uint32_t version) uint32_t version)
{ {
if (xwl_screen->egl_backend.init_wl_registry) if (xwl_screen->gbm_backend.is_available &&
xwl_screen->egl_backend.init_wl_registry(xwl_screen, registry, xwl_screen->gbm_backend.init_wl_registry(xwl_screen,
interface, id, version); 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 * struct wl_buffer *
xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap, xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap,
unsigned short width,
unsigned short height,
Bool *created) Bool *created)
{ {
struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen); struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
if (xwl_screen->egl_backend.get_wl_buffer_for_pixmap) if (xwl_screen->egl_backend->get_wl_buffer_for_pixmap)
return xwl_screen->egl_backend.get_wl_buffer_for_pixmap(pixmap, return xwl_screen->egl_backend->get_wl_buffer_for_pixmap(pixmap,
width, created);
height,
created);
return NULL; return NULL;
} }
@ -176,8 +112,8 @@ xwl_glamor_post_damage(struct xwl_window *xwl_window,
{ {
struct xwl_screen *xwl_screen = xwl_window->xwl_screen; struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
if (xwl_screen->egl_backend.post_damage) if (xwl_screen->egl_backend->post_damage)
xwl_screen->egl_backend.post_damage(xwl_window, pixmap, region); xwl_screen->egl_backend->post_damage(xwl_window, pixmap, region);
} }
Bool Bool
@ -185,8 +121,8 @@ xwl_glamor_allow_commits(struct xwl_window *xwl_window)
{ {
struct xwl_screen *xwl_screen = xwl_window->xwl_screen; struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
if (xwl_screen->egl_backend.allow_commits) if (xwl_screen->egl_backend->allow_commits)
return xwl_screen->egl_backend.allow_commits(xwl_window); return xwl_screen->egl_backend->allow_commits(xwl_window);
else else
return TRUE; return TRUE;
} }
@ -228,6 +164,68 @@ glamor_egl_fd_name_from_pixmap(ScreenPtr screen,
return 0; return 0;
} }
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)) {
ErrorF("glamor: Using nvidia's EGLStream interface, direct rendering impossible.\n");
ErrorF("glamor: Performance may be affected. Ask your vendor to support GBM!\n");
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 Bool
xwl_glamor_init(struct xwl_screen *xwl_screen) xwl_glamor_init(struct xwl_screen *xwl_screen)
{ {
@ -240,7 +238,7 @@ xwl_glamor_init(struct xwl_screen *xwl_screen)
return FALSE; return FALSE;
} }
if (!xwl_screen->egl_backend.init_egl(xwl_screen)) { if (!xwl_screen->egl_backend->init_egl(xwl_screen)) {
ErrorF("EGL setup failed, disabling glamor\n"); ErrorF("EGL setup failed, disabling glamor\n");
return FALSE; return FALSE;
} }
@ -250,7 +248,7 @@ xwl_glamor_init(struct xwl_screen *xwl_screen)
return FALSE; return FALSE;
} }
if (!xwl_screen->egl_backend.init_screen(xwl_screen)) { if (!xwl_screen->egl_backend->init_screen(xwl_screen)) {
ErrorF("EGL backend init_screen() failed, disabling glamor\n"); ErrorF("EGL backend init_screen() failed, disabling glamor\n");
return FALSE; return FALSE;
} }

View file

@ -37,6 +37,12 @@
#include <misc.h> #include <misc.h>
#include "tablet-unstable-v2-client-protocol.h" #include "tablet-unstable-v2-client-protocol.h"
struct axis_discrete_pending {
struct xorg_list l;
uint32_t axis;
int32_t discrete;
};
struct sync_pending { struct sync_pending {
struct xorg_list l; struct xorg_list l;
DeviceIntPtr pending_dev; DeviceIntPtr pending_dev;
@ -565,6 +571,8 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer,
int index; int index;
const int divisor = 10; const int divisor = 10;
ValuatorMask mask; ValuatorMask mask;
struct axis_discrete_pending *pending = NULL;
struct axis_discrete_pending *iter;
switch (axis) { switch (axis) {
case WL_POINTER_AXIS_VERTICAL_SCROLL: case WL_POINTER_AXIS_VERTICAL_SCROLL:
@ -577,8 +585,22 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer,
return; return;
} }
xorg_list_for_each_entry(iter, &xwl_seat->axis_discrete_pending, l) {
if (iter->axis == axis) {
pending = iter;
break;
}
}
valuator_mask_zero(&mask); valuator_mask_zero(&mask);
valuator_mask_set_double(&mask, index, wl_fixed_to_double(value) / divisor);
if (pending) {
valuator_mask_set(&mask, index, pending->discrete);
xorg_list_del(&pending->l);
free(pending);
} else {
valuator_mask_set_double(&mask, index, wl_fixed_to_double(value) / divisor);
}
QueuePointerEvents(xwl_seat->pointer, MotionNotify, 0, POINTER_RELATIVE, &mask); QueuePointerEvents(xwl_seat->pointer, MotionNotify, 0, POINTER_RELATIVE, &mask);
} }
@ -608,6 +630,16 @@ static void
pointer_handle_axis_discrete(void *data, struct wl_pointer *wl_pointer, pointer_handle_axis_discrete(void *data, struct wl_pointer *wl_pointer,
uint32_t axis, int32_t discrete) uint32_t axis, int32_t discrete)
{ {
struct xwl_seat *xwl_seat = data;
struct axis_discrete_pending *pending = malloc(sizeof *pending);
if (!pending)
return;
pending->axis = axis;
pending->discrete = discrete;
xorg_list_add(&pending->l, &xwl_seat->axis_discrete_pending);
} }
static const struct wl_pointer_listener pointer_listener = { static const struct wl_pointer_listener pointer_listener = {
@ -1337,6 +1369,7 @@ create_input_device(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version
wl_array_init(&xwl_seat->keys); wl_array_init(&xwl_seat->keys);
xorg_list_init(&xwl_seat->touches); xorg_list_init(&xwl_seat->touches);
xorg_list_init(&xwl_seat->axis_discrete_pending);
xorg_list_init(&xwl_seat->sync_pending); xorg_list_init(&xwl_seat->sync_pending);
} }
@ -1345,6 +1378,7 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat)
{ {
struct xwl_touch *xwl_touch, *next_xwl_touch; struct xwl_touch *xwl_touch, *next_xwl_touch;
struct sync_pending *p, *npd; struct sync_pending *p, *npd;
struct axis_discrete_pending *ad, *ad_next;
xorg_list_for_each_entry_safe(xwl_touch, next_xwl_touch, xorg_list_for_each_entry_safe(xwl_touch, next_xwl_touch,
&xwl_seat->touches, link_touch) { &xwl_seat->touches, link_touch) {
@ -1357,6 +1391,11 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat)
free (p); free (p);
} }
xorg_list_for_each_entry_safe(ad, ad_next, &xwl_seat->axis_discrete_pending, l) {
xorg_list_del(&ad->l);
free(ad);
}
release_tablet_manager_seat(xwl_seat); release_tablet_manager_seat(xwl_seat);
release_grab(xwl_seat); release_grab(xwl_seat);
@ -1565,8 +1604,8 @@ tablet_tool_motion(void *data, struct zwp_tablet_tool_v2 *tool,
struct xwl_tablet_tool *xwl_tablet_tool = data; struct xwl_tablet_tool *xwl_tablet_tool = data;
struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
int32_t dx, dy; int32_t dx, dy;
int sx = wl_fixed_to_int(x); double sx = wl_fixed_to_double(x);
int sy = wl_fixed_to_int(y); double sy = wl_fixed_to_double(y);
if (!xwl_seat->tablet_focus_window) if (!xwl_seat->tablet_focus_window)
return; return;
@ -1574,8 +1613,8 @@ tablet_tool_motion(void *data, struct zwp_tablet_tool_v2 *tool,
dx = xwl_seat->tablet_focus_window->window->drawable.x; dx = xwl_seat->tablet_focus_window->window->drawable.x;
dy = xwl_seat->tablet_focus_window->window->drawable.y; dy = xwl_seat->tablet_focus_window->window->drawable.y;
xwl_tablet_tool->x = dx + sx; xwl_tablet_tool->x = (double) dx + sx;
xwl_tablet_tool->y = dy + sy; xwl_tablet_tool->y = (double) dy + sy;
} }
static void static void
@ -1733,15 +1772,15 @@ tablet_tool_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time)
int button; int button;
valuator_mask_zero(&mask); valuator_mask_zero(&mask);
valuator_mask_set(&mask, 0, xwl_tablet_tool->x); valuator_mask_set_double(&mask, 0, xwl_tablet_tool->x);
valuator_mask_set(&mask, 1, xwl_tablet_tool->y); valuator_mask_set_double(&mask, 1, xwl_tablet_tool->y);
valuator_mask_set(&mask, 2, xwl_tablet_tool->pressure); valuator_mask_set(&mask, 2, xwl_tablet_tool->pressure);
valuator_mask_set(&mask, 3, xwl_tablet_tool->tilt_x); valuator_mask_set_double(&mask, 3, xwl_tablet_tool->tilt_x);
valuator_mask_set(&mask, 4, xwl_tablet_tool->tilt_y); valuator_mask_set_double(&mask, 4, xwl_tablet_tool->tilt_y);
valuator_mask_set(&mask, 5, xwl_tablet_tool->rotation + xwl_tablet_tool->slider); valuator_mask_set_double(&mask, 5, xwl_tablet_tool->rotation + xwl_tablet_tool->slider);
QueuePointerEvents(xwl_tablet_tool->xdevice, MotionNotify, 0, QueuePointerEvents(xwl_tablet_tool->xdevice, MotionNotify, 0,
POINTER_ABSOLUTE | POINTER_SCREEN, &mask); POINTER_ABSOLUTE | POINTER_DESKTOP, &mask);
valuator_mask_zero(&mask); valuator_mask_zero(&mask);

View file

@ -38,6 +38,8 @@
RR_Reflect_X | \ RR_Reflect_X | \
RR_Reflect_Y) RR_Reflect_Y)
static void xwl_output_get_xdg_output(struct xwl_output *xwl_output);
static Rotation static Rotation
wl_transform_to_xrandr(enum wl_output_transform transform) wl_transform_to_xrandr(enum wl_output_transform transform)
{ {
@ -211,6 +213,7 @@ apply_output_change(struct xwl_output *xwl_output)
{ {
struct xwl_screen *xwl_screen = xwl_output->xwl_screen; struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
struct xwl_output *it; struct xwl_output *it;
int mode_width, mode_height;
int width = 0, height = 0, has_this_output = 0; int width = 0, height = 0, has_this_output = 0;
RRModePtr randr_mode; RRModePtr randr_mode;
Bool need_rotate; Bool need_rotate;
@ -222,7 +225,16 @@ apply_output_change(struct xwl_output *xwl_output)
/* xdg-output sends output size in compositor space. so already rotated */ /* xdg-output sends output size in compositor space. so already rotated */
need_rotate = (xwl_output->xdg_output == NULL); need_rotate = (xwl_output->xdg_output == NULL);
randr_mode = xwayland_cvt(xwl_output->width, xwl_output->height, /* We need to rotate back the logical size for the mode */
if (need_rotate || 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;
}
randr_mode = xwayland_cvt(mode_width, mode_height,
xwl_output->refresh / 1000.0, 0, 0); xwl_output->refresh / 1000.0, 0, 0);
RROutputSetModes(xwl_output->randr_output, &randr_mode, 1, 1); RROutputSetModes(xwl_output->randr_output, &randr_mode, 1, 1);
RRCrtcNotify(xwl_output->randr_crtc, randr_mode, RRCrtcNotify(xwl_output->randr_crtc, randr_mode,
@ -392,14 +404,15 @@ xwl_output_remove(struct xwl_output *xwl_output)
int width = 0, height = 0; int width = 0, height = 0;
Bool need_rotate = (xwl_output->xdg_output == NULL); Bool need_rotate = (xwl_output->xdg_output == NULL);
RRCrtcDestroy(xwl_output->randr_crtc);
RROutputDestroy(xwl_output->randr_output);
xorg_list_del(&xwl_output->link); xorg_list_del(&xwl_output->link);
xorg_list_for_each_entry(it, &xwl_screen->output_list, link) xorg_list_for_each_entry(it, &xwl_screen->output_list, link)
output_get_new_size(it, need_rotate, &height, &width); output_get_new_size(it, need_rotate, &height, &width);
update_screen_size(xwl_output, width, height); update_screen_size(xwl_output, width, height);
RRCrtcDestroy(xwl_output->randr_crtc);
RROutputDestroy(xwl_output->randr_output);
xwl_output_destroy(xwl_output); xwl_output_destroy(xwl_output);
} }
@ -435,7 +448,7 @@ xwl_screen_init_output(struct xwl_screen *xwl_screen)
return TRUE; return TRUE;
} }
void static void
xwl_output_get_xdg_output(struct xwl_output *xwl_output) xwl_output_get_xdg_output(struct xwl_output *xwl_output)
{ {
struct xwl_screen *xwl_screen = xwl_output->xwl_screen; struct xwl_screen *xwl_screen = xwl_output->xwl_screen;

View file

@ -147,6 +147,11 @@ xwl_present_cleanup(WindowPtr window)
/* Clear timer */ /* Clear timer */
xwl_present_free_timer(xwl_present_window); 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); free(xwl_present_window);
} }
@ -440,7 +445,7 @@ xwl_present_flip(WindowPtr present_window,
{ {
struct xwl_window *xwl_window = xwl_window_from_window(present_window); struct xwl_window *xwl_window = xwl_window_from_window(present_window);
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(present_window); struct xwl_present_window *xwl_present_window = xwl_present_window_priv(present_window);
BoxPtr present_box, damage_box; BoxPtr damage_box;
Bool buffer_created; Bool buffer_created;
struct wl_buffer *buffer; struct wl_buffer *buffer;
struct xwl_present_event *event; struct xwl_present_event *event;
@ -448,7 +453,6 @@ xwl_present_flip(WindowPtr present_window,
if (!xwl_window) if (!xwl_window)
return FALSE; return FALSE;
present_box = RegionExtents(&present_window->winSize);
damage_box = RegionExtents(damage); damage_box = RegionExtents(damage);
event = malloc(sizeof *event); event = malloc(sizeof *event);
@ -457,10 +461,7 @@ xwl_present_flip(WindowPtr present_window,
xwl_window->present_window = present_window; xwl_window->present_window = present_window;
buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap, buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap, &buffer_created);
present_box->x2 - present_box->x1,
present_box->y2 - present_box->y1,
&buffer_created);
event->event_id = event_id; event->event_id = event_id;
event->xwl_present_window = xwl_present_window; event->xwl_present_window = xwl_present_window;
@ -547,10 +548,9 @@ xwl_present_init(ScreenPtr screen)
struct xwl_screen *xwl_screen = xwl_screen_get(screen); struct xwl_screen *xwl_screen = xwl_screen_get(screen);
/* /*
* doesn't work with the streams backend. we don't have an explicit * doesn't work with the EGLStream backend.
* boolean for that, but we do know gbm doesn't fill in this hook...
*/ */
if (xwl_screen->egl_backend.post_damage != NULL) if (xwl_screen->egl_backend == &xwl_screen->eglstream_backend)
return FALSE; return FALSE;
if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0)) if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0))

View file

@ -96,9 +96,7 @@ ddxUseMsg(void)
ErrorF("-rootless run rootless, requires wm support\n"); ErrorF("-rootless run rootless, requires wm support\n");
ErrorF("-wm fd create X client for wm on given fd\n"); ErrorF("-wm fd create X client for wm on given fd\n");
ErrorF("-listen fd add give fd as a listen socket\n"); ErrorF("-listen fd add give fd as a listen socket\n");
#ifdef XWL_HAS_EGLSTREAM
ErrorF("-eglstream use eglstream backend for nvidia GPUs\n"); ErrorF("-eglstream use eglstream backend for nvidia GPUs\n");
#endif
} }
int int
@ -117,11 +115,9 @@ ddxProcessArgument(int argc, char *argv[], int i)
else if (strcmp(argv[i], "-shm") == 0) { else if (strcmp(argv[i], "-shm") == 0) {
return 1; return 1;
} }
#ifdef XWL_HAS_EGLSTREAM
else if (strcmp(argv[i], "-eglstream") == 0) { else if (strcmp(argv[i], "-eglstream") == 0) {
return 1; return 1;
} }
#endif
return 0; return 0;
} }
@ -682,8 +678,6 @@ xwl_window_post_damage(struct xwl_window *xwl_window)
#ifdef XWL_HAS_GLAMOR #ifdef XWL_HAS_GLAMOR
if (xwl_screen->glamor) if (xwl_screen->glamor)
buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap, buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap,
pixmap->drawable.width,
pixmap->drawable.height,
NULL); NULL);
else else
#endif #endif
@ -741,7 +735,7 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen)
continue; continue;
#ifdef XWL_HAS_GLAMOR #ifdef XWL_HAS_GLAMOR
if (!xwl_glamor_allow_commits(xwl_window)) if (xwl_screen->glamor && !xwl_glamor_allow_commits(xwl_window))
continue; continue;
#endif #endif
@ -943,9 +937,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
struct xwl_screen *xwl_screen; struct xwl_screen *xwl_screen;
Pixel red_mask, blue_mask, green_mask; Pixel red_mask, blue_mask, green_mask;
int ret, bpc, green_bpc, i; int ret, bpc, green_bpc, i;
#ifdef XWL_HAS_EGLSTREAM
Bool use_eglstreams = FALSE; Bool use_eglstreams = FALSE;
#endif
xwl_screen = calloc(1, sizeof *xwl_screen); xwl_screen = calloc(1, sizeof *xwl_screen);
if (xwl_screen == NULL) if (xwl_screen == NULL)
@ -988,28 +980,18 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
else if (strcmp(argv[i], "-shm") == 0) { else if (strcmp(argv[i], "-shm") == 0) {
xwl_screen->glamor = 0; xwl_screen->glamor = 0;
} }
#ifdef XWL_HAS_EGLSTREAM
else if (strcmp(argv[i], "-eglstream") == 0) { else if (strcmp(argv[i], "-eglstream") == 0) {
#ifdef XWL_HAS_EGLSTREAM
use_eglstreams = TRUE; use_eglstreams = TRUE;
} #else
ErrorF("xwayland glamor: this build does not have EGLStream support\n");
#endif #endif
}
} }
#ifdef XWL_HAS_GLAMOR #ifdef XWL_HAS_GLAMOR
if (xwl_screen->glamor) { if (xwl_screen->glamor)
#ifdef XWL_HAS_EGLSTREAM xwl_glamor_init_backends(xwl_screen, use_eglstreams);
if (use_eglstreams) {
if (!xwl_glamor_init_eglstream(xwl_screen)) {
ErrorF("xwayland glamor: failed to setup eglstream backend, falling back to swaccel\n");
xwl_screen->glamor = 0;
}
} else
#endif
if (!xwl_glamor_init_gbm(xwl_screen)) {
ErrorF("xwayland glamor: failed to setup GBM backend, falling back to sw accel\n");
xwl_screen->glamor = 0;
}
}
#endif #endif
/* In rootless mode, we don't have any screen storage, and the only /* In rootless mode, we don't have any screen storage, and the only
@ -1095,9 +1077,13 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
return FALSE; return FALSE;
#ifdef XWL_HAS_GLAMOR #ifdef XWL_HAS_GLAMOR
if (xwl_screen->glamor && !xwl_glamor_init(xwl_screen)) { if (xwl_screen->glamor) {
ErrorF("Failed to initialize glamor, falling back to sw\n"); xwl_glamor_select_backend(xwl_screen, use_eglstreams);
xwl_screen->glamor = 0;
if (xwl_screen->egl_backend == NULL || !xwl_glamor_init(xwl_screen)) {
ErrorF("Failed to initialize glamor, falling back to sw\n");
xwl_screen->glamor = 0;
}
} }
if (xwl_screen->glamor && xwl_screen->rootless) if (xwl_screen->glamor && xwl_screen->rootless)
@ -1134,6 +1120,10 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
AddCallback(&PropertyStateCallback, xwl_property_callback, pScreen); AddCallback(&PropertyStateCallback, xwl_property_callback, pScreen);
wl_display_roundtrip(xwl_screen->display);
while (xwl_screen->expecting_event)
wl_display_roundtrip(xwl_screen->display);
return ret; return ret;
} }

View file

@ -57,6 +57,60 @@ struct xwl_format {
struct xwl_pixmap; struct xwl_pixmap;
struct xwl_window; struct xwl_window;
struct xwl_screen;
struct xwl_egl_backend {
/* Set by the backend if available */
Bool is_available;
/* 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,
Bool *created);
/* 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.
*/
void (*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);
};
struct xwl_screen { struct xwl_screen {
int width; int width;
@ -109,55 +163,10 @@ struct xwl_screen {
struct xwl_format *formats; struct xwl_format *formats;
void *egl_display, *egl_context; void *egl_display, *egl_context;
/* the current backend for creating pixmaps on wayland */ struct xwl_egl_backend gbm_backend;
struct { struct xwl_egl_backend eglstream_backend;
/* Called once for each interface in the global registry. Backends /* pointer to the current backend for creating pixmaps on wayland */
* should use this to bind to any wayland interfaces they need. This struct xwl_egl_backend *egl_backend;
* callback is optional.
*/
void (*init_wl_registry)(struct xwl_screen *xwl_screen,
struct wl_registry *wl_registry,
const char *name, uint32_t id,
uint32_t version);
/* 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,
unsigned short width,
unsigned short height,
Bool *created);
/* 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.
*/
void (*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);
} egl_backend;
struct glamor_context *glamor_ctx; struct glamor_context *glamor_ctx;
@ -263,6 +272,7 @@ struct xwl_seat {
char *keymap; char *keymap;
struct wl_surface *keyboard_focus; struct wl_surface *keyboard_focus;
struct xorg_list axis_discrete_pending;
struct xorg_list sync_pending; struct xorg_list sync_pending;
struct xwl_pointer_warp_emulator *pointer_warp_emulator; struct xwl_pointer_warp_emulator *pointer_warp_emulator;
@ -301,13 +311,13 @@ struct xwl_tablet_tool {
DeviceIntPtr xdevice; DeviceIntPtr xdevice;
uint32_t proximity_in_serial; uint32_t proximity_in_serial;
uint32_t x; double x;
uint32_t y; double y;
uint32_t pressure; uint32_t pressure;
float tilt_x; double tilt_x;
float tilt_y; double tilt_y;
float rotation; double rotation;
float slider; double slider;
uint32_t buttons_now, uint32_t buttons_now,
buttons_prev; buttons_prev;
@ -414,7 +424,11 @@ PixmapPtr xwl_shm_create_pixmap(ScreenPtr screen, int width, int height,
Bool xwl_shm_destroy_pixmap(PixmapPtr pixmap); Bool xwl_shm_destroy_pixmap(PixmapPtr pixmap);
struct wl_buffer *xwl_shm_pixmap_get_wl_buffer(PixmapPtr pixmap); struct wl_buffer *xwl_shm_pixmap_get_wl_buffer(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_glamor_init(struct xwl_screen *xwl_screen);
Bool xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen, Bool xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
@ -422,58 +436,51 @@ Bool xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
Bool xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen, Bool xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
uint32_t id, uint32_t version); uint32_t id, uint32_t version);
struct wl_buffer *xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap, struct wl_buffer *xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap,
unsigned short width,
unsigned short height,
Bool *created); Bool *created);
void xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen, void xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
struct wl_registry *registry, struct wl_registry *registry,
uint32_t id, const char *interface, uint32_t id, const char *interface,
uint32_t version); uint32_t version);
Bool xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen,
struct xwl_egl_backend *xwl_egl_backend);
void xwl_glamor_post_damage(struct xwl_window *xwl_window, void xwl_glamor_post_damage(struct xwl_window *xwl_window,
PixmapPtr pixmap, RegionPtr region); PixmapPtr pixmap, RegionPtr region);
Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window); Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window);
void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
#ifdef GLAMOR_HAS_GBM #ifdef GLAMOR_HAS_GBM
Bool xwl_present_init(ScreenPtr screen); Bool xwl_present_init(ScreenPtr screen);
void xwl_present_cleanup(WindowPtr window); void xwl_present_cleanup(WindowPtr window);
#endif #endif /* GLAMOR_HAS_GBM */
void xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen);
void xwl_output_get_xdg_output(struct xwl_output *xwl_output);
void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen);
void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
Bool xwl_glamor_egl_supports_device_probing(void);
void **xwl_glamor_egl_get_devices(int *num_devices);
Bool xwl_glamor_egl_device_has_egl_extensions(void *device,
const char **ext_list,
size_t size);
#ifdef XV #ifdef XV
/* glamor Xv Adaptor */ /* glamor Xv Adaptor */
Bool xwl_glamor_xv_init(ScreenPtr pScreen); Bool xwl_glamor_xv_init(ScreenPtr pScreen);
#endif #endif /* XV */
#endif /* XWL_HAS_GLAMOR */
void xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen);
void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen);
#ifdef XF86VIDMODE #ifdef XF86VIDMODE
void xwlVidModeExtensionInit(void); void xwlVidModeExtensionInit(void);
#endif #endif
#ifdef GLAMOR_HAS_GBM #ifdef GLAMOR_HAS_GBM
Bool xwl_glamor_init_gbm(struct xwl_screen *xwl_screen); void xwl_glamor_init_gbm(struct xwl_screen *xwl_screen);
#else #else
static inline Bool xwl_glamor_init_gbm(struct xwl_screen *xwl_screen) static inline void xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
{ {
return FALSE;
} }
#endif #endif
#ifdef XWL_HAS_EGLSTREAM #ifdef XWL_HAS_EGLSTREAM
Bool xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen); void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen);
#else #else
static inline Bool xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen) static inline void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen)
{ {
return FALSE;
} }
#endif #endif

View file

@ -172,3 +172,10 @@ xwin_man = configure_file(
configuration: manpage_config, configuration: manpage_config,
) )
install_man(xwin_man) install_man(xwin_man)
xwinrc_man = configure_file(
input: 'man/XWinrc.man',
output: 'XWinrc.5',
configuration: manpage_config,
)
install_man(xwinrc_man)

View file

@ -30,3 +30,10 @@ executable(
dependencies: [dependency('x11')], dependencies: [dependency('x11')],
install: true, install: true,
) )
xwinclip_man = configure_file(
input: 'xwinclip.man',
output: 'xwinclip.1',
configuration: manpage_config,
)
install_man(xwinclip_man)

View file

@ -153,10 +153,10 @@ conf_data.set('BUSFAULT', conf_data.get('HAVE_SIGACTION'))
conf_data.set('_XTYPEDEF_POINTER', '1') conf_data.set('_XTYPEDEF_POINTER', '1')
conf_data.set('_XITYPEDEF_POINTER', '1') conf_data.set('_XITYPEDEF_POINTER', '1')
conf_data.set('LISTEN_TCP', get_option('listen_tcp'))
conf_data.set('LISTEN_UNIX', get_option('listen_unix'))
conf_data.set('LISTEN_LOCAL', get_option('listen_local'))
# XXX: Configurable? # XXX: Configurable?
conf_data.set('LISTEN_TCP', '1')
conf_data.set('LISTEN_UNIX', '1')
conf_data.set('LISTEN_LOCAL', '1')
conf_data.set('XTRANS_SEND_FDS', '1') conf_data.set('XTRANS_SEND_FDS', '1')
conf_data.set('TCPCONN', '1') conf_data.set('TCPCONN', '1')

View file

@ -3,7 +3,7 @@ project('xserver', 'c',
'buildtype=debugoptimized', 'buildtype=debugoptimized',
'c_std=gnu99', 'c_std=gnu99',
], ],
version: '1.20.0', version: '1.20.3',
meson_version: '>= 0.42.0', meson_version: '>= 0.42.0',
) )
add_project_arguments('-DHAVE_DIX_CONFIG_H', language: 'c') add_project_arguments('-DHAVE_DIX_CONFIG_H', language: 'c')
@ -507,8 +507,8 @@ top_srcdir_inc = include_directories('.')
serverconfigdir = join_paths(get_option('libdir'), 'xorg') serverconfigdir = join_paths(get_option('libdir'), 'xorg')
manpage_config = configuration_data() manpage_config = configuration_data()
manpage_config.set('vendorversion', 'PACKAGE_STRING XORG_MAN_PAGE') manpage_config.set('vendorversion', '"xorg-server @0@" "X Version 11"'.format(meson.project_version()))
manpage_config.set('xorgversion', 'PACKAGE_STRING XORG_MAN_PAGE') manpage_config.set('xorgversion', '"xorg-server @0@" "X Version 11"'.format(meson.project_version()))
manpage_config.set('xservername', 'Xorg') manpage_config.set('xservername', 'Xorg')
manpage_config.set('xconfigfile', 'xorg.conf') manpage_config.set('xconfigfile', 'xorg.conf')
manpage_config.set('projectroot', get_option('prefix')) manpage_config.set('projectroot', get_option('prefix'))
@ -520,9 +520,9 @@ manpage_config.set('libmansuffix', '3')
manpage_config.set('miscmansuffix', '7') manpage_config.set('miscmansuffix', '7')
manpage_config.set('filemansuffix', '5') manpage_config.set('filemansuffix', '5')
manpage_config.set('logdir', log_dir) manpage_config.set('logdir', log_dir)
manpage_config.set('datadir', get_option('datadir')) manpage_config.set('datadir', join_paths(get_option('prefix'), get_option('datadir')))
manpage_config.set('mandir', get_option('mandir')) manpage_config.set('mandir', join_paths(get_option('prefix'), get_option('mandir')))
manpage_config.set('sysconfdir', get_option('sysconfdir')) manpage_config.set('sysconfdir', join_paths(get_option('prefix'), get_option('sysconfdir')))
manpage_config.set('xconfigdir', 'xorg.conf.d') manpage_config.set('xconfigdir', 'xorg.conf.d')
manpage_config.set('xkbdir', xkb_dir) manpage_config.set('xkbdir', xkb_dir)
manpage_config.set('XKB_DFLT_RULES', get_option('xkb_default_rules')) manpage_config.set('XKB_DFLT_RULES', get_option('xkb_default_rules'))

View file

@ -45,6 +45,13 @@ option('vendor_name_short', type: 'string', value: 'X.Org')
option('vendor_web', type: 'string', value: 'http://wiki.x.org') option('vendor_web', type: 'string', value: 'http://wiki.x.org')
option('os_vendor', type: 'string', value: '') option('os_vendor', type: 'string', value: '')
option('listen_tcp', type: 'boolean', value: false,
description: 'Listen on TCP by default')
option('listen_unix', type: 'boolean', value: true,
description: 'Listen on Unix by default')
option('listen_local', type: 'boolean', value: true,
description: 'Listen on local by default')
option('int10', type: 'combo', choices: ['stub', 'x86emu', 'vm86', 'auto', 'false'], option('int10', type: 'combo', choices: ['stub', 'x86emu', 'vm86', 'auto', 'false'],
value: 'auto', value: 'auto',
description: 'Xorg int10 backend (default: usually x86emu)') description: 'Xorg int10 backend (default: usually x86emu)')

View file

@ -141,6 +141,8 @@ miCopyArea(DrawablePtr pSrcDrawable,
free(ordering); free(ordering);
free(pwidthFirst); free(pwidthFirst);
free(pptFirst); free(pptFirst);
if (realSrcClip)
RegionDestroy(prgnSrcClip);
return NULL; return NULL;
} }

View file

@ -829,16 +829,36 @@ damagePolyPoint(DrawablePtr pDrawable,
/* this could be slow if the points were spread out */ /* this could be slow if the points were spread out */
while (--nptTmp) { if (mode == CoordModePrevious) {
pptTmp++; int x = box.x1;
if (box.x1 > pptTmp->x) int y = box.y1;
box.x1 = pptTmp->x;
else if (box.x2 < pptTmp->x) while (--nptTmp) {
box.x2 = pptTmp->x; pptTmp++;
if (box.y1 > pptTmp->y) x += pptTmp->x;
box.y1 = pptTmp->y; y += pptTmp->y;
else if (box.y2 < pptTmp->y) if (box.x1 > x)
box.y2 = pptTmp->y; box.x1 = x;
else if (box.x2 < x)
box.x2 = x;
if (box.y1 > y)
box.y1 = y;
else if (box.y2 < y)
box.y2 = y;
}
}
else {
while (--nptTmp) {
pptTmp++;
if (box.x1 > pptTmp->x)
box.x1 = pptTmp->x;
else if (box.x2 < pptTmp->x)
box.x2 = pptTmp->x;
if (box.y1 > pptTmp->y)
box.y1 = pptTmp->y;
else if (box.y2 < pptTmp->y)
box.y2 = pptTmp->y;
}
} }
box.x2++; box.x2++;

View file

@ -190,10 +190,11 @@ WaitForSomething(Bool are_ready)
/* deal with any blocked jobs */ /* deal with any blocked jobs */
if (workQueue) { if (workQueue) {
ProcessWorkQueue(); ProcessWorkQueue();
are_ready = clients_are_ready();
} }
timeout = check_timers(); timeout = check_timers();
are_ready = clients_are_ready();
if (are_ready) if (are_ready)
timeout = 0; timeout = 0;

View file

@ -194,6 +194,8 @@ LogFilePrep(const char *fname, const char *backup, const char *idstring)
{ {
char *logFileName = NULL; char *logFileName = NULL;
/* the format string below is controlled by the user,
this code should never be called with elevated privileges */
if (asprintf(&logFileName, fname, idstring) == -1) if (asprintf(&logFileName, fname, idstring) == -1)
FatalError("Cannot allocate space for the log file name\n"); FatalError("Cannot allocate space for the log file name\n");

View file

@ -56,9 +56,13 @@ endif
rpc_dep = [] rpc_dep = []
if get_option('secure-rpc') if get_option('secure-rpc')
# prefer libtirpc (if available), otherwise assume RPC functions are # prefer libtirpc (if available), otherwise ensure RPC functions are
# provided by libc. # provided by libc.
rpc_dep = dependency('libtirpc', required: false) rpc_dep = dependency('libtirpc', required: false)
if not (rpc_dep.found() or cc.has_header('rpc/rpc.h'))
error('secure-rpc requested, but neither libtirpc or libc RPC support were found')
endif
srcs_os += 'rpcauth.c' srcs_os += 'rpcauth.c'
endif endif

View file

@ -569,10 +569,9 @@ XdmcpRegisterDisplayClass(const char *name, int length)
} }
static void static void
xdmcp_start(void) xdmcp_reset(void)
{ {
timeOutRtx = 0; timeOutRtx = 0;
get_xdmcp_sock();
if (xdmcpSocket >= 0) if (xdmcpSocket >= 0)
SetNotifyFd(xdmcpSocket, XdmcpSocketNotify, X_NOTIFY_READ, NULL); SetNotifyFd(xdmcpSocket, XdmcpSocketNotify, X_NOTIFY_READ, NULL);
#if defined(IPv6) && defined(AF_INET6) #if defined(IPv6) && defined(AF_INET6)
@ -583,6 +582,13 @@ xdmcp_start(void)
send_packet(); send_packet();
} }
static void
xdmcp_start(void)
{
get_xdmcp_sock();
xdmcp_reset();
}
/* /*
* initialize XDMCP; create the socket, compute the display * initialize XDMCP; create the socket, compute the display
* number, set up the state machine * number, set up the state machine
@ -611,7 +617,7 @@ XdmcpReset(void)
{ {
state = XDM_INIT_STATE; state = XDM_INIT_STATE;
if (state != XDM_OFF) if (state != XDM_OFF)
xdmcp_start(); xdmcp_reset();
} }
/* /*

View file

@ -188,10 +188,11 @@ present_wnmd_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_
window_priv->flip_active = vblank; window_priv->flip_active = vblank;
window_priv->flip_pending = NULL; window_priv->flip_pending = NULL;
present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, ust, crtc_msc);
if (vblank->abort_flip) if (vblank->abort_flip)
present_wnmd_flips_stop(window); present_wnmd_flips_stop(window);
present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, ust, crtc_msc);
present_wnmd_flip_try_ready(window); present_wnmd_flip_try_ready(window);
} }
@ -469,6 +470,10 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
PixmapPtr old_pixmap = screen->GetWindowPixmap(window); PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
/* Replace window pixmap with flip pixmap */ /* 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); present_set_tree_pixmap(toplvl_window, old_pixmap, vblank->pixmap);
vblank->pixmap->refcnt++; vblank->pixmap->refcnt++;
dixDestroyPixmap(old_pixmap, old_pixmap->drawable.id); dixDestroyPixmap(old_pixmap, old_pixmap->drawable.id);

View file

@ -89,8 +89,12 @@ RRCloseScreen(ScreenPtr pScreen)
{ {
rrScrPriv(pScreen); rrScrPriv(pScreen);
int j; int j;
RRLeasePtr lease, next;
unwrap(pScrPriv, pScreen, CloseScreen); unwrap(pScrPriv, pScreen, CloseScreen);
xorg_list_for_each_entry_safe(lease, next, &pScrPriv->leases, list)
RRTerminateLease(lease);
for (j = pScrPriv->numCrtcs - 1; j >= 0; j--) for (j = pScrPriv->numCrtcs - 1; j >= 0; j--)
RRCrtcDestroy(pScrPriv->crtcs[j]); RRCrtcDestroy(pScrPriv->crtcs[j]);
for (j = pScrPriv->numOutputs - 1; j >= 0; j--) for (j = pScrPriv->numOutputs - 1; j >= 0; j--)

View file

@ -829,6 +829,9 @@ RRCrtcIsLeased(RRCrtcPtr crtc);
extern _X_EXPORT Bool extern _X_EXPORT Bool
RROutputIsLeased(RROutputPtr output); RROutputIsLeased(RROutputPtr output);
void
RRTerminateLease(RRLeasePtr lease);
Bool Bool
RRLeaseInit(void); RRLeaseInit(void);

View file

@ -534,6 +534,7 @@ rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height,
width, height, depth, width, height, depth,
x, y, rotation); x, y, rotation);
if (spix_front == NULL) { if (spix_front == NULL) {
ErrorF("randr: failed to create shared pixmap\n");
return FALSE; return FALSE;
} }
@ -701,8 +702,8 @@ rrCheckPixmapBounding(ScreenPtr pScreen,
if (new_height < screen_pixmap->drawable.height) if (new_height < screen_pixmap->drawable.height)
new_height = screen_pixmap->drawable.height; new_height = screen_pixmap->drawable.height;
if (new_width == screen_pixmap->drawable.width && if (new_width <= screen_pixmap->drawable.width &&
new_height == screen_pixmap->drawable.height) { new_height <= screen_pixmap->drawable.height) {
} else { } else {
pScrPriv->rrScreenSetSize(pScreen, new_width, new_height, 0, 0); pScrPriv->rrScreenSetSize(pScreen, new_width, new_height, 0, 0);
} }
@ -871,6 +872,17 @@ RRCrtcDestroyResource(void *value, XID pid)
if (pScreen) { if (pScreen) {
rrScrPriv(pScreen); rrScrPriv(pScreen);
int i; int i;
RRLeasePtr lease, next;
xorg_list_for_each_entry_safe(lease, next, &pScrPriv->leases, list) {
int c;
for (c = 0; c < lease->numCrtcs; c++) {
if (lease->crtcs[c] == crtc) {
RRTerminateLease(lease);
break;
}
}
}
for (i = 0; i < pScrPriv->numCrtcs; i++) { for (i = 0; i < pScrPriv->numCrtcs; i++) {
if (pScrPriv->crtcs[i] == crtc) { if (pScrPriv->crtcs[i] == crtc) {

View file

@ -169,7 +169,7 @@ RRLeaseFree(RRLeasePtr lease)
* finished, which may be some time after this function returns * finished, which may be some time after this function returns
* if the driver operation is asynchronous * if the driver operation is asynchronous
*/ */
static void void
RRTerminateLease(RRLeasePtr lease) RRTerminateLease(RRLeasePtr lease)
{ {
ScreenPtr screen = lease->screen; ScreenPtr screen = lease->screen;

View file

@ -379,6 +379,17 @@ RROutputDestroyResource(void *value, XID pid)
if (pScreen) { if (pScreen) {
rrScrPriv(pScreen); rrScrPriv(pScreen);
int i; int i;
RRLeasePtr lease, next;
xorg_list_for_each_entry_safe(lease, next, &pScrPriv->leases, list) {
int o;
for (o = 0; o < lease->numOutputs; o++) {
if (lease->outputs[o] == output) {
RRTerminateLease(lease);
break;
}
}
}
if (pScrPriv->primaryOutput == output) if (pScrPriv->primaryOutput == output)
pScrPriv->primaryOutput = NULL; pScrPriv->primaryOutput = NULL;

View file

@ -2570,7 +2570,7 @@ _XkbSetMap(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req, char *values)
first = last = 0; first = last = 0;
if (change.map.num_modmap_keys > 0) { if (change.map.num_modmap_keys > 0) {
firstMM = change.map.first_modmap_key; firstMM = change.map.first_modmap_key;
lastMM = first + change.map.num_modmap_keys - 1; lastMM = firstMM + change.map.num_modmap_keys - 1;
} }
else else
firstMM = lastMM = 0; firstMM = lastMM = 0;